How to Create a Database Web App with Oracle APEX

In this tutorial, you'll learn how to create a database web app with Oracle APEX. Build scalable, secure enterprise apps with Oracle APEX

Oracle Application Express (APEX) is a low-code development platform that enables you to build scalable, secure enterprise apps, with world-class features, that can be deployed anywhere.

Using APEX, developers can quickly develop and deploy compelling apps that solve real problems and provide immediate value. You won't need to be an expert in a vast array of technologies to deliver sophisticated solutions. Focus on solving the problem and let APEX take care of the rest.

If you have Oracle Database, you already have Oracle APEX? It's one of the most popular features of Oracle Database — the most complete, integrated, and secure database solution for any scale deployment. This solid foundation enables apps built using Oracle APEX to be enterprise ready from day one.

Oracle APEX has been an included no-cost feature of Oracle Database since 2004. That means, if you have Oracle Database, you already have Oracle APEX! This also means there are no additional licensing fees irrespective of the number of developers, building any number of apps, for unlimited end users.

Oracle APEX runs anywhere that Oracle Database runs, whether it is on premises, in Oracle Cloud, or anywhere else.

Oracle Application Express (APEX) is a low-code development platform that enables you to build stunning, scalable, secure apps with world-class features that can be deployed anywhere. Using APEX, developers can quickly develop and deploy compelling apps that solve real problems and provide immediate value.

What you’ll learn:

  •        Setup Oracle Database
  •        Unlock Sample Schema
  •        Create a workspace in Oracle APEX
  •        Build a database driven web app
  •        Publish app to end users
  •        Perform CRUD Operations

Are there any course requirements or prerequisites?

  •        Basic knowledge of database concepts advised.

Who this course is for:

  •        Beginners to Oracle Application Development

#database #webapp #oracle

How to Create a Database Web App with Oracle APEX
John David

John David

1665561126

Copper: Go Toolkit Complete to Build Web Apps

Copper

Copper is a Go toolkit complete with everything you need to build web apps. It focuses on developer productivity and makes building web apps in Go more fun with less boilerplate and out-of-the-box support for common needs.

🚀 Fullstack Toolkit

Copper provides a toolkit complete with everything you need to build web apps quickly.

📦 One Binary

Build frontend apps along with your backend and ship everything in a single binary.

📝 Server-side HTML

Copper includes utilities that help build web apps with server rendered HTML pages.

💡 Auto Restarts

Copper detects changes and automatically restarts server to save time.

🏗 Scaffolding

Skip boilerplate and scaffold code for your packages, database queries and routes.

🔋 Batteries Included

Includes CLI, lint, dev server, config management, and more!

🔩 First-party packages

Includes packages for authentication, pub/sub, queues, emails, and websockets.

Intro Video (Hacker News Clone)


Getting Started

Head over to the documentation to get started - https://docs.gocopper.dev/

Download Details: 
Author: gocopper
Source Code: https://github.com/gocopper/copper 
License: MIT
#go #golang #webdev #webapp

Copper: Go Toolkit Complete to Build Web Apps

How to Create a Web Application in Go using Copper

In this tutorial, you'll learn how to create a web application in Go using Copper that will be able to perform basic create, read, update, and delete operations.

Copper is an all-inclusive Go toolbox for creating web applications with less boilerplate and high focus on developer efficiency, which makes building web apps in Go more interesting and fun.

Copper still relies on the Go standard library to maintain the traditional Go experience while allowing you build frontend apps along with your backend and ship everything in a single binary. It has support for building full-stack web apps with React and Tailwind in the frontend, and it also supports building APIs that give more flexiblity to work with other frontend frameworks like Vue and Svelte.

In this article, we will be taking a look at how we can build a web application in Go with the gocopper framework so you can see how you’d implement it in your own projects.

Prerequisites

To get along with this tutorial, you should have the following:

  • Go v1.16+ installed
  • Node v16+ installed
  • Experience building Golang applications

Installation

To get started with Copper, we’ll run the following command on our terminal:

$ go install github.com/gocopper/cli/cmd/copper@latest

Run the following command to ensure your Copper installation works correctly:

$ copper -h

If copper -h didn’t work, it probably means that $GOPATH/bin is not in your $PATH. Add the following to ~/.zshrc or ~/.bashrc:

export PATH=$HOME/go/bin:$PATH

Then, restart your terminal session and try copper -h again.

Configuration

Copper allows you to configure the project template using -frontend and -storage arguments.

The -frontend argument allows you to configure your frontend with the following frontend frameworks and libraries:

The -storage argument allows you to configure your database stack, which is sqlite3 by default. You have options to set it to postgres, mysql, or skip storage entirely with none.

What we will be building: A simple to-do app

We will be building a full-stack web application that allows us to perform CRUD operations on our SQLite database. Basically, we will be building a to-do application. Here is how the finished app looks:

Finished App

This application allows us to get, add, update, and delete to-do items from our database. Without further ado, let’s get started.

Project setup

We’ll create a project that uses the Go templates for frontend using the go frontend stack as follows:

copper create -frontend=go github.com/<your-username>/todolist

With the above command, copper create a basic scaffold project with the Go templates for frontend and sqlite3 for the database.

Here is how your project scaffold should look:

Project Scaffold

To start the app server, run the following command:

$ cd todolist && copper run -watch

Open http://localhost:5901 to see the Copper welcome page.

Updating the layout file

Let’s update the web/src/layouts/main.html file with a script tag as follows:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Copper App</title>
    <link rel="stylesheet" href="/static/styles.css" />
  </head>
  <body>
    {{ template "content" . }}
    <script src="/static/index.js"></script>
  </body>
</html>

We’ll write some javascript in the static/index.js file to handle the delete request in our app as we proceed.

Our to-do app requires users to add to-dos to the database. Let’s create a new to-dos page with a simple form and a section to list all to-do items.

Navigate to the pages directory and create a file called todos.html with the following:

{{ define "content"}}
<div class="gr-container">
    <h2 class="heading">Todo List</h2>
    <form class="add-todo" action="/todos" method="post">
        <input type="text" name="todo">
        <button type="submit">Add Todo</button>
    </form>
    <div class="todo-list">
        <form class="todo-item" action="" method="post">
            <input type="text" name="todo">
            <button class="update" type="submit">Update Todo</button>
            <button class="delete" type="button">Remove Todo</button>
        </form>
    </div>
</div>
{{ end }}

Styling our sample app

Navigate to web/public directory and update style.css with the following:

@import url('https://fonts.googleapis.com/css2?family=Work+Sans:ital,wght@0,700;1,400&display=swap');
html, body {
    margin: 0;
    background-color: wheat;
}
#app {
    /* background-color: whitesmoke; */
    padding: 40px 0;
    font-family: 'Work Sans', sans-serif;
    text-align: center;
    height: 100%;
    box-sizing: border-box;
}
.tagline {
    font-style: italic;
    font-weight: 400;
}
hr {
    margin: 40px auto;
    width: 60%;
    border-top: 1px solid #ddd;
}
.video {
    width: 60%;
    margin: 0 auto;
}
.todo-list {
    background-color: greenyellow;
    margin-top: 2rem;
    width: 60%;
    padding: 1.5rem;
}
.add-todo {
    width: 50%;
    display: flex;
    justify-items: center;
}
.add-todo input {
    width: 85%;
    height: 2rem;
}
.add-todo button {
    width: 15%;
    /* height: 1.5rem; */
}
.todo-item {
    display: flex;
    margin-bottom: 1rem;
}
.todo-item input {
    width: 65%;
    height: 1.6rem;
}
.update, .delete {
    width: 16%;
}
.heading {
    text-align: center;
    font-size: 2.5rem;
}
.gr-container {
    padding: 1rem;

    display: flex;
    flex-direction: column;
    align-items: center;
}

In order to view the to-dos page on the browser, we’ll update the pkg/app/router.go file as follows:

func (ro *Router) Routes() []chttp.Route {
    return []chttp.Route{
        {
            Path:    "/",
            Methods: []string{http.MethodGet},
            Handler: ro.HandleIndexPage,
        },
        {
            Path:    "/todos",
            Methods: []string{http.MethodGet},
            Handler: ro.HandleTodosPage,
        },
    }
}
func (ro *Router) HandleTodosPage(w http.ResponseWriter, r *http.Request) {
    ro.rw.WriteHTML(w, r, chttp.WriteHTMLParams{
        PageTemplate: "todos.html",
    })
}

Here, we update our app route with the "/todos" path and also create the HandleTodosPage handler, which serves todos.html page when a user hit the "/todos" route in the browser.

Restart the app server and open http://localhost:5901/todos to see the to-dos page.

Here is how the to-dos page should look:

Initial Version of App

Implement a feature to create now to-do items

To implement the create feature, we’d set up a storage layer that can save the todo items into our database.

Let’s run the following command to create the pkg/todos package as well as a pkg/todos/queries.go that we can use to implement our SQL queries:

copper scaffold:pkg todos
copper scaffold:queries todos

