Python-Requests auf Micropython-Urequests umschreiben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Abend zusammen,

als ich mich heute Mittag über den aktuellen Inzidenzwert informiert habe, bin ich über die API gestolpert die das Rober Koch Institut bereitstellt. Auf der Seite findet man tatsächlich einen Beispielcode, der in Python geschrieben ist. Hier ist der entsprechende Link dazu, der Code befindet sich am Ende der Seite:
https://arcgis.esri.de/nutzung-der-api- ... dashboard/

Ich habe den Code getestet allerdings habe ich so am Laptop keine Verwendung dafür. Ich habe aber noch einen ESP32 und ein 1,7" Display hier und dachte das könnte ich ja mal "kurz" probieren. Naja wie meistens klappt das nicht problemlos und obwohl ich eigentlich andere Projekte noch offen habe, bin ich jetzt neugierig, wie man so etwas macht.
Erst mal der Code, denn ich vom RKI kopiert habe:

Code: Alles auswählen

import requests, json

url = "https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/rki_key_data_v/FeatureServer/0/query?"
lk_id = 5566 # ID für den Kreis Steinfurt gemäß AdmUnit Tabelle
parameter = {
    'referer':'https://www.mywebapp.com',
    'user-agent':'python-requests/2.9.1',
    'where': f'AdmUnitId = {lk_id}', # Welche landkreise sollen zurück gegeben werden
    'outFields': '*', # Rückgabe aller Felder
    'returnGeometry': False, # Keine Geometrien
    'f':'json', # Rückgabeformat, hier JSON
    'cacheHint': True # Zugriff über CDN anfragen
}
result = requests.get(url=url, params=parameter) #Anfrage absetzen
resultjson = json.loads(result.text) # Das Ergebnis JSON als Python Dictionary laden
print(resultjson['features'][0]['attributes']) # Wir erwarten genau einen Datensatz, Ausgabe aller Attribute
Für Micropython gibt es 'urequests', das Problem ist, das 'urequests.get' kein 'params' entgegen nimmt.
Zum Vergleich Requests-Code:

Code: Alles auswählen

def get(url, params=None, **kwargs):
    r"""Sends a GET request.

    :param url: URL for the new :class:`Request` object.
    :param params: (optional) Dictionary, list of tuples or bytes to send
        in the query string for the :class:`Request`.
    :param \*\*kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    return request('get', url, params=params, **kwargs)
und der Urequests-Code:

Code: Alles auswählen

def get(url, **kw):
    return request("GET", url, **kw
Das ist jetzt das erste mal das ich etwas mit 'requests' mache und ich habe keine Idee, wie ich 'urequests' die Parameter übergeben könnte.

Ich habe mal das einfachste versucht und die Zeile so abgeändert:

Code: Alles auswählen

 result = urequests.get(url=url, **parameter)
Dann erhalte ich aber diese Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "<stdin>", line 26, in <module>
  File "urequests.py", line 108, in get
TypeError: unexpected keyword argument 'where'
Ich vermute das ich die Parameter anders bereitstellen muss, also kein Dictonary sondern eine andere Struktur.

Könnt ihr mir bitte sagen, wie ich weiters vorgehen muss? Ist das mit MicroPython überhaupt möglich?

Vielen Dank und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Ich würde nach "urequest get params" bei google suchen und dann einfach den ersten Treffer anschauen.
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Danke für die schnelle Antwort. Auf die Idee kam ich gar nicht, das ist ja jetzt schon fast etwas peinlich. Aber leider funktioniert die Lösung nicht problemlos.
Ich bekam schon die erste Fehlermeldung wegen:

Code: Alles auswählen

from urllib.parse import urlencode

Code: Alles auswählen

 ImportError: no module named 'urllib'

Dann habe ich mir die Datei:
https://pypi.org/project/micropython-urllib.parse/#files
heruntergeladen und auf dem ESP gespeichert unter 'parse.py' gespeichert.

In meinem Programm importiere ich dann 'parse' und will mit 'parse.urlencode' dann auf 'urlencode' zugreifen.
[code]Traceback (most recent call last):
  File "<stdin>", line 39, in <module>
  File "<stdin>", line 34, in main
  File "<stdin>", line 29, in get
AttributeError: 'module' object has no attribute 'urlencode'
Habe ich die falsche Datei erwischt oder mache ich etwas grundlegendes gerade falsch?

Hier mal noch der gesamte Code:

Code: Alles auswählen

import urequests, json
import network
import parse


URL = "https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/rki_key_data_v/FeatureServer/0/query?"

PARAMETER = {'referer': 'https://www.mywebapp.com',
             'user-agent': 'python-requests/2.9.1',
             'where': 'AdmUnitId = 8417',
             'outFields': '*',
             'returnGeometry': False,
             'f': 'json',
             'cacheHint': True
             }

def connect_wlan():
    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect('XXX', 'XXX')
        while not sta_if.isconnected():
            pass
    print('network config:', sta_if.ifconfig())
    
def get(url, params=None, **kw):
    if params:
        url = url.rstrip('?') + '?' + parse.urlencode(params, doseq=True)
    return urequests.get(url, **kw)

def main():
    connect_wlan()
    result = get(URL, PARAMETER)
    resultjson = json.loads(result.text)
    print(resultjson['features'][0]['attributes'])
    
if __name__ == '__main__':
    main()
Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten