0

I am trying to send a post request to a python backend running on a fast API server. The current method I am using below throws error test() takes 0 positional arguments but 1 was given but I haven't passed any arguments to the function test. Why is this happening and how can I fix it? Thanks in advance.

import requests

data = {"foo": "bar"}

r = requests.post("http://127.0.0.1:8000/test", json = data)

print(r.text)
import requests
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.route('/test', methods=['POST'])
def test(request):
    print(request.form['foo'])
    return 'thisIsResponse'

EDIT: as per John Gordon's answer I updated my code by assigning a positional argument to the test function now I get error TypeError: 'method' object is not subscriptable

Stack trace:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/usr/lib/python3/dist-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/home/spree/.local/lib/python3.10/site-packages/fastapi/applications.py", line 271, in __call__
    await super().__call__(scope, receive, send)
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/applications.py", line 118, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/cors.py", line 84, in __call__
    await self.app(scope, receive, send)
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/home/spree/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/home/spree/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/routing.py", line 706, in __call__
    await route.handle(scope, receive, send)
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/home/spree/.local/lib/python3.10/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
  File "/home/spree/spreeTv/./ods_info.py", line 30, in test
    print(request.form['foo'])
TypeError: 'method' object is not subscriptable
seriously
  • 1,202
  • 5
  • 23
  • Have a look at [How to read body as any valid json](https://stackoverflow.com/questions/64379089/how-to-read-body-as-any-valid-json) – Maurice Meyer Mar 04 '23 at 22:25
  • Please have a look at [this answer](https://stackoverflow.com/a/70636163/17865804), as well as [this answer](https://stackoverflow.com/a/73761724/17865804) – Chris Mar 05 '23 at 07:23

2 Answers2

1

but I haven't passed any arguments to the function test

You aren't calling test() directly; the FastAPI framework calls it for you, automatically, when a matching web request is received.

And when it does, it passes one argument. So the error is that you've defined test() to accept no arguments.

Change your definition to this:

def test(request):

(... where did you think request.form came from?)

John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • I applied that now it throws error: ```TypeError: 'method' object is not subscriptable ``` – seriously Mar 04 '23 at 22:30
  • @seriously Are we supposed to guess where this error is? Please update your question to include the full error trace message. – John Gordon Mar 04 '23 at 22:32
  • OK, apparently `request.form` is a function, and cannot be accessed the way you're trying to do it. Where did you get that code? Did you copy it as an example from somewhere? – John Gordon Mar 04 '23 at 22:46
  • yeah I got it from an SO post that had Flask running as a server: https://stackoverflow.com/questions/38070373/how-to-send-and-receive-http-post-requests-in-python – seriously Mar 04 '23 at 22:52
  • Well, you're not using Flask here, you're using FastAPI. Why would you use Flask code as an example? – John Gordon Mar 04 '23 at 23:20
  • I thought they had a similar request access structure. I figured wrong! – seriously Mar 04 '23 at 23:26
1

EDITED

Here's a canonical way to get request body as any valid JSON in FastAPI.

If you want to stick to the current solution, there are two things to be changed:

  • you're sending a JSON payload, not form data - use request.json() to get it
  • however, request.json() returns a coroutine, so to use it, I'd recommend to mark your function as async (more details here)
@app.route('/test', methods=['POST'])
async def test(request):
    print(await request.json())

P.S. Just a note: FastAPI relies on type annotations to determine which arguments to pass. So if you need request variable to be an actual request object, just let the framework know about this:) Though in this case it will pass a request object anyway.

from fastapi import Request

@app.route('/test', methods=['POST'])
def test(request: Request):
    ...
Oleh Rybalchenko
  • 6,998
  • 3
  • 22
  • 36