I'm trying to make an endpoint that takes parameters, this is my code:
from aiohttp import web
routes = web.RouteTableDef()
@routes.post('/test')
async def test(request):
print(request.query)
print(await resp.json())
return web.Response('Testing...')
app = web.Application()
app.add_routes(routes)
if __name__ == '__main__':
web.run_app(app)
When I try with requests in another terminal:
import requests
requests.post('http://localhost:8080/test', data={'param1': 'value1'})
It outputs:
<MultiDictProxy()>
Error handling request
Traceback (most recent call last):
File "C:\Users\kwiecinski\Desktop\python\SETUP\venv\lib\site-packages\aiohttp\web_protocol.py", line 418, in start
resp = await task
File "C:\Users\kwiecinski\Desktop\python\SETUP\venv\lib\site-packages\aiohttp\web_app.py", line 458, in _handle
resp = await handler(request)
File "main.py", line 69, in send_message
print(await request.json())
File "C:\Users\kwiecinski\Desktop\python\SETUP\venv\lib\site-packages\aiohttp\web_request.py", line 584, in json
return loads(body)
File "C:\Users\kwiecinski\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "C:\Users\kwiecinski\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\kwiecinski\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
It just doesn't work, what's the attribute to get the data
attribute from when I make the request?
Your server expects JSON
data.
And requests
has to use json=
instead of data=
to send it as JSON
import requests
requests.post('http://localhost:8080/test', json={'param1': 'value1'})
or it would have to manually convert dictionary
to json
string using json.dumps()
And eventually it would have to add header 'Content-Type: application/json'
but not all servers need it.
import requests
import json
requests.post('http://localhost:8080/test',
data=json.dumps({'param1': 'value1'}),
headers={'Content-Type': 'application/json'})
EDIT:
I never used aiohttp
so I had to read documentation and test in on some code.
BTW: I found out that it can't use at the same time: content.read()
, text()
, post()
, json()
, multiparts()
because they all read from the same stream (not get from variable) and after first read this stream is empty and other function has nothing to read. And this is why I had to comment BODY, POST, JSON to test code for FILES.
It is what I created:
server.py
from aiohttp import web
routes = web.RouteTableDef()
@routes.post('/test')
async def test(request):
print('\n--- request ---\n')
# ----------------------------------------------------------------------
print('ARGS string:', request.query_string) # arguments in URL as string
print('ARGS :', request.query) # arguments in URL as dictionary
# ----------------------------------------------------------------------
# >> it can't use at the same time: `content.read()`, `text()`, `post()`, `json()`, `multiparts()`
# >> because they all read from the same stream (not get from variable)
# >> and after first read this stream is empty
# ----------------------------------------------------------------------
#print('BODY bytes :', await request.content.read()) # body as bytes (post data as bytes, json as bytes)
#print('BODY string:', await request.text()) # body as string (post data as string, json as string)
# ----------------------------------------------------------------------
#print('POST :', await request.post()) # POST data
# ----------------------------------------------------------------------
#try:
# print('JSON:', await request.json()) # json data as dictionary/list
#except Exception as ex:
# print('JSON: ERROR:', ex)
# ----------------------------------------------------------------------
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='Testing...')
app = web.Application()
app.add_routes(routes)
if __name__ == '__main__':
web.run_app(app)
client.py
import requests
import json
# --- JSON ---
r = requests.post('http://0.0.0.0:8080/test', json={'param1': 'value1'})
print(r.text)
# --- JSON ---
r = requests.post('http://0.0.0.0:8080/test',
data=json.dumps({'param1': 'value1'}),
headers={'Content-Type': 'application/json'},
)
print(r.text)
# --- POST data ---
r = requests.post('http://0.0.0.0:8080/test', data={'param1': 'value1'})
print(r.text)
# --- URL data ---
r = requests.post('http://0.0.0.0:8080/test', params={'param1': 'value1'})
print(r.text)
# --- FILES ---
r = requests.post('http://0.0.0.0:8080/test', files=[('file', open('client.py'))])
print(r.text)