Next, we’ll create the Todo model and its database migration. Open up pkg/todos/models.go and define the Todo model:

type Todo struct {
    Name string
    Rank int64 `gorm:"-"`
}

Then, open up migrations/0001_initial.sql and define its database schema:

-- +migrate Up
CREATE TABLE todos (
    name text
);
-- +migrate Down
DROP TABLE todos;

In your terminal, run copper migrate to create the table.

Now that we have a Todo model and a todos table in our database, we can write our database queries in the pkg/posts/queries.go file.

Let’s add a SaveTodo method that can be used to insert new to-dos into the todos table:

import (
    "context"
    ...
)
func (q *Queries) SaveTodo(ctx context.Context, todo *Todo) error {
    const query = `
    INSERT INTO todos (name)
    VALUES (?)`
    _, err := q.querier.Exec(ctx, query,
        todo.Name,
    )
    return err
}

Here, we use an SQL query to insert a new to-do into the DB. The question mark is a placeholder for a value in the query. The q.querier.Exec function takes a context object, a query, and as many arguments you want to pass into the placeholders. Then, the values in the placeholders are inserted in the order they appear in the q.querier.Exec function.

Now, let’s head over to pkg/app/router.go and use the SaveTodo method to handle form submissions for creating new to-dos.

Create a new route handler, HandleSubmitPost, to handle submissions for creating new to-dos as follows:

func (ro *Router) HandleCreateTodos(w http.ResponseWriter, r *http.Request) {
    var (
        todo = strings.TrimSpace(r.PostFormValue(("todo")))
    )
    if todo == "" {
        ro.rw.WriteHTMLError(w, r, cerrors.New(nil, "unable to create todos: todo cannot be empty", map[string]interface{}{
            "form": r.Form,
        }))
        return
    }
    newtodo := todos.Todo{Name: todo}
    err := ro.todos.SaveTodo(r.Context(), &newtodo)
    if err != nil {
        ro.logger.Error("an error occured while saving todo", err)
        ro.rw.WriteHTMLError(w, r, cerrors.New(nil, "unable to create todos", map[string]interface{}{
            "form": r.Form,
        }))
        return
    }
    http.Redirect(w, r, "/todos", http.StatusSeeOther)
}

This function creates a new to-do item. First. we get the to-do value from the form and trim any white space the user may have added. Then, we check if the to-do is an empty string, in which case we throw an error. Next, we create a new to-do object and call the ro.todos.SaveTodo function to save it into the database. If there was an error while saving the to-do, we throw an error. Finally, we redirect to the to-dos page.

Update the pkg/app/router.go file with the HandleCreateTodos as follows:

import (
    "strings"
    "github.com/gocopper/copper/cerrors"
    "github.com/gocopper/copper/chttp"
    "github.com/gocopper/copper/clogger"
    "net/http"
    "github.com/emmanuelhashy/todolist/pkg/todos"
)

type NewRouterParams struct {
    Todos  *todos.Queries
    RW     *chttp.ReaderWriter
    Logger clogger.Logger
}

func NewRouter(p NewRouterParams) *Router {
    return &Router{
        rw:     p.RW,
        logger: p.Logger,
        todos:  p.Todos,
    }
}

type Router struct {
    rw     *chttp.ReaderWriter
    logger clogger.Logger
    todos  *todos.Queries
}

func (ro *Router) Routes() []chttp.Route {
    return []chttp.Route{
        {
            Path:    "/",
            Methods: []string{http.MethodGet},
            Handler: ro.HandleIndexPage,
        },
        {
            Path:    "/todos",
            Methods: []string{http.MethodGet},
            Handler: ro.HandleTodosPage,
        },
        {
            Path:    "/todos",
            Methods: []string{http.MethodPost},
            Handler: ro.HandleCreateTodos,
        },
    }
}

Now, the create feature for our todo app should work! We can add a new to-do into the todos table.

Add a read feature to see all the to-do items

To implement the read feature, we’d create a new SQL query to return a list of all todos that exist in the database and work our way up from there.

Update pkg/todos/queries.go with the following method to list all to-dos:

func (q *Queries) ListTodos(ctx context.Context) ([]Todo, error) {
    const query = "SELECT * FROM todos"
    var (
        todos []Todo
        err   = q.querier.Select(ctx, &todos, query)
    )
    return todos, err
}

Here, we use an SQL query to get all the to-dos stored in the database. Since we are not updating a value in the DB, we use the q.querier.Select method as opposed to q.querier.Exec.

Next, update the HandleTodosPage method in pkg/app/router.go to query all todos and pass it to the HTML template:

func (ro *Router) HandleTodosPage(w http.ResponseWriter, r *http.Request) {
    todos, err := ro.todos.ListTodos(r.Context())
    if err != nil {
        ro.logger.Error("an error occured while fetching todos", err)
        ro.rw.WriteHTMLError(w, r, cerrors.New(nil, "unable to fetch todos", map[string]interface{}{
            "form": r.Form,
        }))
    }
    for i := range todos {
        todos[i].Rank = int64(i + 1)
    }
    ro.rw.WriteHTML(w, r, chttp.WriteHTMLParams{
        PageTemplate: "todos.html",
        Data:         todos,
    })
}

To make use of the data and render a list of all to-dos, update web/src/pages/todos.html as follows:

{{ define "content"}}
<div class="gr-container">
    <h2 class="heading">Todo List</h2>
    <form class="add-todo" action="/todos" method="post">
        <input type="text" name="todo">
        <button type="submit">Add Todo</button>
    </form>
    <div class="todo-list">
        {{ range . }}
        <form class="todo-item" action="/{{.Name}}" method="post">
            {{.Rank}}.
            <input type="text" name="todo" value="{{.Name}}">
            <button class="update" type="submit">Update Todo</button>
            <button class="delete" type="button">Remove Todo</button>
        </form>

        {{ end }}
    </div>
</div>
{{ end }}

Now, you should see a list of all the to-dos in the database in the to-dos page.

List of Todos

Update to-do items

To implement the update feature, we’ll create a new SQL query to update to-dos that exist in the database.

Update pkg/todos/queries.go with the following method:

func (q *Queries) UpdateTodo(ctx context.Context, oldName string, todo *Todo) error {
    const query = `
    UPDATE todos SET name=(?) WHERE name=(?)`
    _, err := q.querier.Exec(ctx, query,
        todo.Name,
        oldName,
    )
    return err
}

Here, we use an SQL query to update a to-do value in the DB. We pass in new and old values respectively to the placeholder in the SQL query.

Next, we’ll create a HandleUpdateTodos method in pkg/app/router.go to update existing todos:

func (ro *Router) HandleUpdateTodos(w http.ResponseWriter, r *http.Request) {
    var (
        todo    = strings.TrimSpace(r.PostFormValue("todo"))
        oldName = chttp.URLParams(r)["todo"]
    )
    if todo == "" {
        ro.rw.WriteHTMLError(w, r, cerrors.New(nil, "unable to update todos: todo cannot be empty", map[string]interface{}{
            "form": r.Form,
        }))
        return
    }
    newtodo := todos.Todo{Name: todo}
    ro.logger.WithTags(map[string]interface{}{
        "oldname": oldName,
        "newname": newtodo.Name,
    }).Info("Todo updated")
    err := ro.todos.UpdateTodo(r.Context(), oldName, &newtodo)
    if err != nil {
        ro.logger.Error("an error occured while saving todo", err)
        ro.rw.WriteHTMLError(w, r, cerrors.New(nil, "unable to update todos", map[string]interface{}{
            "form": r.Form,
        }))
        return
    }
    http.Redirect(w, r, "/todos", http.StatusSeeOther)
}

Then update Routes with the HandleUpdateTodos method as follows:

func (ro *Router) Routes() []chttp.Route {
    return []chttp.Route{
        ...
        {
            Path:    "/{todo}",
            Methods: []string{http.MethodPost},
            Handler: ro.HandleUpdateTodos,
        },
    }
}

Delete to-dos

To implement the delete feature, we’ll create a new SQL query to delete to-dos that exist in the database.

Update pkg/todos/queries.go with the following method:

func (q *Queries) DeleteTodo(ctx context.Context, todo *Todo) error {
    const query = `
    DELETE from todos WHERE name=(?)`
    _, err := q.querier.Exec(ctx, query,
        todo.Name,
    )
    return err
}

Next, we’ll create HandleDeleteTodos method in pkg/app/router.go to delete existing to-dos:

type error struct {
    error string
}

func (ro *Router) HandleDeleteTodos(w http.ResponseWriter, r *http.Request) {
    var (
        todo = strings.TrimSpace(chttp.URLParams(r)["todo"])
    )
    if todo == "" {
        deleteError := error{error: "Unable to delete todo"}
        ro.rw.WriteJSON(w, chttp.WriteJSONParams{StatusCode: 500, Data: deleteError})
        return
    }
    newtodo := todos.Todo{Name: todo}
    err := ro.todos.DeleteTodo(r.Context(), &newtodo)
    if err != nil {
        ro.logger.Error("an error occured while deleting todo", err)
        deleteError := error{error: "Unable to delete todo"}
        ro.rw.WriteJSON(w, chttp.WriteJSONParams{StatusCode: 500, Data: deleteError})
        return
    }
    http.Redirect(w, r, "/todos", http.StatusSeeOther)
}

