swagger-api / swagger-api/swagger-codegen

[Python] Swagger 2.0 does not support xml in python

Open
#8,995 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

Description

The python client appears to be missing xml serialization and may be missing deserialization.

When one autogenerates a python client for an endpoint that produces and consumes
application/xml, upon using the python client for that endpoint, the library throws the error:

Cannot prepare a request message for provided
arguments. Please check that your arguments match
declared content type.

in rest.py:RESTClientObject:request
Checking the sent data shows that the correct content headers are being sent, but that the body is still a dict.
The code implies that previous serialization should have been done (perhaps based on content-type)?
But the serialization was not done. So XML should be sent but does not exist yet and is not being sent.

Swagger-codegen version

2.4.1-SNAPSHOT

Swagger declaration file content or url
swagger: "2.0"
info:
  title: "carrier api"
  description: "An API to connect to the carrier"
  version: "1.0.0"
host: "mailcarrier.com"
basePath: "/api"
schemes:
# - "https"
- "http"
paths:
  /tracking:
    post:
      summary: "Gets tracking info for a single tracking_id"
      description: "Gets tracking info for a single tracking_id"
      operationId: "getTrackingInfo"
      consumes:
      - "text/xml; charset=utf-8"
      produces:
      - "text/xml; charset=utf-8"
      parameters:
        - in: header
          name: SOAPAction
          type: string
          required: true
          default: 'http://mailcarrier.com/IDhlWebApi/GetTrackingInfo'
        - in: body
          name: TrackingRequest
          description: "Tracking Request Body"
          required: true
          schema:
            $ref: "#/definitions/TrackingRequest"
      responses:
        200:
          description: "Valid input"

definitions:
  TrackingRequest:
    xml:
      name: 'Envelope'
      prefix: 'soap-env'
      namespace: 'http://schemas.xmlsoap.org/soap/envelope/'
    required:
      - Header
      - Body
    properties:
      Header:
        type: object
        xml:
          name: 'soap-env:Header'
        required:
          - xmlns:wsa
          - Action
          - MessageID
          - To
        properties:
          xmlns:wsa:
            type: string
            default: 'http://www.w3.org/2005/08/addressing'
            xml:
              attribute: true
          Action:
            type: string
            default: 'http://mailcarrier.com/IDhlWebApi/GetTrackingInfo'
            xml:
              prefix: 'wsa'
          MessageID:
            type: string
            default: 'urn:uuid:123'
            xml:
              prefix: 'wsa'
          To:
            type: string
            default: 'http://mailcarrier.com/api/DhlApi.svc'
            xml:
              prefix: 'wsa'
      Body:
        type: object
        xml:
          prefix: 'soap-env'
        required:
          - GetTrackingInfo
        properties:
          GetTrackingInfo:
            type: object
            xml:
              prefix: 'ns0'
              namespace: 'http://tempuri.org/'
            required:
              - request
            properties:
              request:
                type: string
                default: ''
                xml:
                  prefix: 'ns0'
Command line used for generation

Generate the carrierapi library

swagger-codegen generate -i carrierapi.yaml -l python -o ./carrierapi -DpackageName=carrierapi

Sample python code sample using the client:

import carrierapi
from carrierapi.rest import ApiException

# create an instance of the API class
api_instance = carrierapi.DefaultApi(carrierapi.ApiClient())
soap_action = 'http://mailcarrier.com/IDhlWebApi/GetTrackingInfo' 
tracking_request_header = carrierapi.TrackingRequestHeader(message_id='urn:uuid:123')
get_tracking_info = carrierapi.TrackingRequestBodyGetTrackingInfo()
tracking_request_body = carrierapi.TrackingRequestBody(get_tracking_info=get_tracking_info)
tracking_request = carrierapi.TrackingRequest(header=tracking_request_header, body=tracking_request_body)

try:
    # Gets tracking info for a single tracking_id
    api_instance.get_tracking_info(soap_action, tracking_request)
except ApiException as e:
    print("Exception when calling DefaultApi->get_tracking_info: %s\n" % e)
Steps to reproduce
  1. Produce a client with the above yaml file above.
  2. Run the code sample above in python 3.6 or higher.
Suggest a fix/enhancement

Please add the xml serialization/deserialization feature to python. If said feature already exists, please provide a sample at: https://github.com/swagger-api/swagger-codegen/tree/master/samples/client/petstore/python

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at rest.py:RESTClientObject:request and inspect the generated Python client behavior for the provided Swagger declaration. Compare the relevant client output with samples/client/petstore/python. Done means the Python client serializes and, where needed, deserializes XML for the reproduced content types instead of sending the body as a dict.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.