connexion
connexion copied to clipboard
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 --version
Python 3.10.13
-
pip 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)