Then update Routes with the HandleDeleteTodos method as follows:

func (ro *Router) Routes() []chttp.Route {
    return []chttp.Route{
        ...
        {
            Path:    "/{todo}",
            Methods: []string{http.MethodDelete},
            Handler: ro.HandleDeleteTodos,
        },
    }
}

To wrap up the delete feature of our to-do app, we’ll create an index.js file in web/public directory and add the following function:

function deleteTodo(name){
    fetch(`/${name}`, {method: "Delete"}).then(res =>{
        if (res.status == 200){
            window.location.pathname = "/todos"
        }
    }).catch(err => {
        alert("An error occured while deleting the todo", err.message)
    })
}

Then, update the remove to-do button in pages/todos.html as follows:

<button class="delete" type="button" onclick = "deleteTodo('{{.Name}}')" >Remove Todo</button>

We have successfully built a web app in Go using gocopper.

If you followed the above tutorial correctly, your to-do app should be able to perform basic create, read, update, and delete operations.

Here is the link to the final code repository.

Conclusion

This tutorial has finally come to an end. We looked at how to create a web application in Go using Copper, and we used this to build a to-do application successfully.

Copper makes use of google/wire to enable on-the-fly dependency injection. It comes with the clogger package, which enables structured logging in both development and production environments. Also, it works closely with the cerrors package to help add structure and context to your errors, resulting in significantly improved error logs.

Original article source at https://blog.logrocket.com

#go #golang #copper #webdev #webapp

How to Create a Web Application in Go using Copper
Jade Bird

Jade Bird

1665024026

Build a Reactive Backend for a Web App with Convex

Build a Reactive Backend for a Web App

Convex is a JS-powered database and backend for web apps that’s reactive — you can use it to create endpoints and queries that update automatically when data changes. Tom Ballinger will teach us how.
   
00:00:00 - Welcome
00:00:32 - Who is Tom Ballinger?
00:01:40 - Explaining Convex
00:15:28 - What is Convex’s sweet spot?
00:23:08 - Where should I start with Convex?
00:28:53 - What has happened with the quick start?
00:35:23 - The Convex folder is where you find the backend
00:43:55 - How does it scale with schema defined in code?
00:48:27 - How do you handle authentication?
01:19:29 - Where should someone go for more information on Convex?

Repo: https://github.com/learnwithjason/convex-reactive-toy      

Demo: https://convex-reactive-toy.netlify.app/ 

#webapp #convex #webdev 

Build a Reactive Backend for a Web App with Convex

Learn Jenkins by Building a CI/CD Pipeline for Web Application

Learn about Jenkins by building a CI/CD pipeline for a web application. Jenkins is an open source automation server which makes it easier to build, test, and deploy software. In this course, you will learn how to build a full dev-ops pipeline using Jenkins, Linode Servers, and other tools.

⭐️ Contents ⭐️
⌨️ (00:00:00) Video Intro
⌨️ (00:01:33) Course Overview
⌨️ (00:02:36) What is Jenkins?
⌨️ (00:08:47) Terms & Definitions
⌨️ (00:11:58) Project Architecture
⌨️ (00:13:28) Linode Intro
⌨️ (00:20:18) Setting Up Jenkins
⌨️ (00:24:11) Tour of Jenkins Interface
⌨️ (00:30:33) Installing Plugins
⌨️ (00:33:39) Blue Ocean
⌨️ (00:34:55) Creating a Pipeline
⌨️ (00:42:37) Installing Git
⌨️ (00:45:15) Jenkinsfile
⌨️ (00:46:27) Updating a Pipeline
⌨️ (00:52:05) Jenkins with nom
⌨️ (00:56:36) Docker & Dockerhub
⌨️ (01:02:14) Closing Remarks

#jenkins #devops #docker #linux #linode #webapp

 

Learn Jenkins by Building a CI/CD Pipeline for Web Application
Jade Bird

Jade Bird

1661564624

Building a Full-Stack Web App with ReactJS, NodeJS, Express & MySQL

In this Full Stack Web Development Course, you'll learn how to create a full stack web app from scratch with ReactJS, NodeJS, Express & MySQL

In this tutorial, you'll learn:

  1. Introduction - Full Stack Web Development Course [1] | ReactJS, NodeJS, Express, MySQL
  2. GET and POST Requests - Full Stack Web Development Course [2] | ReactJS, NodeJS, MySQL
  3. Connecting React to NodeJS - Full Stack Web Development Course [3] | ReactJS, NodeJS, MySQL
  4. Form Validation - Full Stack Web Development Course [4] | ReactJS, NodeJS, MySQL
  5. Full Stack Web Development Course [5] | ReactJS, NodeJS, MySQL - Individual Pages Based on ID
  6. Full Stack Web Development Course [6] | ReactJS, NodeJS, MySQL - Associations in Sequelize
  7. Full Stack Web Development Course [7] | ReactJS, NodeJS, MySQL - Comment Section in React
  8. Full Stack Web Development Course [8] | ReactJS, NodeJS, MySQL - Registration and Login
  9. Full Stack Web Development Course [9] | ReactJS, NodeJS, MySQL - JWT Authentication
  10. Full Stack Web Development Course [10] | ReactJS, NodeJS, MySQL - Auth in the Frontend
  11. Full Stack Web Development Course [11] | ReactJS, NodeJS, MySQL - Logging Out
  12. Full Stack Web Development Course [12] | ReactJS, NodeJS, MySQL - Liking System
  13. Full Stack Web Development Course [13] | ReactJS, NodeJS, MySQL - Page Not Found
  14. Full Stack Web Development Course [14] | ReactJS, NodeJS, MySQL - Delete a Post
  15. Full Stack Web Development Course [15] | ReactJS, NodeJS, MySQL - Profile Page
  16. Full Stack Web Development Course [16] | ReactJS, NodeJS, MySQL - Update Password
  17. Full Stack Web Development Course [17] | ReactJS, NodeJS, MySQL - Deploying the Website

Introduction - Full Stack Web Development Course [1] | ReactJS, NodeJS, Express, MySQL

GET and POST Requests - Full Stack Web Development Course [2] | ReactJS, NodeJS, MySQL

Connecting React to NodeJS - Full Stack Web Development Course [3] | ReactJS, NodeJS, MySQL

Form Validation - Full Stack Web Development Course [4] | ReactJS, NodeJS, MySQL

Full Stack Web Development Course [5] | ReactJS, NodeJS, MySQL - Individual Pages Based on ID

Full Stack Web Development Course [6] | ReactJS, NodeJS, MySQL - Associations in Sequelize

Full Stack Web Development Course [7] | ReactJS, NodeJS, MySQL - Comment Section in React

Full Stack Web Development Course [8] | ReactJS, NodeJS, MySQL - Registration and Login

Full Stack Web Development Course [9] | ReactJS, NodeJS, MySQL - JWT Authentication

Full Stack Web Development Course [10] | ReactJS, NodeJS, MySQL - Auth in the Frontend

Full Stack Web Development Course [11] | ReactJS, NodeJS, MySQL - Logging Out

Full Stack Web Development Course [12] | ReactJS, NodeJS, MySQL - Liking System

Full Stack Web Development Course [13] | ReactJS, NodeJS, MySQL - Page Not Found

Full Stack Web Development Course [14] | ReactJS, NodeJS, MySQL - Delete a Post

Full Stack Web Development Course [15] | ReactJS, NodeJS, MySQL - Profile Page

Full Stack Web Development Course [16] | ReactJS, NodeJS, MySQL - Update Password

Full Stack Web Development Course [17] | ReactJS, NodeJS, MySQL - Deploying the Website

Code: https://github.com/machadop1407/FullStack-Course/tree/Episode1/Episode2

#react #node #mysql #expressjs #reactjs #nodejs #webdev #webdevelopment #webapp 

 

Building a Full-Stack Web App with ReactJS, NodeJS, Express & MySQL

Build .NET 6 Web App with Web API, Entity Framework & SQL Server

Build the back-end of a .NET 6 web application with Web API, Entity Framework Core & SQL Server in no time!

What you'll learn:

  • Build a complete .NET 6 back-end with Web API, Entity Framework Core, SQL Server
  • Implement Token Authentication with JSON Web Tokens & Roles
  • Utilize all three types of relationships in your database: one-to-one, one-to-many, many-to-many
  • Use the HTTP request methods GET, POST, PUT & DELETE
  • Implement best practices like a proper structure for your Web API, Dependency Injection, asynchronous calls with async/await and Data-Transfer-Objects (DTOs)
  • Use LINQ to filter, sort, map, select and access your entities.
  • Seed data with code-first migrations programmatically

