Skip to content

Python & Redis-Datenbank

Verschoben Linux
  • Erste Gehversuche mit einer Redis DB & Python.

    Was ist Redis?

    The open source, in-memory data store used by millions of developers as a database, cache, streaming engine, and message broker.

    Ich nutze Redis schon länger, z.B. in diesem Forum als Datenbank oder als lokaler Cache für meine Nextcloud Installation.

    Die Redis DB läuft als Docker Container zum Testen.

    docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest
    

    und in der Python Umgebung dann

    pip install redis
    

    Erster Test

     import redis
     
     data = {
             'project' : 'Portfolio',
             "version": "0.0.1",
             "settings_path": "/home/frankm/settings_portfolio.json",
             "theme": "dark"
         }
     
     r = redis.Redis(host='localhost', port=6379, db=0)
     r.json().set('settings', '$', data)  # DB setzen und mit Daten (data) füllen
     
     json_settings = r.json().get('settings', '$')
     main_settings = r.json().get('settings', '$.main_settings')
     project_name = r.json().get('settings', '$..project')
     version = r.json().get('settings', '$..version')
     
     print(json_settings)
     # [{'main_settings': {'project': 'Portfolio', 'version': '0.0.1', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}}]
     
     print(main_settings)
     # [{'project': 'Portfolio', 'version': '0.0.1', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}]
     
     print(project_name)
     # ['Portfolio']
     
     print(project_name[0])
     # Portfolio
     
     # Wir aktualisieren das data objekt mit einem neuen Wert.
     data.update({"version": "0.0.2"})
     print("DATA", data)
     
     # Wir speichern das data objekt in der Redis Datenbank
     r.json().set('settings', '$', data)  # DB setzen und mit Daten (data) füllen
     # Kontrolle ob Version 0.0.2 ist
     json_settings = r.json().get('settings', '$')
     version = r.json().get('settings', '$..version')
     print(json_settings)
     print(version)
    

    Ausgabe

    /home/frankm/PycharmProjects/redis/venv/bin/python /home/frankm/PycharmProjects/redis/main.py 
    [{'project': 'Portfolio', 'version': '0.0.1', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}]
    []
    ['Portfolio']
    Portfolio
    DATA {'project': 'Portfolio', 'version': '0.0.2', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}
    [{'project': 'Portfolio', 'version': '0.0.2', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}]
    ['0.0.2']
    
    Process finished with exit code 0
    

    Erster Test erfolgreich!

    Zweiter Test

    import redis
    
    data = {
        'main_settings': {
            'project' : 'Portfolio',
            "version": "0.0.1",
            "settings_path": "/home/frankm/settings_portfolio.json",
            "theme": "dark"
        }
    }
        
    r = redis.Redis(host='localhost', port=6379, db=0)
    r.json().set('settings', '$', data)  # DB setzen und mit Daten (data) füllen
    
    json_settings = r.json().get('settings', '$')
    main_settings = r.json().get('settings', '$.main_settings')
    project_name = r.json().get('settings', '$..project')
    version = r.json().get('settings', '$..version')
    
    print(json_settings)
    # [{'main_settings': {'project': 'Portfolio', 'version': '0.0.1', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}}]
    
    print(main_settings)
    # [{'project': 'Portfolio', 'version': '0.0.1', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}]
    
    print(project_name)
    # ['Portfolio']
    
    print(project_name[0])
    # Portfolio
    
    # Wir aktualisieren das data objekt mit einem neuen Wert.
    data['main_settings']["version"] = "0.0.2"
    data.update()
    
    #data.update({"version": "0.0.2"})
    print("DATA", data)
    
    # Wir speichern das data objekt in der Redis Datenbank
    r.json().set('settings', '$', data)  # DB setzen und mit Daten (data) füllen
    # Kontrolle ob Version 0.0.2 ist
    json_settings = r.json().get('settings', '$')
    version = r.json().get('settings', '$..version')
    print(json_settings)
    print(version)
    

    Ausgabe

    /home/frankm/PycharmProjects/redis/venv/bin/python /home/frankm/PycharmProjects/redis/main.py 
    [{'main_settings': {'project': 'Portfolio', 'version': '0.0.1', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}}]
    [{'project': 'Portfolio', 'version': '0.0.1', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}]
    ['Portfolio']
    Portfolio
    DATA {'main_settings': {'project': 'Portfolio', 'version': '0.0.2', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}}
    [{'main_settings': {'project': 'Portfolio', 'version': '0.0.2', 'settings_path': '/home/frankm/settings_portfolio.json', 'theme': 'dark'}}]
    ['0.0.2']
    
    Process finished with exit code 0
    
    Process finished with exit code 0
    

    Zweiter Test erfolgreich

    Bitte niemals Redis Datenbanken OHNE Passwort im Netz laufen lassen. Danke!!

  • FrankMF FrankM verschob dieses Thema von Privat am
  • Ok, das o.g dient ja nur der groben Orientierung und dazu zu schauen ob das funktioniert und man es evt. auch verstanden hat 😉

    Das muss man aber ein wenig anders in ein vorhandenes Projekt einbauen. Wir bauen uns mal eine Klasse dafür.

    Wir brauchen eine Initialisierung, damit man mit Redis überhaupt arbeiten kann.

    #####################
    # Init Redis
    #####################
    r = redis.Redis(host='192.168.3.213', port=6379, db=0)
    
    # Redis Server am Leben?
    try:
        response = r.ping()
        print("Client =", r.ping())
        print("Client =", type(r.ping()))
    except redis.ConnectionError:
        exit("Konnte keine Verbindung zum Redis-Server aufbauen")
    

    Ok, hier mal wieder der alt bekannte Fehler. Benutzt bitte durchgehend englische Wörter beim Coden. Es macht das Leben einfacher. Ich verfalle leider beim Ausprobieren von Funktionen und neuen Dingen immer wieder dazu es in deutsch zu beschriften. Macht später dann immer viel Arbeit...Also bitte sofort richtig machen.

    Zum obigen Code. Wir initialisieren die Redis Datenbankverbindung. Danach ein kurzer Test, ob der Docker Container läuft, wenn nicht gibt es eine Fehlermeldung.

    Danach die Klasse und die erste Funktioen. Wir erzeugen einen Eintrag in der DB. Dazu erstellen wir ein Dictonary und speichern es. Die Funktion kommt später.

    ###############################################
    # Class for Redis DB
    ###############################################
    class Redis:
        """ Class to handle Redis DB
        Data ia stored in Docker Container
        atm not persistent
        """
    
        @staticmethod
        def init():
            data = {}
    
            data = {
                'project': 'Portfolio',
                "version": "0.0.1",
                "settings_path": str(settings_path),
                "theme": "dark"
            }
            Redis.save(data)
            return (data)
    

    Nun liegen die Daten in der Redis Datenbank, Doch wir müssen sie ja auch irgendwie in unser Projekt laden.

    @staticmethod
        def load():
            data = {}
            # Wir laden die Daten aus der Redis DB und erzeugen die Dictonary data
            # diese wird zurückgegeben!
    
            project = r.json().get('settings', '$..project')
            version = r.json().get('settings', '$..version')
            settings_path = r.json().get('settings', '$..settings_path')
            theme = r.json().get('settings', '$..theme')
    
            data = {
                'project': str(project[0]),
                "version": str(version[0]),
                "settings_path": str(settings_path[0]),
                "theme": str(theme[0])
            }
            return(data)
    

    Nun die Funktion zum Speichern

    @staticmethod
        def save(file):
    
            try:
                r.json().set('settings', '$', file)  # DB setzen und mit Daten (data) füllen
            except:
                print("Error")
    

    Was macht man, wenn man nur einen Wert ändern möchte?

    @staticmethod
        def update(key, value):
    
            # Example: Redis.update('version', '0.0.9')
    
            settings.update({key: value})
    
            Redis.save(settings)
    

    Und nun, was ich dann noch mache.

    settings = Redis.init()
    

    wenn noch nichts vorhanden ist. Ansonsten

    settings = Redis.load()
    

    Damit lade ich die Daten in das Python Objekt settings.

    Und so spricht man dann die Daten an.

    print("Theme:", settings['theme'])
    print("Version:", settings['version'])
    

    Ändern eines Wertes

    Redis.update('version', '0.0.2')
    

    Und zum Speichern des Ganzen Datensatzes (settings)

    Redis.save(settings)
    
  • Heute dann die nächste Herausforderung. Mein JSON soll so aussehen, damit ich das entsprechend erweitern kann.

    Stocks {0: {'stockname': 'Deutsche Telekom Aktie', 'wkn1': '4534543534', 'wkn2': 'sfsdfsdfsfdfd', 'quantity': 100}, 1: {'stockname': 'Henkel', 'wkn1': '4534543534', 'wkn2': 'sfsdfsdfsfdfd', 'quantity': 50}}
    

    Die Daten sollen wie oben schon ausprobiert, in einer Redis Datenbank liegen. So weit auch kein großes Problem. ABER, der Zugriff auf diese Daten war dann meine nächste Hürde 🙂

    Ok, ich habe also mehrere Einträge im JSON File bzw. in der Datenbank. Wie komme ich da nun wieder dran. Ein paar ☕ später dann die Lösung.

    Wie komme ich an den einzelnen Eintrag, also über den Index??

    r1.json().get('stocks', 1)
    

    Gibt als Ergebnis

    {'stockname': 'Henkel', 'wkn1': '4534543534', 'wkn2': 'sfsdfsdfsfdfd', 'quantity': 50}

    Ok, das passt schon mal. Somit kann man dann gewohnt auf die einzelnen Elemente zugreifen.

    print("TESTING", testing['stockname'])
    

    Ausgabe

    TESTING Henkel
    

    Ok, Teil 1 erledigt. Jetzt habe ich ja irgendwann mehrere Elemente in der Liste und brauch dann den letzten Index , um damit was machen zu können. Also, z.B. durch die Daten zu loopen.

    objkeys = r1.json().objkeys('stocks')
    print("Objkeys", objkeys)
    

    Ausgabe

    Objkeys ['0', '1']
    

    Ok, kommt eine Liste des Index zurück. Damit kann man arbeiten 😉

    Ich hatte dann zum Testen mittels einer while Schleife die Daten geladen, aber jetzt beim Tippen klingelt es und wir machen das schön mit enumerate 😉

    @staticmethod
    def load():
        data = {}
    
        for count, value in enumerate(objkeys):
            testing = r1.json().get('stocks', count)
            data[count] = {
                "stockname": testing['stockname'],
                "wkn1": testing['wkn1'],
                "wkn2": testing['wkn2'],
                "quantity": testing['quantity']}  
       return data
    

    Somit habe ich die Daten aus der Redis Datenbank in einem Objekt und kann damit arbeiten.

  • Portfolio - mein kleines Flask Projekt

    Python3
    5
    0 Stimmen
    5 Beiträge
    177 Aufrufe
    FrankMF

    Hab ChatGPT nochmal nach der Installation auf einem Production Server befragt.

    ChatGPT

    Certainly! Here's a short example of the steps you can follow to deploy a Flask application on a production server using Nginx and Gunicorn:

    Prepare your server:

    Set up a server (e.g., using a cloud provider like AWS, DigitalOcean, or a dedicated server) and ensure it has a clean, up-to-date installation of a Linux distribution (e.g., Ubuntu or CentOS).

    Install required software:

    Install necessary software packages on your server. You'll need Python, pip (Python package manager), Nginx, and Gunicorn. You can use your distribution's package manager (e.g., apt for Ubuntu or yum for CentOS) to install these dependencies.

    Deploy your Flask application:

    Copy your Flask application code and any required dependencies to your server.

    Set up a virtual environment (optional but recommended):

    Create a virtual environment for your Flask application to isolate its dependencies. You can use venv or virtualenv for this purpose.

    Install Flask and any required Python packages within your virtual environment:

    pip install flask

    Test your Flask application:

    Ensure your Flask application runs correctly within your server's virtual environment.

    Configure Gunicorn:

    Create a Gunicorn configuration file (e.g., gunicorn_config.py) to specify the settings for running your Flask application. Here's a simple example: workers = 4 # Number of Gunicorn worker processes bind = '0.0.0.0:8000' # The address and port Gunicorn should listen on

    Start Gunicorn:

    Start Gunicorn with your Flask application: gunicorn -c gunicorn_config.py your_app:app

    Configure Nginx:

    Create an Nginx server block (often located in /etc/nginx/sites-available) to define how Nginx should handle incoming requests. Here's a simplified example: server { listen 80; server_name your_domain.com www.your_domain.com; location / { proxy_pass http://127.0.0.1:8000; # Pass requests to Gunicorn proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

    Enable the Nginx server block and restart Nginx:

    sudo ln -s /etc/nginx/sites-available/your_config /etc/nginx/sites-enabled/ sudo nginx -t # Test Nginx configuration sudo systemctl restart nginx

    Configure your DNS:

    Point your domain name to your server's IP address.

    Secure your server (optional but recommended):

    Set up SSL/TLS certificates for your domain to enable HTTPS. You can use Let's Encrypt for free SSL certificates.

    Monitor your application:

    Set up monitoring tools and logs to keep track of your application's performance and troubleshoot any issues.

    These are the basic steps to deploy a Flask application on a production server with Nginx and Gunicorn. Please note that this is a simplified example, and there are many additional considerations, such as database configuration, security, and optimization, depending on your specific application and requirements. It's also important to keep your server and software up to date and follow security best practices to ensure the stability and security of your production environment.

    Das werde ich doch mal ausprobieren 😎

  • Redis Insight - Desktop UI

    Redis
    1
    0 Stimmen
    1 Beiträge
    104 Aufrufe
    Niemand hat geantwortet
  • Redis - systemd anpassen

    Redis
    1
    0 Stimmen
    1 Beiträge
    76 Aufrufe
    Niemand hat geantwortet
  • Python - Frameworks

    Python3
    2
    0 Stimmen
    2 Beiträge
    107 Aufrufe
    FrankMF

    Und mal hier parken

  • PyWebIO - put_buttons

    PyWebIO
    2
    0 Stimmen
    2 Beiträge
    172 Aufrufe
    FrankMF

    Und noch eine kleine Übung, wie man den Buttton abhängig von einem Value enabled/disabled

    # we build header and tdata for table tab_mount = [] for count, value in enumerate(backups): if count == 0: tab_mount.append(['No.', 'Backup name of the restic data backup', 'Actions']) if backups[value].init == "0": tab_mount.append([count + 1, backups[count].name, put_buttons([ dict(label='Mount', value='Mount', color='primary', disabled=True), dict(label='UMount', value='UMount', color='primary', disabled=True), dict(label='Restore', value='Restore', color='primary', disabled=True), ] , onclick=partial(actions, count + 1)) ]) else: tab_mount.append([count + 1, backups[count].name, put_buttons([ dict(label='Mount', value='Mount', color='primary'), dict(label='UMount', value='UMount', color='primary'), dict(label='Restore', value='Restore', color='primary'), ], onclick=partial(actions, count + 1)) ])
  • Redis Replication - Can't handle RDB format version 10

    Verschoben Redis
    1
    0 Stimmen
    1 Beiträge
    3k Aufrufe
    Niemand hat geantwortet
  • Redis - Zweite Instanz

    Redis
    1
    0 Stimmen
    1 Beiträge
    225 Aufrufe
    Niemand hat geantwortet
  • Wenn dir der Redis-Server flöten geht....

    Verschoben Redis
    3
    0 Stimmen
    3 Beiträge
    546 Aufrufe
    FrankMF

    So, nach einer kleinen Pause und ein wenig nachdenken ist mir doch noch was eingefallen 😉

    Backports! Man so einfach!

    nano /etc/apt/sources.list

    Das folgende eintragen.

    # backports deb http://deb.debian.org/debian stretch-backports main

    Danach ein

    apt update

    Und dann schauen wir uns mal die Version an....

    apt -t stretch-backports search redis-server Sorting... Done Full Text Search... Done golang-github-stvp-tempredis-dev/stretch-backports 0.0~git20160122.0.83f7aae-1~bpo9+1 all Go package to start and stop temporary redis-server processes libtest-redisserver-perl/oldstable,oldstable 0.20-1 all redis-server runner for tests python-hiredis/oldstable,oldstable 0.2.0-1+b2 amd64 redis protocol reader for Python 2.X using hiredis python3-hiredis/oldstable,oldstable 0.2.0-1+b2 amd64 redis protocol reader for Python using hiredis redis/stretch-backports 5:5.0.3-3~bpo9+2 all Persistent key-value database with network interface (metapackage) redis-server/stretch-backports 5:5.0.3-3~bpo9+2 amd64 [residual-config] Persistent key-value database with network interface

    Und die habe ich gestern Abend gebaut.

    127.0.0.1:6379> INFO # Server redis_version:5.0.5

    Ok, das schmerzt jetzt 😛