connexion.request.{body, form, etc}() seem to hang
Description
I found that connexion.request does not appear to work the way the documentation implies. It seems to hang when async methods are called (I tested form() and body()).
Expected behaviour
Given:
from pathlib import Path
import connexion
from starlette.responses import PlainTextResponse, Response
async def post_greeting(body, selfie=None) -> Response:
form = await connexion.request.form()
print(f"form is {form}")
return PlainTextResponse(f"Hello body={body} selfie={selfie}!", status_code=201)
app = connexion.AsyncApp(__name__, specification_dir="spec")
app.add_api("openapi.yaml", arguments={"title": "Hello World Example"})
if __name__ == "__main__":
app.run(f"{Path(__file__).stem}:app", port=8080)
And spec
openapi: "3.0.1"
info:
title: Form Data
version: "1.0"
servers:
- url: /openapi
paths:
/greeting:
post:
summary: Generate greeting
operationId: hello.post_greeting
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
name:
type: string
selfie:
type: string
format: binary
required:
- name
- selfie
responses:
200:
description: OK
Any request to this endpoint seems to hang. The docs seem to at least imply that it's OK to access these items:
Actual behaviour
$ curl -F name=dave -F selfie=nah http://localhost:8080/openapi/greeting
<hangs forever>
I found https://github.com/encode/starlette/issues/495, which documents similar issues therein. I am not knowledgeable enough about the innards here to know if this is the same issue or not.
Steps to reproduce
See above.
Additional info:
Output of the commands:
python --versionPython 3.10.13pip show connexion | grep "^Version\:"3.0.1
Thanks for the report @danielbprice.
These are not available because Connexion already consumes them. I agree that this is not ideal. I think it would be logical if Connexion only consumes them if you let Connexion inject them into your view function. This should be possible but requires some refactoring. For now, I added a warning to the docs in #1813.
Having the same problem here, but also added to the fact that our controller is autogenerated by Swagger, whose online_controller.py functions are not async :skull: . Our workaround that at least initiates the server but hangs forever when accessing the endpoint is as follows:
def my_endpoint(body): # noqa: E501
"""<endpoint description...>
"""
check_permission(PERMISSIONS)
if connexion.request.mimetype == "application/json":
body = asyncio.run(connexion.request.json())
return my_functions(body)