Table of Contents:
00:00:00 🚀 .NET 6 Web API & Entity Framework Core Jump Start
00:02:24 Introduction
00:04:35 Create a new Web API
00:12:56 First API Call
00:16:48 Github Repository & .gitignore File
00:20:27 Web API Introduction
00:21:01 Mode-View-Controller (MVC) Design Pattern
00:23:15 New Models
00:26:45 New Controller & GET a new Character
00:37:19 First Steps with Attribute Routing
00:42:28 Routing with Parameters
00:44:50 HTTP Request Methods Explained
00:48:01 Add a new Character with POST
00:52:07 Best Practice: Web API Structure
00:55:37 Character Service
01:03:35 Asynchronous Calls
01:07:58 Proper Service Response with Generics
01:14:30 Data-Transfer-Objects (DTOs)
01:19:13 AutoMapper
01:30:54 Update Character with PUT
01:40:43 Update Character with AutoMapper
01:44:16 DELETE a Character

🚀 .NET Jumpstart Course: https://www.udemy.com/course/net-core-31-web-api-entity-framework-core-jumpstart/?couponCode=DOTNET6YT

#dotnet #webapi #webapp 

Build .NET 6 Web App with Web API, Entity Framework & SQL Server
Nat  Grady

Nat Grady

1657762620

Wire-webapp: Wire for Web

Wire™

This repository is part of the source code of Wire. You can find more information at wire.com or by contacting opensource@wire.com.

You can find the published source code at github.com/wireapp/wire.

For licensing information, see the attached LICENSE file and the list of third-party licenses at wire.com/legal/licenses/.

If you compile the open source software that we make available from time to time to develop your own mobile, desktop or web application, and cause that application to connect to our servers for any purposes, we refer to that resulting application as an “Open Source App”. All Open Source Apps are subject to, and may only be used and/or commercialized in accordance with, the Terms of Use applicable to the Wire Application, which can be found at https://wire.com/legal/#terms. Additionally, if you choose to build an Open Source App, certain restrictions apply, as follows:

a. You agree not to change the way the Open Source App connects and interacts with our servers; b. You agree not to weaken any of the security features of the Open Source App; c. You agree not to use our servers to store data for purposes other than the intended and original functionality of the Open Source App; d. You acknowledge that you are solely responsible for any and all updates to your Open Source App.

For clarity, if you compile the open source software that we make available from time to time to develop your own mobile, desktop or web application, and do not cause that application to connect to our servers for any purposes, then that application will not be deemed an Open Source App and the foregoing will not apply to that application.

No license is granted to the Wire trademark and its associated logos, all of which will continue to be owned exclusively by Wire Swiss GmbH. Any use of the Wire trademark and/or its associated logos is expressly prohibited without the express prior written consent of Wire Swiss GmbH.

How to build the open source client

Prerequisites:

  1. Install Node.js
  2. Install Yarn

1. Fetching dependencies and configurations

Run yarn

  • This will install all dependencies and fetch a configuration for the application.

2. Build & run

Development

  1. Rename .env.localhost to .env in order to configure the application. This configuration can override/extend the configuration from the previous step.
  2. Add the following entries to your hosts file (macOS / Linux: /etc/hosts, Windows 10: %WINDIR%\system32\drivers\etc\hosts):
    • 127.0.0.1 local.wire.com (to connect with production backend)
    • 127.0.0.1 local.zinfra.io (to connect with staging backend)
  3. Run yarn start and Wire's web app will be available at: https://local.zinfra.io:8081/auth/

Install the self-signed certificate

If you would like your browser to trust the certificate from "local.wire.com" or "local.zinfra.io":

  1. Download mkcert
  2. Set the CAROOT environment variable to <WebApp Dir>/server/certificate
  3. Run mkcert -install

Production

  1. Run yarn build:prod
  2. Run cd server && yarn start:prod

Testing

To launch the full test suite (types check + linting + server tests + app tests), simply run:

yarn test

Alternatively, you can test specific parts of the app:

yarn test:(server|types|app)

CI Status

CI Lint styled with prettier

Translations

All Wire translations are crowdsourced via Crowdin.

Add new strings

Info:

  • To download translations we use Crowdin API v1, and you need to setup your username and api_key (Account API key).
  • To upload translations we use Crowdin CLI v3, and you will need to setup project_identifier and api_token (Personal Access Token).

Setup:

Create a keys/crowdin.yaml in this repository and add the following entries:

api_key: your-account-api-key
api_token: your-personal-access-token
project_identifier: wire-webapp
username: your-username

Usage:

  1. Add string variable to "src/script/strings.ts" (source for the React part of our app) and text to "i18n/en-US.json" (source for the Knockout part of our app)
  2. Create a PR and merge it after approval. When the PR gets merged, our CI will take care of uploading the english texts to Crowdin.

If our CI pipeline is broken, you still have the option to upload new strings manually. For this case do the following:

  1. Install Crowdin CLI v3
  2. Verify you have a keys/crowdin.yaml in place
  3. Run yarn translate:upload

Once translations are uploaded on Crowdin, our (and external) translators can translate the new strings on Crowdin. There is a script that will run to create PRs with translation updates. As an alternative, translations can be downloaded the following way:

  1. Verify your string shows up on Crowdin project: wire-webapp
  2. Add translation on Crowdin
  3. Approve translation on Crowdin
  4. Run yarn translate:download

Contributing

Contributions are welcome! Feel free to check our issues page.

The following commits will help you getting started quickly with our code base:

Author: Wireapp
Source Code: https://github.com/wireapp/wire-webapp 
License: GPL-3.0 license

#electron #webapp #javascript #typescript 

Wire-webapp: Wire for Web
Corey Brooks

Corey Brooks

1657270786

Building Rich Web-based UI for Browsers and Native Apps with Blazor

What’s next for Blazor, and .NET on WASI

This tutorial will show the current state-of-the-art in Blazor for building rich web-based UI for browsers and native apps. 

Do you build web UIs, API servers, or native desktop/mobile apps? Then .NET Core wants to give you more capabilities and productivity!

In this demo-centric talk, Microsoft developer/architect Steve will show the current state-of-the-art in Blazor for building rich web-based UI for browsers and native apps. This will include powerful new features shipped in .NET 6, as well as upcoming enhancements under development for .NET 7 and .NET MAUI. We’ll also look at more experimental future possibilities, including running .NET Core on WASI (WebAssembly on the server) which creates entirely new cloud and edge hosting options and lets you bring .NET code to places it’s never been before.

#blazor #dotnet #webapp #webdev 

Building Rich Web-based UI for Browsers and Native Apps with Blazor
Dylan  Iqbal

Dylan Iqbal

1656919170

What is Spin | Introducing Spin

Spin is a framework for building and running event-driven microservice applications with WebAssembly (Wasm) components. With Spin, we’re trying to make it easier to get started with using WebAssembly on the server so that we can all take advantage of the security, portability, and speed WebAssembly provides when it comes to running microservices.

Structure of a Spin Application

  1. A Spin application manifest (spin.toml) file which defines where your WebAssembly components live and what triggers them.
  2. One or more WebAssembly components.

Spin executes the component(s) as a result of events being generated by the trigger(s) defined in the spin.toml file.

Example Spin Application

The following illustrates how to define an HTTP application.

HTTP Handler

This hello_world function written in Rust defines a component that takes a Request and returns a Result<Response>.

#[http_component]​
fn hello_world(_req: Request) -> Result<Response> {​
    Ok(http::Response::builder()​
        .status(200)​
        .body(Some("Hello, Fermyon!".into()))?)​
}​

Spin Manifest

Once the code is compiled to a WebAssembly component, it can be referenced in a spin.toml file to create an HTTP application like below.

spin_version = "1"
name = "spin-hello-world"
trigger = { type = "http", base = "/" }
version = "1.0.0"

[[component]]
id = "hello"
source = "<path to compiled Wasm module>"
[component.trigger]
route = "/hello"

Running a Spin Application

Running this application with the spin CLI is as simple as using the spin up command. Because a trigger type of http is specified in the spin.toml, spin up will start a web server:

$ spin up
Serving HTTP on address http://127.0.0.1:3000
Available Routes:
  hello: http://127.0.0.1:3000/hello

Any time a request is made on the /hello route, it will invoke the hello_world function. Adding another component is as simple as adding another [[component]] stanza to the spin.toml file.

Original article source at https://spin.fermyon.dev/ 

#spin #webapp #microservices #webassembly #wasm 

What is Spin | Introducing Spin
Rust  Language

Rust Language

1656919053

Rust, WebAssembly & Spin | Building Microservices

Building microservices with WebAssembly, Rust and Spin

In this tutorial, you'll learn how to create fast, secure and portable Microservices with WebAssembly, Rust and Spin. 

Spin is a framework for building and running event-driven microservice applications with WebAssembly (Wasm) components.

With Spin, we’re trying to make it easier to get started with using WebAssembly on the server so that we can all take advantage of the security, portability, and speed WebAssembly provides when it comes to running microservices.

In this session, we will introduce the WebAssembly component model, and how Fermyon uses it together with Rust to create fast, secure, and portable microservices.

#rust #webassembly #wasm #spin #microservice #webapp 

