Skip to content

Flask - Erste Schritte

Allgemeine Diskussionen
  • Ich habe ja meine letzten kleineren Projekte mit Pywebio gemacht. Aber, so langsam komme ich damit an seine Grenzen. Da fiel mir ein, das es für Python auch noch andere Frameworks gibt. Zwei die mir spontan einfielen waren

    Ich hatte beide schon mal getestet, aber da waren meine Python Kenntnisse noch sehr begrenzt. Mittlerweile bin ich da schon ein Stück weiter. Django machte damals den komplizierten Eindruck, so das meine Wahl auf Flask fiel.

    Da man heute einen prima Personal Trainer hat, ChatGPT, habe ich diesen mal gebeten mir ein kurzes Beispiel zu generieren. Grundlage ist meine private Aktienverwaltung, die auf der ersten Seite mein Depot anzeigt usw. Die Kurse scrape ich von einer Webseite usw.

    Kurze Zeit später hatte ich ein funktionierendes Beispiel, das ich bis jetzt gut ausgebaut habe. Da Flask den Logikteil vom HTML-Teil sehr gut trennt, kann man das relativ einfach überblicken. Nach kurzem Ausprobieren, hatte ich das Konzept in seinen Grundzügen verstanden.

    Der Anfang sah so aus.

    app.py

    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    # Sample data for our table
    DATA = [
        {"id": 1, "name": "John", "email": "john@example.com"},
        {"id": 2, "name": "Jane", "email": "jane@example.com"},
        {"id": 3, "name": "Doe", "email": "doe@example.com"}
    ]
    
    @app.route('/')
    def index():
        return render_template('index.html', data=DATA)
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    templates/index.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>Flask Table Example</title>
    </head>
    <body>
        <!-- Navigation Menu -->
        <ul>
            <li><a href="#">Menu 1</a></li>
            <li><a href="#">Menu 2</a></li>
            <li><a href="#">Menu 3</a></li>
            <li><a href="#">Menu 4</a></li>
            <li><a href="#">Menu 5</a></li>
        </ul>
    
        <!-- Table Displaying Data -->
        <table border="1">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                    <th>Email</th>
                </tr>
            </thead>
            <tbody>
                {% for row in data %}
                <tr>
                    <td>{{ row.id }}</td>
                    <td>{{ row.name }}</td>
                    <td>{{ row.email }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </body>
    </html>
    
    

    Mittlerweile ist das mein Stand

    2b147097-c888-447e-8fc4-acd7f459d666-grafik.png

    Daten kommen aus einer Redis Datenbank usw. Vielleicht stelle ich das mal hier vor, wenn es "fertig" ist. Liest hier einer mit, der auch Flask nutzt?

  • Ok, ich benutze eine Funktion die sich die aktuellen Kurs abholt. Das habe ich in Pywebio mit

    put_loading()
    

    gemacht. Dafür brauche ich jetzt eine Alternative. Mir kam da in den Sinn, das mit asyncio zu machen. Den Test aus der Flask Doku ausprobiert.

    @app.route("/get-data")
    async def get_data():
        data = await async_db_query(...)
        return jsonify(data)
    

    Leicht abgewandelt in

    @app.route('/refresh', methods=['POST'])
    async def refresh():
        import time
        time.sleep(5)
        return jsonify("TEST")
    

    Kommt beim Testen die Fehlermeldung das async erst ab Version 2.0 unterstützt wird und auch nur, wenn Flask mit async installiert wurde 🤔

    Ok, kurz recherchiert. Man muss Flask mit der Option async installieren.

    (venv) frank@debian:~/PycharmProjects/flask$ pip install Flask[async]
    Requirement already satisfied: Flask[async] in ./venv/lib/python3.11/site-packages (3.0.0)
    Requirement already satisfied: Werkzeug>=3.0.0 in ./venv/lib/python3.11/site-packages (from Flask[async]) (3.0.0)
    Requirement already satisfied: Jinja2>=3.1.2 in ./venv/lib/python3.11/site-packages (from Flask[async]) (3.1.2)
    Requirement already satisfied: itsdangerous>=2.1.2 in ./venv/lib/python3.11/site-packages (from Flask[async]) (2.1.2)
    Requirement already satisfied: click>=8.1.3 in ./venv/lib/python3.11/site-packages (from Flask[async]) (8.1.7)
    Requirement already satisfied: blinker>=1.6.2 in ./venv/lib/python3.11/site-packages (from Flask[async]) (1.6.3)
    Collecting asgiref>=3.2 (from Flask[async])
    

    Danach ging mein Beispiel und es kam 5 Sekunden später folgende Anzeige im Webbrowser.

    9753d07e-a2ce-47a7-9be0-c2010684b725-grafik.png

    Dann kann ich jetzt weiter spielen..

  • Mein vorhandenes Projekt war doch etwas größer als ich gedacht hatte. Also musste ich mehr Zeit aufwenden um es nach Flask zu transferieren. Nach einiger Zeit hatte sich eine ganz ansehnliche Zahl von Dateien angesammelt und es kam wie es kommen musste, ich wusste manchmal nicht mehr, welches File ich anfassen musste. Chaos kam auf 🙂

    So fing ich an ein wenig zu recherchieren und kam auf die Funktion Blueprint von Flask. Mich ein wenig eingelesen, ChatGPT mal eben um ein Beispiel gebeten und dann angefangen die Applikation entsprechend umzubauen.

    Auch das hat Zeit gekostet. Aber, jetzt habe ich ein aufgeräumtes Projekt, was es mir wesentlich einfacher macht, daran zu arbeiten.

    5226e90d-aa20-4b20-93af-e50f8f841880-grafik.png

    Wenn ihr also mal vorhabt, so was zu coden, halte ich es für sinnvoll das Projekt von Anfang an zu strukturieren. Und zum Schluss noch ein Screenshot zum Stand des Projektes.

    a7981ffc-0f93-41f4-93e2-c914fdba5e43-grafik.png

    Und weiter geht es, ist nämlich noch nicht fertig 😀

  • FreeOTP+ Datenumzug nach Bitwarden Authenticator

    Python3 ki-generiert python
    1
    0 Stimmen
    1 Beiträge
    181 Aufrufe
    Niemand hat geantwortet
  • MongoDB - Erste Erfahrungen

    Linux mongodb linux ki-generiert
    2
    2
    0 Stimmen
    2 Beiträge
    187 Aufrufe
    FrankMF
    So frisch von der MongoDB Front und wieder viel gelernt, weil beim Üben macht man Fehler Oben war ja mongodump & mongorestore von der KI empfohlen. Hier das wie ich es gemacht habe. mongodump frank@redis-stack:~$ mongodump -u frank -p '<password>' --host 192.168.3.9 --authenticationDatabase admin -d portfolio -o mongodump/ 2024-04-06T09:29:25.174+0200 writing portfolio.stockList to mongodump/portfolio/stockList.bson 2024-04-06T09:29:25.175+0200 writing portfolio.users to mongodump/portfolio/users.bson 2024-04-06T09:29:25.175+0200 done dumping portfolio.stockList (8 documents) 2024-04-06T09:29:25.176+0200 writing portfolio.total_sum to mongodump/portfolio/total_sum.bson 2024-04-06T09:29:25.177+0200 done dumping portfolio.total_sum (1 document) 2024-04-06T09:29:25.177+0200 writing portfolio.old_total_sum to mongodump/portfolio/old_total_sum.bson 2024-04-06T09:29:25.177+0200 writing portfolio.stocks to mongodump/portfolio/stocks.bson 2024-04-06T09:29:25.177+0200 done dumping portfolio.users (4 documents) 2024-04-06T09:29:25.178+0200 writing portfolio.settings to mongodump/portfolio/settings.bson 2024-04-06T09:29:25.178+0200 done dumping portfolio.settings (1 document) 2024-04-06T09:29:25.179+0200 done dumping portfolio.old_total_sum (1 document) 2024-04-06T09:29:25.179+0200 done dumping portfolio.stocks (34 documents) mongorestore mongorestore -u frank -p '<password>' --host 192.168.3.9 --authenticationDatabase admin -d portfolio mongodump/meineDatenbank/ Hier wird die Datensicherung mongodump/meineDatenbank/ in die neue Datenbank portfolio transferiert. Grund für das Ganze? Mich hatte der Datenbank Name meineDatenbank gestört. Benutzerrechte Jetzt der Teil wo man schnell was falsch machen kann Ich hatte also die neue Datenbank, konnte sie aber nicht lesen. Fehlten halt die Rechte. Ich hatte dann so was hier gemacht. db.updateUser("frank", { roles: [ { role: "readWrite", db: "meineDatenbank" }, { role: "readWrite", db: "portfolio" }]}) Ging auch prima, kam ein ok zurück. Nun das Problem, ich hatte beim Einrichten, den User frank als admin benutzt. Durch den oben abgesetzten Befehl (frank ist ja admin), wurden die neuen Rechte gesetzt und die Rechte als Admin entzogen!! Das war jetzt nicht wirklich das was ich gebrauchen konnte. LOL Ich hatte jetzt keine Kontrolle mehr über die DB. Das war aber nicht so wirklich kompliziert, das wieder zu ändern. Die Authentication temporär abstellen. Also /etc/mongod.conf editieren und #security: security.authorization: enabled eben mal auskommentieren. Den Daemon neustarten und anmelden an der DB. mongosh --host 192.168.3.9 Danach neuen User anlegen db.createUser({ user: "<name>", pwd: "<password>", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] }) mongod.conf wieder ändern und neustarten. Danach hat man wieder eine DB mit Authentifizierung und einen neuen Admin. Ich bin diesmal, man lernt ja, anders vorgegangen. Es gibt nun einen Admin für die DB und einen User zum Benutzen der Datenbanken! So wie man es auch auf einem produktiven System auch machen würde. Wenn ich jetzt mal was an den Benutzerrechten des Users ändere, kann mir das mit dem Admin nicht mehr passieren. Hoffe ich
  • Frohes Neues 2024

    Allgemeine Diskussionen ki-generiert
    1
    1
    0 Stimmen
    1 Beiträge
    104 Aufrufe
    Niemand hat geantwortet
  • Redis - Datenbank Zugriff mit Python

    Redis redis python
    3
    1
    0 Stimmen
    3 Beiträge
    194 Aufrufe
    FrankMF
    Ich bin mit der Lernkurve noch nicht so richtig zufrieden. Eine Frage die sich mir stellte, geht das einfacher? Der Ursprung meiner Datenbank Struktur liegt in einem anderen Projekt, wo ich versucht habe Daten permanent in einem File zu speichern. Dazu hatte ich damals JSON genommen. Deswegen auch diese Zeilen self.project = str(db_client.json().get('settings', '$..project')[0]) or self.project Gut, ich hatte dann mal ChatGPT gefragt, wie macht man das so 'normalerweise'? es kam eine Klasse heraus, die ich dann intensiv ausprobiert habe, ein wenig umgebaut usw. So lange, bis ich der Meinung war, ok ich habe es verstanden. Jetzt nutzte der Code auch mehr Redis Funktionen, wie self.client.hset('settings', name, json.dumps(data)) Es waren jetzt folgende Funktionen drin hset hexists hdel hget Dokumentation -> https://redis.io/commands/hset/ Beim Durchlesen des Codes hatte ich jetzt mehr das Gefühl, so muss das sein In RedisInsight sieht das dann jetzt so aus. [image: 1695479582374-393195f7-1017-4285-8fca-734ee6b4bff7-grafik.png] Klasse class PortfolioSettings: def __init__(self, host='172.17.0.2', port=6379, db=0): if args.test_mode == 1: self.client = redis.StrictRedis(host=SERVER_IP, port=port, db=TEST[0]) else: self.client = redis.StrictRedis(host=SERVER_IP, port=port, db=LIVE[0]) def set_settings(self, name, data): """Init settings if db don't exist""" if not self.client.hexists('settings', name): self.client.hset('settings', name, json.dumps(data)) return True return False def edit_setting(self, name, data): """Edit an entry in settings""" if self.client.hexists('settings', name): self.client.hset('settings', name, json.dumps(data)) return True return False def delete_setting(self, name): """Delete an entry in settings""" return self.client.hdel('settings', name) def get_setting(self, name): """Get an entry in settings""" setting = self.client.hget('settings', name) return json.loads(setting) if setting else None def get_all_settings(self): """Get all entries in settings""" settings = self.client.hgetall('settings') return {k.decode(): json.loads(v) for k, v in settings.items()} Und hier die Initialisierung settings_data = PortfolioSettings() ##################### # Will only be executed if DB is not available! ##################### if not settings_data.get_all_settings(): # Settings initialisieren print("INIT") settings_data.set_settings("project", "Portfolio") settings_data.set_settings("version", "0.0.3") settings_data.set_settings("theme", "dark") settings_data.set_settings("url_list", ["https://www.onvista.de/aktien/Deutsche-Telekom-Aktie-DE0005557508"]) settings_data.set_settings("exchange_list", ['DKB','Smartbroker','BUX']) Teile der Klasse sind [KI-generiert] Ich war zufrieden und habe die Klasse dann in mein Projekt übernommen und den Code überall entsprechend angepasst.
  • PyPi - Pakete ein Sicherheitsproblem?

    Python3 python pypi docker
    1
    0 Stimmen
    1 Beiträge
    106 Aufrufe
    Niemand hat geantwortet
  • Python - Formatumwandlung str -> float

    Python3 python
    1
    0 Stimmen
    1 Beiträge
    840 Aufrufe
    Niemand hat geantwortet
  • Python - Frameworks

    Python3 python pywebio flet
    2
    0 Stimmen
    2 Beiträge
    140 Aufrufe
    FrankMF
    Und mal hier parken https://www.youtube.com/watch?v=Tucr8Ta-kq4&t=1911s
  • PyWebIO - Footer bearbeiten

    PyWebIO pywebio python
    1
    1
    0 Stimmen
    1 Beiträge
    109 Aufrufe
    Niemand hat geantwortet