Home » Beitrag verschlagwortet mit 'WebApp'

Schlagwort-Archive: WebApp

React JS – Einführung

Diese wunderbare Einführung in das React JS Gui Framework macht es völlig unnötig hier noch mehr zu schreiben.

Dass ich trotzdem noch etwas Schreibe ist mehr als Mittel gedacht für mich selbst einig Merkpunkte nochmals zu recapitulieren.

Building Blocks

Importieren von

import React from 'react';
import ReactDOM from 'react-dom';

GUI-Compoent-Modell

Nun können React Componenten als Klassen angelegt werden:

class Square extends React.Component {
  render() {
    return (
      <button className="square" onClick={function() { console.log('click'); }}>
        {this.props.value}
      </button>
    );
  }
}

class Board extends React.Component {
    renderSquare(i) {
        return (<Square value={this.props.squares[i]} onClick={() => this.props.onClick(i)} />);
    }

    render() {
        return (
            <div>
                <div className="board-row">
                    {this.renderSquare(0)}
                    {this.renderSquare(1)}
                    {this.renderSquare(2)}
                </div>
                <div className="board-row">
                    {this.renderSquare(3)}
                    {this.renderSquare(4)}
                    {this.renderSquare(5)}
                </div>
                <div className="board-row">
                    {this.renderSquare(6)}
                    {this.renderSquare(7)}
                    {this.renderSquare(8)}
                </div>
            </div>
        );
    }
}

Obiger Code zeigt die definition von zwei Componenten (Board und Square). Was durch diese Component im GUI angezeigt wird ist dadurch definiert, was ihre render Methode zurück gibt.
Dieses Rückgabe-Object wird auch React Element genannt.
Im obigen Beispiel wird das React Element mittels JSX Notation beschrieben, welche HTML imitiert.
Die Mitgabe von Sub-Elementen (-Componenten) and den Parser geschieht im Beispiel mit:

return (<Square value={this.props.squares[i]} onClick={() => this.props.onClick(i)} />);

Die Component-Sub-Klasse (im Beispiel ‚Square‘) wird also wie ein HTML-Tag referenziert!

Parameter-Übergabe und Modell-GUI-Synchronisation

Parameter-Übergabe

Wird eine Sub-Component z.B. so ins GUI einbezogen …

return (<Square meinWert={myVar}>

dann kann sie nachher in der Sqare-Component so ausgelesen werden:

this.parms.meinWert

Status und Modell-GUI-Synchronisation

Status Definition

Der von React verwaltete State muss im Constructor definiert werden:

class Game extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            meineVar: 'Mein Wert' 
        };
    }

Beachte:

  • super(props) ist zu programmieren!
  • Der State einer Component ist privat!
Status Update

Mittels this.setState() wird der State in der render Methode vom Programmierer nachgeführt. React führt automatisch die States der Unter-Komponenten nach.

this.setState({meineVar: 'Hallo Welt'});

Flask WebApp Request handling

Request-Typen und ihr Handling

Request-TypHandling (Python)
URL parameter:
/foo?field1=value
value1 = request.args.get(field1)
Form inputun = reqest.form.get(‚username‘)
pw = request.form.get(‚password‘)
application/jsondata_string = request.data
data_dictionary = json.loads(data_string)

Erste Flask Python Webapp mit DB zugriff über sqlAlchemy

Referenzen

Overall Example

Python HTTP-Server (Flask) Applikation, die vom Browser aufgerufen mit ‚Hello <name>‘ antwortet, wobei der Name von der Personen-Tabelle der DB gelesen wird.
Flask wird dabei benutzt um den HTTP Server zur Verfügung zu stellen und darin die Web-App auf definierter URL anzubieten.
SQLAlchemy (in der Flask-Version) bietet die APIs um DB Entitäten als Klassen (z.B. ‚Person‘) formulieren zu können diese als Objekte auf die relationale DB zu mappen (ORM provider).

flask-postgres-sql-hello-app.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__) #Create a flask app with the name of this runnable python file (stored in the env var __name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://myDB:pw@localhost:5432/testDB'
db = SQLAlchemy(app)

class Person(db.Model):
  __tablename__ = 'persons'
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(), nullable=False)

#create all defined entities:
db.create_all()

#Insert an object to the DB:
person1 = Person(name = 'Marc')
db.session.add(person1)
db.session.commit()

person = Person.query.first()

#Handle web request on the web root:
@app.route('/')
def index():
    return 'Hello ' + person.name

# Wird dieser Code auskommentiert, dann kann diese HTTP-Server-App 
# durch 'python dieses-file-py' gestartet werden.
#if __name__ == '__main__':
#   app.run()

Define an Entity

class Person(db.Model):
  __tablename__ = 'persons'
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(), unique=False, nullable=False)
  ahv = db.Column(db.String(), unique=True, nullable=False)

How to run a Flask HTTP Server

Das obige HTTP-Server-Script flask-postgres-sql-hello-app.py wird gestartet mit:

> flask run

nachdem die Umgebungsvariablen FLASK_APP=pfad/flask-postgres-sql-hello-app.py gesetzt ist (Windows).
In Linux wird anscheinend so aufgerufen: >FLASK_APP=pfad/flask-postgres-sql-hello-app.py flask run

Debug-Mode: (Autorerun des HTTP-Server-Scripts)
Env. Variable setzen: FLASK_DEBUG=true

Remark flask --reload probably does the same as set FLASK_DEBUG=TRUE: Reloads the app as soon as code has changed.

Alternative Start-Methode:
Sieh code auch oben:

# Wird dieser Code auskommentiert, dann kann diese HTTP-Server-App 
# durch 'python dieses-file-py' gestartet werden.
#if __name__ == '__main__':
#   app.run()

Soll die Server-App von aussen Aufrufbar sein:

>flask run --host=0.0.0.0

oder

if __name__ == '__main__':
   app.run(host="0.0.0.0")

Use Python Interactive Console to Import script and query script defined Entities

C:\tmp\Python_Workspace1\src>python

>>> from flask_postgres_sql_hello_app import db,Person
>>> Person.query.all()
[<Person ID: 5, name: Marc>
, <Person ID: 9, name: Marc>
, <Person ID: 10, name: Marc>

Funktioniert nur mit PY-Files deren Namen nach Konvention ist (kein ‚-‚).

Object Lifecycle in SQLAlchemy

The Lifecycle is: –object instantiated–> transient— query add executed–> pending –qery select/filter OR commit exec–> flushed –commit ex.–> committed

Flushed heisst: Im internen (in Memory) ORM-Object-Model-Cache sind die Änderungen bereits geschrieben.

!! ORM Selects (z.B. Person.query.all()) erhält bereits alle Objekte, die oberhalb im Code mit session.query.add(person) hinzugefügt/verändert/gelöscht wurden. –> ORM select-artige Queries löschen Flush aus!
Der SQL Select (direkt auf der DB) zeigt diese aber erst nach einem Commit!