Rust, WebAssembly & Spin | Building Microservices

Data Visualizations Tutorial | Web App Dashboards with Python & Dash

Learn how to use Python and Dash library to create, style, and host an interactive data analysis web application.

If not long ago the creation of analytical web applications required knowledge of several programming languages, today you can create a data visualization interface in pure Python. One popular tool for this has become Dash, which allows data scientists to display results in interactive web applications.

In this guide, we’ll cover:

  • How to create a Dash app
  • Main library components
  • How to customize the app style
  • How to make an application interactive
  • How to deploy an application to a remote server (using Heroku as an example)

What is Dash?

Dash is an open-source framework for building data visualization interfaces. After being released in 2017 as a Python library, Dash was soon extended for R and Julia.

The library was created and maintained by a Canadian company called Plotly. Perhaps you know about her from the popular graphics libraries that bear her name. Plotly opened source Dash and released it under the MIT license, so the library is free to use.

Dash is based on and integrates three frameworks:

  1. Flask provides web server functionality.
  2. React renders the web interface.
  3. Plotly.js generates charts.

You don’t have to worry about these technologies working together. You just need to write the code in Python, R, or Julia and add some CSS.

If you are used to analyzing data using Python, Dash is a useful addition to your toolbox. Here are some practical examples of the library’s capabilities:

Setting up a virtual environment

To develop your application, you need a directory to store your code and data, as well as a clean Python 3 virtual environment. To create them, follow the instructions for your operating system.

Windows. Open a command prompt and run the following commands:

mkdir avocado_analytics && cd avocado_analytics
python -m venv venv venv\Scripts\activate.bat

The first command will create a project directory and change the current working directory. The second command will create the virtual environment, and the last command will activate it. You may need to specify a file path to python.exe instead of a command python .

MacOS or Linux. The meaning of the following terminal commands is identical to those for Windows:

mkdir avocado_analytics && cd avocado_analytics
python3 -m venv venv source venv/bin/activate

Next, you need to install the following libraries into the virtual environment:

python -m pip install dash==1.13.3 pandas==1.0.5

The Dash and pandas libraries will be installed in the virtual environment. The virtual environment allows the use of specific versions of the libraries, similar to those used in this tutorial.

Finally, you will need some data that can be downloaded from the accompanying lesson materials.

Save the data file in the root directory of the project. By now, you should have a virtual environment with the required libraries and data in the project root folder. The project structure looks like this: avocado.csv

avocado_analytics/
├── venv/
└── avocado.csv

How to create an app with Dash

Let’s break down the process of creating a Dash application into two steps:

  1. We initialize the application and define the appearance using the application layout ( layout).
  2. We determine through callbacks ( callbacks) which parts of the application are interactive and what they react to.

Initializing the Dash Application

First, let’s create an empty file called app.py. Next, we will fill it out step by step and explain what is happening, and at the end of the section, you will find its entire contents.

Here are the first few lines of app.py:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

data = pd.read_csv("avocado.csv")
data = data.query("type == 'conventional' and region == 'Albany'")
data["Date"] = pd.to_datetime(data["Date"], format="%Y-%m-%d")
data.sort_values("Date", inplace=True)

app = dash.Dash(__name__)

First, we import the required libraries:

  • dash will help initialize the application
  • dash_core_components allows you to create interactive components: charts, drop-down lists, date ranges, etc.
  • dash_html_components allows you to access HTML tags
  • pandas helps to read and display data in an organized manner

Next, we read the data and process it for use in the control panel. On the last line, we create an instance of the Dash class.

If you’ve used Flask before, then the initialization of the Dash class is already familiar to you. In Flask, we usually initialize a WSGI (short for Web Server Gateway Interface) application with Flask(__name__). For Dash apps, we use Dash(__name__).

Defining the Dash Application Layout

Now we will define the layout of the application, its appearance. In our case, the layout will consist of a title, description and two diagrams.

app.layout = html.Div(
    children=[
        html.H1(children="Avocado Analytics",),
        html.P(
            children="Analyze the behavior of avocado prices"
            " and the number of avocados sold in the US"
            " between 2015 and 2018",
        ),
        dcc.Graph(
            figure={
                "data": [
                    {
                        "x": data["Date"],
                        "y": data["AveragePrice"],
                        "type": "lines",
                    },
                ],
                "layout": {"title": "Average Price of Avocados"},
            },
        ),
        dcc.Graph(
            figure={
                "data": [
                    {
                        "x": data["Date"],
                        "y": data["Total Volume"],
                        "type": "lines",
                    },
                ],
                "layout": {"title": "Avocados Sold"},
            },
        ),
    ]
)

Well, let’s go step-by-step what’s going on here.

This code defines layout property of app object . The appearance of the application is described using a tree structure consisting of Dash components.

We start by defining the parent component html.Div, then add a heading html.H1and paragraph html.Pas children. These components are equivalent to HTML tags div, h1and p accordingly. Component arguments are used to change the attributes or content of tags. For example, to indicate what is inside a div tag , we use in html.Div an argument children.

Components also have other arguments, such as style, className or id that refer to attributes of HTML tags. In the next section, we’ll see how to use these properties to style the toolbar.

Thus, the Python code will be converted to the following HTML code:

<div>
  <h1>Avocado Analytics</h1>
  <p>
    Analyze the behavior of avocado prices and the number
    of avocados sold in the US between 2015 and 2018
  </p>
  <!-- The rest of the app -->
</div>

Next two components of dcc.Graph are described below. The first chart displays the average avocado prices over the study period, and the second shows the number of avocados sold in the US during the same period.

Under the hood, Dash uses Plotly.js to create graphs. The dcc.Graph components expect a figure object or a Python dictionary containing the graph data and layout that we are passing in our case.

There are two lines of code left to help launch the application:

if __name__ == "__main__":
    app.run_server(debug=True,
                   host = '127.0.0.1')

These lines allow you to run your Dash application locally using Flask’s built-in server. The debug = Trueparameter from app.run_server allows hot reloads: when we make changes to the application, it automatically reloads without restarting the server.

Finally, the full version of app.py. You can copy the code to blank app.py and check the result.

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

data = pd.read_csv("avocado.csv")
data = data.query("type == 'conventional' and region == 'Albany'")
data["Date"] = pd.to_datetime(data["Date"], format="%Y-%m-%d")
data.sort_values("Date", inplace=True)

app = dash.Dash(__name__)

app.layout = html.Div(
    children=[
        html.H1(children="Avocado Analytics",),
        html.P(
            children="Analyze the behavior of avocado prices"
            " and the number of avocados sold in the US"
            " between 2015 and 2018",
        ),
        dcc.Graph(
            figure={
                "data": [
                    {
                        "x": data["Date"],
                        "y": data["AveragePrice"],
                        "type": "lines",
                    },
                ],
                "layout": {"title": "Average Price of Avocados"},
            },
        ),
        dcc.Graph(
            figure={
                "data": [
                    {
                        "x": data["Date"],
                        "y": data["Total Volume"],
                        "type": "lines",
                    },
                ],
                "layout": {"title": "Avocados Sold"},
            },
        ),
    ]
)

if __name__ == "__main__":
    app.run_server(debug=True,
                   host = '127.0.0.1')

It’s time to finally ✨launch the application ✨.

Open a terminal in the project root and in the virtual project environment. Run python app.py, then go to the address http://localhost:8050in your browser.

The control panel should look something like this:

We now have a working version, but we will improve it further.

🌟Controlling panel appearance

The reason why I liked Dash is that it becomes very flexible in customizing the look and feel of your application. We can use our own CSS or JavaScript files, embed images, and configure additional options.

How to style Dash components

You can style components in two separate ways:

  • Use a style argument of distinct components.
  • Provide an external CSS file.

The style argument takes a Python dictionary with key-value pairs consisting of the CSS property names and the values ​​we want to set.

When we want to change the size and color of the H1 element in app.py, we can set the style argument like this:

html.H1(
    children="Avocado Analytics",
    style={"fontSize": "48px", "color": "red"},
),

In this case, the title will be formatted in 48 pixels.

The downside to ease of use styleis that code like this will become more difficult to maintain as the codebase grows. If there are several of the same components on the control panel, most of the code will be repeated. You can use a CSS file instead.

If you want to include your own local CSS or JavaScript files, you must create a folder named assets/ in the root directory of the project and save the necessary files in it.

You can then use the className arguments or id of components to style them using CSS. When converted to HTML tags, these arguments match the class and id attributes .

When we want to customize the font size and text color of an H1 element in app.py, we can use an className argument:

html.H1(
    children="Avocado Analytics",
    className="header-title",
),

Setting the argument specifies the className class attribute for the H1element. Then, in the CSS file (style.css) in the assets/ folder, we specify how we want it to look:

.header-title {
  font-size: 48px;
  color: red;
}

How to improve the toolbar appearance

Let’s find out how to customize the appearance of the toolbar. Let’s make the following improvements:

  • Add the site icon ( favicon) and title.
  • Let’s change the font family.
  • We use an external CSS file to style the Dash components.

