connexion icon indicating copy to clipboard operation
connexion copied to clipboard

connexion.request.{body, form, etc}() seem to hang

Open danielbprice opened this issue 1 year ago • 2 comments

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:

image

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

danielbprice avatar Nov 17 '23 20:11 danielbprice

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.

RobbeSneyders avatar Nov 18 '23 15:11 RobbeSneyders

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)

SrSoto avatar Nov 22 '23 15:11 SrSoto