aiohttp.web post 方法获取参数

aiohttp.web post method get params

我正在尝试创建一个带参数的端点,这是我的代码:

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)

当我在另一个终端尝试请求时:

import requests

requests.post('http://localhost:8080/test', data={'param1': 'value1'})

它输出:

<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)

它只是不起作用,当我发出请求时获取 data 属性的属性是什么?

您的服务器需要 JSON 数据。

requests 必须使用 json= 而不是 data= 才能将其发送为 JSON

import requests

requests.post('http://localhost:8080/test', json={'param1': 'value1'})

或者它必须使用 json.dumps()

手动将 dictionary 转换为 json 字符串

最终它必须添加 header 'Content-Type: application/json' 但并非所有服务器都需要它。

import requests
import json

requests.post('http://localhost:8080/test', 
              data=json.dumps({'param1': 'value1'}), 
              headers={'Content-Type': 'application/json'})

编辑:

我从未使用过 aiohttp 所以我不得不阅读文档并测试一些代码。

BTW: 我发现不能同时使用: content.read(), text(), post(), json(), multiparts() 因为他们都从同一个流中读取(不是从变量中获取)并且在第一次读取之后这个流是空的并且其他函数没有任何可读取的。这就是为什么我必须评论 BODY、POST、JSON 来测试文件代码。

这是我创建的:

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)