Adding external resources to the application

Let’s create assets/folder in the root of the project. Save the favicon.ico icon and the style.css.

By now, the project structure should look like this:

avocado_analytics/
├── assets/
│   ├── favicon.ico
│   └── style.css
├── venv/
├── app.py
└── avocado.csv

app.py requires several changes. You need to include an external style sheet, add a title to the toolbar, and style the components using the style.cssfile:

external_stylesheets = [
    {
        "href": "https://fonts.googleapis.com/css2?"
                "family=Lato:wght@400;700&display=swap",
        "rel": "stylesheet",
    },
]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.title = "Avocado Analytics: Understand Your Avocados!"

Here we specify the CSS file and font family that we want to load into the application. External files are loaded before the application body is loaded. The external_stylesheets argument is used to add external CSS files, and external_scripts is used for external JavaScript files such as a Google Analytics script.

Customizing component styles

In the code below, we add className with the appropriate class selector to each of the components representing the title of the dashboard:

app.layout = html.Div(
    children=[
        html.Div(
            children=[
                html.P(children="🥑", className="header-emoji"),
                html.H1(
                    children="Avocado Analytics", className="header-title"
                ),
                html.P(
                    children="Analyze the behavior of avocado prices"
                    " and the number of avocados sold in the US"
                    " between 2015 and 2018",
                    className="header-description",
                ),
            ],
            className="header",
        ),

The header-description class assigned to the paragraph component has a matching selector in style.css:

.header-description {
    color: #CFCFCF;
    margin: 4px auto;
    text-align: center;
    max-width: 384px;
}

Another significant change is the graphics. New code for the price chart:

html.Div(
    children=[
        html.Div(
            children=dcc.Graph(
                id="price-chart",
                config={"displayModeBar": False},
                figure={
                    "data": [
                        {
                            "x": data["Date"],
                            "y": data["AveragePrice"],
                            "type": "lines",
                            "hovertemplate": "$%{y:.2f}"
                                                "<extra></extra>",
                        },
                    ],
                    "layout": {
                        "title": {
                            "text": "Average Price of Avocados",
                            "x": 0.05,
                            "xanchor": "left",
                        },
                        "xaxis": {"fixedrange": True},
                        "yaxis": {
                            "tickprefix": "$",
                            "fixedrange": True,
                        },
                        "colorway": ["#17B897"],
                    },
                },
            ),
            className="card",
        ),

We removed the default bar that appears on the chart and set the hover pattern so that when you hover over the data point, the price is displayed in dollars. So $2.5 will be displayed instead of 2.5.

We also set up the axis, the color of the picture, the format of the title in the section of the chart layout. We also wrapped the schedule in html.Div with the class card class. This will give the graphic a white background and add a little shadow underneath. Similar changes have been made to the sales and volume schedules. Here is the complete code of the updated app.py:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
data = pd.read_csv("avocado.csv")
data = data.query("type == 'conventional' and region == 'Albany'")
data["Date"] = pd.to_datetime(data["Date"], format="%Y-%m-%d")
data.sort_values("Date", inplace=True)
external_stylesheets = [
    {
        "href": "https://fonts.googleapis.com/css2?"
        "family=Lato:wght@400;700&display=swap",
        "rel": "stylesheet",
    },
]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.title = "Avocado Analytics: Understand Your Avocados!"
app.layout = html.Div(
    children=[
        html.Div(
            children=[
                html.P(children="🥑", className="header-emoji"),
                html.H1(
                    children="Avocado Analytics", className="header-title"
                ),
                html.P(
                    children="Analyze the behavior of avocado prices"
                    " and the number of avocados sold in the US"
                    " between 2015 and 2018",
                    className="header-description",
                ),
            ],
            className="header",
        ),
        html.Div(
            children=[
                html.Div(
                    children=dcc.Graph(
                        id="price-chart",
                        config={"displayModeBar": False},
                        figure={
                            "data": [
                                {
                                    "x": data["Date"],
                                    "y": data["AveragePrice"],
                                    "type": "lines",
                                    "hovertemplate": "$%{y:.2f}"
                                                     "<extra></extra>",
                                },
                            ],
                            "layout": {
                                "title": {
                                    "text": "Average Price of Avocados",
                                    "x": 0.05,
                                    "xanchor": "left",
                                },
                                "xaxis": {"fixedrange": True},
                                "yaxis": {
                                    "tickprefix": "$",
                                    "fixedrange": True,
                                },
                                "colorway": ["#17B897"],
                            },
                        },
                    ),
                    className="card",
                ),
                html.Div(
                    children=dcc.Graph(
                        id="volume-chart",
                        config={"displayModeBar": False},
                        figure={
                            "data": [
                                {
                                    "x": data["Date"],
                                    "y": data["Total Volume"],
                                    "type": "lines",
                                },
                            ],
                            "layout": {
                                "title": {
                                    "text": "Avocados Sold",
                                    "x": 0.05,
                                    "xanchor": "left",
                                },
                                "xaxis": {"fixedrange": True},
                                "yaxis": {"fixedrange": True},
                                "colorway": ["#E12D39"],
                            },
                        },
                    ),
                    className="card",
                ),
            ],
            className="wrapper",
        ),
    ]
)
if __name__ == "__main__":
    app.run_server(debug=True)

The panel of the updated version looks like this: app.py

Adding interactive elements to your Dash application

Dash’s interactivity is based on the paradigm of reactive programming. This means that we can link the components and elements of the application that we want to update. If the user interacts with an input component, such as a drop-down list or slider, then the data output object, such as a graph, will automatically respond to input changes.

Let’s make the control panel interactive. The new version will allow the user to interact with the following filters:

  • Production region.
  • Avocado type.
  • Date range.

Let’s start by replacing the local version of app.pywith the new version:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import numpy as np
from dash.dependencies import Output, Input

data = pd.read_csv("avocado.csv")
data["Date"] = pd.to_datetime(data["Date"], format="%Y-%m-%d")
data.sort_values("Date", inplace=True)

external_stylesheets = [
    {
        "href": "https://fonts.googleapis.com/css2?"
        "family=Lato:wght@400;700&display=swap",
        "rel": "stylesheet",
    },
]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.title = "Avocado Analytics: Understand Your Avocados!"

app.layout = html.Div(
    children=[
        html.Div(
            children=[
                html.P(children="🥑", className="header-emoji"),
                html.H1(
                    children="Avocado Analytics", className="header-title"
                ),
                html.P(
                    children="Analyze the behavior of avocado prices"
                    " and the number of avocados sold in the US"
                    " between 2015 and 2018",
                    className="header-description",
                ),
            ],
            className="header",
        ),
        html.Div(
            children=[
                html.Div(
                    children=[
                        html.Div(children="Region", className="menu-title"),
                        dcc.Dropdown(
                            id="region-filter",
                            options=[
                                {"label": region, "value": region}
                                for region in np.sort(data.region.unique())
                            ],
                            value="Albany",
                            clearable=False,
                            className="dropdown",
                        ),
                    ]
                ),
                html.Div(
                    children=[
                        html.Div(children="Type", className="menu-title"),
                        dcc.Dropdown(
                            id="type-filter",
                            options=[
                                {"label": avocado_type, "value": avocado_type}
                                for avocado_type in data.type.unique()
                            ],
                            value="organic",
                            clearable=False,
                            searchable=False,
                            className="dropdown",
                        ),
                    ],
                ),
                html.Div(
                    children=[
                        html.Div(
                            children="Date Range",
                            className="menu-title"
                            ),
                        dcc.DatePickerRange(
                            id="date-range",
                            min_date_allowed=data.Date.min().date(),
                            max_date_allowed=data.Date.max().date(),
                            start_date=data.Date.min().date(),
                            end_date=data.Date.max().date(),
                        ),
                    ]
                ),
            ],
            className="menu",
        ),
        html.Div(
            children=[
                html.Div(
                    children=dcc.Graph(
                        id="price-chart", config={"displayModeBar": False},
                    ),
                    className="card",
                ),
                html.Div(
                    children=dcc.Graph(
                        id="volume-chart", config={"displayModeBar": False},
                    ),
                    className="card",
                ),
            ],
            className="wrapper",
        ),
    ]
)


@app.callback(
    [Output("price-chart", "figure"), Output("volume-chart", "figure")],
    [
        Input("region-filter", "value"),
        Input("type-filter", "value"),
        Input("date-range", "start_date"),
        Input("date-range", "end_date"),
    ],
)
def update_charts(region, avocado_type, start_date, end_date):
    mask = (
        (data.region == region)
        & (data.type == avocado_type)
        & (data.Date >= start_date)
        & (data.Date <= end_date)
    )
    filtered_data = data.loc[mask, :]
    price_chart_figure = {
        "data": [
            {
                "x": filtered_data["Date"],
                "y": filtered_data["AveragePrice"],
                "type": "lines",
                "hovertemplate": "$%{y:.2f}<extra></extra>",
            },
        ],
        "layout": {
            "title": {
                "text": "Average Price of Avocados",
                "x": 0.05,
                "xanchor": "left",
            },
            "xaxis": {"fixedrange": True},
            "yaxis": {"tickprefix": "$", "fixedrange": True},
            "colorway": ["#17B897"],
        },
    }

    volume_chart_figure = {
        "data": [
            {
                "x": filtered_data["Date"],
                "y": filtered_data["Total Volume"],
                "type": "lines",
            },
        ],
        "layout": {
            "title": {"text": "Avocados Sold", "x": 0.05, "xanchor": "left"},
            "xaxis": {"fixedrange": True},
            "yaxis": {"fixedrange": True},
            "colorway": ["#E12D39"],
        },
    }
    return price_chart_figure, volume_chart_figure


if __name__ == "__main__":
    app.run_server(debug=True,
                   host='127.0.0.1')

Then you need to update style.css with the following code:

body {
    font-family: "Lato", sans-serif;
    margin: 0;
    background-color: #F7F7F7;
}

.header {
    background-color: #222222;
    height: 288px;
    padding: 16px 0 0 0;
}

.header-emoji {
    font-size: 48px;
    margin: 0 auto;
    text-align: center;
}

.header-title {
    color: #FFFFFF;
    font-size: 48px;
    font-weight: bold;
    text-align: center;
    margin: 0 auto;
}

.header-description {
    color: #CFCFCF;
    margin: 4px auto;
    text-align: center;
    max-width: 384px;
}

.wrapper {
    margin-right: auto;
    margin-left: auto;
    max-width: 1024px;
    padding-right: 10px;
    padding-left: 10px;
    margin-top: 32px;
}

.card {
    margin-bottom: 24px;
    box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.18);
}

.menu {
    height: 112px;
    width: 912px;
    display: flex;
    justify-content: space-evenly;
    padding-top: 24px;
    margin: -80px auto 0 auto;
    background-color: #FFFFFF;
    box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.18);
}

.Select-control {
    width: 256px;
    height: 48px;
}

.Select--single > .Select-control .Select-value, .Select-placeholder {
    line-height: 48px;
}

.Select--multi .Select-value-label {
    line-height: 32px;
}

.menu-title {
    margin-bottom: 6px;
    font-weight: bold;
    color: #079A82;
}

How to create interactive components

New html.Div above charts includes two dropdowns and a date range selector that the user can use to filter data and update charts.

This is how it looks in app.py:

html.Div(
    children=[
        html.Div(
            children=[
                html.Div(children="Region", className="menu-title"),
                dcc.Dropdown(
                    id="region-filter",
                    options=[
                        {"label": region, "value": region}
                        for region in np.sort(data.region.unique())
                    ],
                    value="Albany",
                    clearable=False,
                    className="dropdown",
                ),
            ]
        ),
        html.Div(
            children=[
                html.Div(children="Type", className="menu-title"),
                dcc.Dropdown(
                    id="type-filter",
                    options=[
                        {"label": avocado_type, "value": avocado_type}
                        for avocado_type in data.type.unique()
                    ],
                    value="organic",
                    clearable=False,
                    searchable=False,
                    className="dropdown",
                ),
            ],
        ),
        html.Div(
            children=[
                html.Div(
                    children="Date Range",
                    className="menu-title"
                    ),
                dcc.DatePickerRange(
                    id="date-range",
                    min_date_allowed=data.Date.min().date(),
                    max_date_allowed=data.Date.max().date(),
                    start_date=data.Date.min().date(),
                    end_date=data.Date.max().date(),
                ),
            ]
        ),
    ],
    className="menu",
),

The drop-down lists and date range selector serve as menus for interacting with the data:

The first component in the menu is the Region dropdown. Component code:

html.Div(
    children=[
        html.Div(children="Region", className="menu-title"),
        dcc.Dropdown(
            id="region-filter",
            options=[
                {"label": region, "value": region}
                for region in np.sort(data.region.unique())
            ],
            value="Albany",
            clearable=False,
            className="dropdown",
        ),
    ]
),

Here’s what each parameter means:

  • id - element identifier.
  • options - options displayed when selecting the dropdown list. Waits for a dictionary with labels and values.
  • value - the default value when loading the page.
  • clearable - Allows the user to leave the field blank if set True.
  • className - class selector used to apply styles

The Type and Data Range selectors have the same structure as the Region drop-down menu.

Now let’s take a look at the components of dcc.Graphs:

html.Div(
    children=[
        html.Div(
            children=dcc.Graph(
                id="price-chart", config={"displayModeBar": False},
            ),
            className="card",
        ),
        html.Div(
            children=dcc.Graph(
                id="volume-chart", config={"displayModeBar": False},
            ),
            className="card",
        ),
    ],
    className="wrapper",
),

Components lack figureargument compared to the previous version of the figuretoolbar. This is because the argument will now be generated by the callback function using the input that the user sets with the Region, Type, and Data Range selectors.

💬How to define callbacks

We have defined how the user will interact with the application. Now we need to make the application respond to user actions. For this we will use the callback functions ( callbacks).

Dash callback functions are regular Python functions with a decorator called app.callback.

When the input changes, a callback function runs, performs predefined operations (such as filtering a dataset), and returns the result to the application. Basically, callbacks bind input and output data in an application.

Here is the callback function used to update the graphs:

@app.callback(
    [Output("price-chart", "figure"), Output("volume-chart", "figure")],
    [
        Input("region-filter", "value"),
        Input("type-filter", "value"),
        Input("date-range", "start_date"),
        Input("date-range", "end_date"),
    ],
)
def update_charts(region, avocado_type, start_date, end_date):
    mask = (
        (data.region == region)
        & (data.type == avocado_type)
        & (data.Date >= start_date)
        & (data.Date <= end_date)
    )
    filtered_data = data.loc[mask, :]
    price_chart_figure = {
        "data": [
            {
                "x": filtered_data["Date"],
                "y": filtered_data["AveragePrice"],
                "type": "lines",
                "hovertemplate": "$%{y:.2f}<extra></extra>",
            },
        ],
        "layout": {
            "title": {
                "text": "Average Price of Avocados",
                "x": 0.05,
                "xanchor": "left",
            },
            "xaxis": {"fixedrange": True},
            "yaxis": {"tickprefix": "$", "fixedrange": True},
            "colorway": ["#17B897"],
        },
    }

    volume_chart_figure = {
        "data": [
            {
                "x": filtered_data["Date"],
                "y": filtered_data["Total Volume"],
                "type": "lines",
            },
        ],
        "layout": {
            "title": {
                "text": "Avocados Sold",
                "x": 0.05,
                "xanchor": "left"
            },
            "xaxis": {"fixedrange": True},
            "yaxis": {"fixedrange": True},
            "colorway": ["#E12D39"],
        },
    }
    return price_chart_figure, volume_chart_figure

First, we define the output using Output objects. These objects take two arguments:

  • The identifier of the element that they will change when they execute the function.
  • Property of the item being changed. For example, Output("price-chart", "figure") update the figure property of the "price-chart" item.

Then we define the inputs using Input objects, they also take two arguments:

  • The ID of the item that they will watch for changes.
  • The property of the observed element that they should accept when a change occurs.

That is Input("region-filter", "value"), it will monitor the "region-filter"element’s changes and will accept its property if the element changes.

Note

The object discussed here is Input imported from dash.dependencies. Do not confuse it with a component coming from dash_core_components. These objects are not interchangeable and have different purposes.

In the last lines of the above block, we define the body of the function. In the above example, the function takes input (region, avocado type, and date range), filters it, and generates objects for price and volume charts.

This is the latest version of our toolbar. We made it not only beautiful but also interactive. The only missing step is to make the result shareable with others.

Deploying a Dash application on Heroku

We have finished building the application. We have a beautiful, fully interactive dashboard. Now we will learn how to deploy it.

In fact, Dash apps are the same as Flask apps, so they have the same deployment capabilities. In this section, we will deploy the application to Heroku hosting (with a free plan).

Before starting, make sure you have installed the Heroku Command Line Interface (CLI) and Git. To make sure that both programs are present on the system, run the version check commands in the terminal:

git --version
heroku --version

Next, we need to make a small change to app.py. After initializing the application, add a variable named server:

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server

This add-on is required to run the application using a WSGI server. The built-in Flask server is not recommended for use in a production environment as it cannot handle a lot of traffic.

In the root directory of the project, create a file with a name in which we specify the Python version for the Heroku application: runtime.txt

python-3.8.6

When deployed, Heroku will automatically detect that this is a Python application and use the appropriate build package. If you provide the runtime.txt file as well, the server will determine the Python version that the application will use.

Then, in the root directory of the project, create requirements.txt file where we list the libraries required to install the Dash application on the web server:

dash==1.13.3
pandas==1.0.5
gunicorn==20.0.4

In the requirements.txt file there is a gunicornpackage, which we have not mentioned before. Gunicorn is basically a HTTP server that is often used to deploy Flask applications in a production environment.

Now let’s create a file named Procfile with the following content:

web: gunicorn app:server

This file tells the Heroku application what commands to run to launch our application.

Then you need to initialize the Git repository. To do this, go to the root directory of the project and run the following command:

git init

This command will initiate the creation of a Git repository for avocado_analytics/. That is, Git will keep track of the changes we make to files in that directory.

However, there are files that are not worth tracking with Git. For example, we usually do not want to track the contents of the virtual environment directory, bytecode files, and metadata files such as .DS_Store.

Create a file in the root directory named .gitignore and the following contents:

# Only if you are using macOS
venv *.pyc .DS_Store

This ensures that the repository does not track unnecessary files. Now let’s fix the state of the project:

git add . git commit -m 'Add dashboard files'

Make sure everything is in place before the last step. The project structure should look like this:

avocado_analytics/
├── assets/
│   ├── favicon.ico
│   └── style.css
├── venv/
├── app.py
├── avocado.csv
├── Procfile
├── requirements.txt
└── runtime.txt

Finally, you need to create an application in Heroku, upload your code there using Git, and run the application on one of the free Heroku server options. To do this, run the following commands:

heroku create APP-NAME  # Insert your app name instead of APP-NAME
git push heroku master
heroku ps:scale web=1

That’s it. We created and deployed a data dashboard. To access the application, just copy the link: https://APP-NAME.herokuapp.com/ and replace it with the name you defined in the previous step. APP-NAME

Conclusion

Congratulations! You have just created, configured and deployed your dashboard using Dash. We’ve gone from a simple dashboard to fully interactive and deployed on a remote server. With this knowledge, we can use Dash to create analytic applications that can be shared with colleagues and customers.

#webapp #dashboards #python #dash #datavisualizations

Data Visualizations Tutorial | Web App Dashboards with Python & Dash
Thierry  Perret

Thierry Perret

1655736540

Comment Créer Une interface Utilisateur D'application Web Avec Python

Une petite introduction à la création d'interfaces utilisateur d'applications Web avec rien d'autre que Python.

Anvil vous permet de créer le front-end de votre application entièrement en Python - aucun code HTML, CSS ou Javascript n'est requis. Vous pouvez créer votre interface utilisateur en faisant glisser et en déposant des composants dans le concepteur visuel d'Anvil ou en ajoutant des composants à l'aide de code Python :


 

Voyons comment vous pouvez utiliser l' éditeur Anvil pour créer une interface utilisateur en transformant cette application en une application "hello world" qui dit bonjour à vos utilisateurs.

Au milieu de l'IDE Anvil se trouve l' éditeur de formulaires qui est divisé en mode conception et mode code. À droite de l'éditeur Anvil, vous trouverez la boîte à outils .


 

Vous pouvez faire glisser et déposer des composants, tels que Labels , à partir de la boîte à outils pour créer votre interface utilisateur. Cette application hello world aura également besoin d'un TextBox pour que les utilisateurs entrent leur nom :


 

Pour configurer les composants, vous pouvez modifier leurs propriétés sur le côté droit du panneau Propriétés . Cela inclut à la fois les informations affichées par le composant et son style :


 

Chaque composant est un objet Python, vous pouvez donc également définir les propriétés du composant dans la vue Code de l'éditeur de formulaire :
 

Tous les composants ont des événements qu'ils peuvent déclencher. Par exemple, lorsqu'un utilisateur de votre application clique sur un composant Button , il déclenche un événement de clic. Nous pouvons créer une méthode Python dans la vue Code à appeler lorsque cela se produit. Dans la méthode click de votre Button, vous pouvez appeler la alertfonction d'Anvil pour afficher une alerte qui dit bonjour à vos utilisateurs :

Vous pouvez maintenant cliquer sur Exécuter pour tester votre application et son interface. Vos utilisateurs peuvent maintenant entrer leur nom et cliquer sur le say hibouton affiche l'alerte :

 

L'utilisation du concepteur par glisser-déposer n'est pas votre seule option pour créer des interfaces utilisateur dans Anvil. Vous pouvez également créer et ajouter des composants à votre interface utilisateur directement dans le code :
 

Anvil est livré avec tous les composants d'interface utilisateur habituels - boutons, zones de texte, listes déroulantes, tableaux, etc. Et si cela ne suffit pas, vous pouvez créer vos propres composants personnalisés et les partager avec d'autres applications. 

Cette histoire a été initialement publiée sur https://hackernoon.com/how-to-make-a-web-app-user-interface-with-python

#python #programming #webapp 

Comment Créer Une interface Utilisateur D'application Web Avec Python
高橋  花子

高橋 花子

1655733900

Pythonを使用してWebアプリのユーザーインターフェイスを構築する

PythonだけでWebアプリのユーザーインターフェイスを構築するための一口サイズの紹介。

Anvilを使用すると、アプリのフロントエンドを完全にPythonで構築できます。HTML、CSS、またはJavascriptは必要ありません。Anvilのビジュアルデザイナーでコンポーネントをドラッグアンドドロップするか、Pythonコードを使用してコンポーネントを追加することにより、UIを構築できます。


 

このアプリをユーザーに挨拶する「HelloWorld」アプリに変えて、 Anvilエディターを使用してユーザーインターフェイスを作成する方法を見てみましょう。

Anvil IDEの中央には、デザインビューとコードビューに分割されたフォームエディタがあります。アンビルエディタの右側にツールボックスがあります。


 

ラベルなどのコンポーネントをツールボックスからドラッグアンドドロップして、ユーザーインターフェイスを構築できます。このhelloworldアプリには、ユーザーが名前を入力するためのTextBoxも必要です。


 

コンポーネントを構成するには、プロパティパネルの右側でコンポーネントのプロパティを編集できます。これには、コンポーネントが表示する情報とそのスタイルの両方が含まれます。


 

すべてのコンポーネントはPythonオブジェクトであるため、フォームエディタのコードビューでコンポーネントのプロパティを設定することもできます。
 

すべてのコンポーネントには、発生させることができるイベントがあります。たとえば、アプリのユーザーがButtonコンポーネントをクリックすると、クリックイベントが発生します。これが発生したときに呼び出されるPythonメソッドをコードビューに作成できます。Buttonのclickメソッドで、Anvilのalert関数を呼び出して、ユーザーに挨拶するアラートを表示できます。

これで、[実行]をクリックして、アプリとそのインターフェースをテストできます。これで、ユーザーは自分の名前を入力でき、say hiボタンをクリックするとアラートが表示されます。

 

ドラッグアンドドロップデザイナを使用することは、Anvilでユーザーインターフェイスを構築するための唯一のオプションではありません。コンポーネントを作成して、コードで直接ユーザーインターフェイスに追加することもできます。
 

Anvilには、ボタン、テキストボックス、ドロップダウン、テーブルなど、通常のUIコンポーネントがすべて付属しています。それでも不十分な場合は、独自のカスタムコンポーネントを作成して、他のアプリケーションと共有できます。 

このストーリーはもともとhttps://anvil.worksで公開されました

#python  #programming  #webapp 

Pythonを使用してWebアプリのユーザーインターフェイスを構築する
曾 俊

曾 俊

1655733600

如何使用 Python 构建 Web 应用程序用户界面

只用 Python 构建 Web 应用程序用户界面的简短介绍。

Anvil 让您可以完全用 Python 构建应用程序的前端 - 无需 HTML、CSS 或 Javascript。您可以通过在 Anvil 的可视化设计器中拖放组件或使用 Python 代码添加组件来构建您的 UI:


 

让我们看看如何使用Anvil 编辑器创建用户界面,将这个应用程序变成一个向用户打招呼的“hello world”应用程序。

Anvil IDE 的中间是表单编辑器,它分为设计视图和代码视图。在 Anvil 编辑器的右侧,您会找到Toolbox


 

您可以从工具箱中拖放组件(例如Labels)来构建您的用户界面。这个 hello world 应用还需要一个TextBox供用户输入姓名:


 

要配置组件,您可以在属性面板的右侧编辑它们的属性。这包括组件显示的信息及其样式:


 

每个组件都是一个 Python 对象,因此您还可以在表单编辑器的代码视图中设置组件的属性:
 

所有组件都有可以引发的事件。例如,当您的应用程序的用户单击一个Button组件时,它会引发一个单击事件。我们可以在代码视图中创建一个 Python 方法,以便在发生这种情况时调用。在您的 Button 的 click 方法中,您可以调用 Anvil 的alert函数来显示一个向您的用户打招呼的警报:

现在您可以单击运行来测试您的应用程序及其界面。您的用户现在可以输入他们的姓名并单击say hi按钮显示警报:

 

使用拖放设计器并不是在 Anvil 中构建用户界面的唯一选择。您还可以直接在代码中创建组件并将其添加到用户界面:
 

Anvil 带有所有常用的 UI 组件——按钮、文本框、下拉列表、表格等等。如果这还不够,您可以创建自己的自定义组件并与其他应用程序共享它们。 

这个故事最初发表在 https://hackernoon.com/how-to-make-a-web-app-user-interface-with-python

#python  #programming  #webapp 

如何使用 Python 构建 Web 应用程序用户界面