Python: Jak użyć requests do wysłania danych JSON, danych POST, argumentów w url i plików do serwera aiohttp.web
Dane JSON
requests
używa json=
do wysyłania JSON
i automatycznie zamienia na text i dodaje nagłówek 'Content-Type': 'application/json'
.
import requests
r = requests.post('http://0.0.0.0:8080/test', json={'param1': 'value1', 'param2': 'value2'})
To samo z użyciem standardowego data=
.
import requests
import json
r = requests.post('http://0.0.0.0:8080/test',
data=json.dumps({'param1': 'value1', 'param2': 'value2'}),
headers={'Content-Type': 'application/json'},
)
aiohttp.web
odbiera to za pomocą await request.json()
.
Może wyrzucić błąd gdy nie ma danych JSON
.
Czyta dane ze strumienia więc może wyrzucić błąd jeśli inna funkcja już pobrała dane ze strumiemia.
from aiohttp import web
routes = web.RouteTableDef()
@routes.post('/test')
async def test(request):
try:
print('JSON:', await request.json()) # json data as dictionary/list
except Exception as ex:
print('JSON: ERROR:', ex)
return web.Response(text='Received...')
app = web.Application()
app.add_routes(routes)
if __name__ == '__main__':
web.run_app(app)
Dane POST
requests
używa data=
do wysłania jako standardowe dane POST
.
import requests
r = requests.post('http://0.0.0.0:8080/test', data={'param1': 'value1', 'param2': 'value2'})
aiohttp.web
odbiera to za pomocą await request.post()
.
Nie wyrzuca błędu gdy nie ma danych POST
.
Czyta dane ze strumienia więc zwraca puste dane jeśli inna funkcja już pobrała dane ze strumiemia.
from aiohttp import web
routes = web.RouteTableDef()
@routes.post('/test')
async def test(request):
print('POST :', await request.post()) # POST data
return web.Response(text='Received...')
app = web.Application()
app.add_routes(routes)
if __name__ == '__main__':
web.run_app(app)
Argumenty w URL
requests
używa params=
do wysłanie wartości w adresie url.
Automatycznie używa uses urllib.parse
do zamiany w tekst ?param1=value1¶m2=value2
.
Jeśli w danych są specialne znaki to użyje wartości %code
.
import requests
r = requests.post('http://0.0.0.0:8080/test', params={'param1': 'value1', 'param2': 'value2'})
aiohttp.web
odbiera to za pomocą request.query_string
(jaki tekst ?param1=value1¶m2=value2
)
lub request.query
(jaki słownik {'param1': 'value1', 'param2': 'value2'}
).
Nie wyrzuca błędu gdy nie ma danych w adresie url.
Nie czyta danych ze strumienia więc nie ma to konfliktu z innymi funkcjami.
from aiohttp import web
routes = web.RouteTableDef()
@routes.post('/test')
async def test(request):
print('ARGS string:', request.query_string) # arguments in URL as string
print('ARGS :', request.query) # arguments in URL as dictionary
return web.Response(text='Received...')
app = web.Application()
app.add_routes(routes)
if __name__ == '__main__':
web.run_app(app)
PLIKI
requests
używa files=
do wysłania plików. Używa do tego listy z tuplami/krotkami.
Każda tupla opisuje jeden plik. Zawiera ona nazwę pola (jak w formularzu w HTML), uchwyt do pliku (open(...)
) lub dane z pliku (open(...).read()
)
import requests
r = requests.post('http://0.0.0.0:8080/test', files=[('file', open('client.py'))])
aiohttp.web
odbiera to za pomocą await request.multipart()
.
Wyrzuca błąd gdy nie ma plików.
Czyta dane ze strumienia więc może wyrzucić błąd jeśli inna funkcja już pobrała dane ze strumiemia.
from aiohttp import web
routes = web.RouteTableDef()
@routes.post('/test')
async def test(request):
try:
#print('MULTIPART:', await request.multipart()) # files and forms
reader = await request.multipart()
print('MULTIPART:', reader)
while True:
part = await reader.next()
if part is None:
break
print('filename:', part.filename)
print('>>> start <<<')
print(await part.text())
print('>>> end <<<')
except Exception as ex:
print('MULTIPART: ERROR:', ex)
return web.Response(text='Received...')
app = web.Application()
app.add_routes(routes)
if __name__ == '__main__':
web.run_app(app)
BODY
aiohttp.web
ma także funkcje to pobierania surowych danych z body.
Funkcje te nie wyrzucają błędu ale zwracają puste dane jeśli inna funkcja już pobrała dane ze strumiemia.
print('BODY bytes :', await request.content.read()) # body as bytes
print('BODY string:', await request.text()) # body as string
Notatki:
URL | POST | JSON | FILE | BODY | |
---|---|---|---|---|---|
async/stream/body | NO | YES | YES | YES | YES |
raise error | NO | NO | YES | YES | NO |
Funkcje, które czytają ze strumienia (POST
, JSON
, FILE
, BODY
) mogą nie zwrócić danych jeśli inna z tych funkcji wcześniej czytała dane.
Original pytanie na Stackoverflow: aiohttp.web post method get params
