spec-first / connexion

Connexion is a modern Python web framework that makes spec-first and api-first development easy.
https://connexion.readthedocs.io/en/latest/
Apache License 2.0
4.48k stars 762 forks source link

application/xml as requestbody does not work #1085

Closed larsschilling closed 1 year ago

larsschilling commented 4 years ago

Description

I want to provide an API via openapi3 that accepts xml. unfortunately i get an error message at the post request, which i can't get any further at the moment.

Expected behaviour

Connection should work as expected and accept xml as requestbody.

Actual behaviour

[2019-11-29 11:16:34,704] ERROR in app: Exception on /rooftop/push [POST]
Traceback (most recent call last):
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/decorator.py", line 48, in wrapper
    response = function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/security.py", line 299, in wrapper
    return function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/uri_parsing.py", line 173, in wrapper
    response = function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/validation.py", line 194, in wrapper
    response = function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/validation.py", line 388, in wrapper
    return function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/parameter.py", line 108, in wrapper
    request.files, arguments, has_kwargs, sanitize)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/operations/abstract.py", line 274, in get_arguments
    has_kwargs, sanitize))
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/operations/openapi.py", line 268, in _get_body_argument
    body_arg.update(body or {})
TypeError: cannot convert dictionary update sequence element #0 to a sequence
127.0.0.1 - - [29/Nov/2019 11:16:34] "POST /rooftop/push HTTP/1.1" 500 -

When I try the fix 518d1dd i get the following error

[2019-11-29 11:19:16,018] ERROR in app: Exception on /rooftop/push [POST]
Traceback (most recent call last):
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/decorator.py", line 48, in wrapper
    response = function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/security.py", line 299, in wrapper
    return function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/uri_parsing.py", line 173, in wrapper
    response = function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/validation.py", line 194, in wrapper
    response = function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/validation.py", line 388, in wrapper
    return function(request)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/decorators/parameter.py", line 108, in wrapper
    request.files, arguments, has_kwargs, sanitize)
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/operations/abstract.py", line 274, in get_arguments
    has_kwargs, sanitize))
  File "/Users/xx/Documents/projects/xxx/roof_findings/.venv/lib/python3.6/site-packages/connexion/operations/openapi.py", line 275, in _get_body_argument
    body_arg.update(body or {})
ValueError: dictionary update sequence element #0 has length 1; 2 is required
127.0.0.1 - - [29/Nov/2019 11:19:16] "POST /rooftop/push HTTP/1.1" 500 -

Steps to reproduce

openapi.yml

openapi: "3.0.0"
info:
  description: xxxxxxx
  version: "1.0.0"
  title: xxxxxxx
  contact:
    email: xxxxxxxx
servers:
  - url: https://xxxxxxxx
    description: API endpoint
paths:
  /rooftop/push:
    post:
      operationId: rooftop.push
      summary: take an xml push
      parameters:
        - name: X-APP-ID
          in: header
          required: true
          schema:
            type: string
            pattern: '^[A-Za-z0-9]{10}$'
          description: The application ID
      requestBody:
        content:
          application/xml:
            schema:
              $ref: '#/components/schemas/passage'
        description: take an xml push
      responses:
        200:
          description: OK
components:
  schemas:
    passage:
      type: object
      properties:
        id:
          type: string
  securitySchemes:
    apiKey:
      type: apiKey
      in: header      
      name: X-API-KEY
      x-apikeyInfoFunc: auth.apikey
security:
  - apiKey: []

request.http (restplugin vscode)

@hostname = localhost
@port = 5000
@host = {{hostname}}:{{port}}
@contentType = application/xml

###

POST http://{{host}}/rooftop/push HTTP/1.1
content-type: {{contentType}}
X-API-KEY: 2Ok1kIw8KkjPASb6tmmQ5pwrMHESlYz0
X-APP-ID: 1234567890

<passage>
    <id>550e84d0-e29b-41d4-a716-446655440022</id>
</passage>

Additional info:

Output of the commands:

dtkav commented 4 years ago

Connexion does not currently do a good job of handling XML. It doesn't know how to parse it, and would require some design changes to easily make that pluggable.

If you're planning to put some work in to add that capability, consider looking at #760 which splits out validation and serialization/deserialization logic by content type.

RobbeSneyders commented 1 year ago

No longer reproducible