pyopenapi / pyswagger

An OpenAPI (fka Swagger) client & converter in python, which is type-safe, dynamic, spec-compliant.
MIT License
385 stars 89 forks source link

petstore example gives encoding error #142

Closed fenchu closed 6 years ago

fenchu commented 7 years ago

Hi

When I run the example in the readme.md on petstore I get the following: pyswagger v0.8.36 and python 3.6.3

:
2017-11-07 08:15:48,530 - pyswagger.core - INFO - request.file: {}
2017-11-07 08:15:48,531 - pyswagger.core - INFO - request.schemes: ['http']
2017-11-07 08:15:48,531 - pyswagger.core - INFO - applying: [api_key]
Traceback (most recent call last):
  File "./gen-petstore.py", line 36, in <module>
    pet = client.request(app.op['getPetById'](petId=1)).data
  File "/home/mortenb/.pyenv/versions/flask/lib/python3.6/site-packages/pyswagger/contrib/client/requests.py", line 74, in request
    raw=six.BytesIO(rs.content).getvalue()
  File "/home/mortenb/.pyenv/versions/flask/lib/python3.6/site-packages/pyswagger/io.py", line 416, in apply_with
    data = self.__op._mime_codec.unmarshal(content_type, self.raw, _type=_type, _format=_format, name=name)
  File "/home/mortenb/.pyenv/versions/flask/lib/python3.6/site-packages/pyswagger/primitives/codec.py", line 34, in unmarshal
    raise Exception('Could not find codec for %s, data: %s, args: %s' % (mime, data, kwargs))
Exception: Could not find codec for application/xml, data: b'<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Pet><id>1</id><name>Tom</name><photoUrls><photoUrl>http://test</photoUrl></photoUrls><tags/></Pet>', args:
{'_type': 'object', '_format': None, 'name': 'Pet'}
(flask) mortenb@MB-PC:/mnt/d/sensio-data/pyswagger$ code gen-petstore.py

Thanks

MortenB

mission-liao commented 7 years ago

For some reason that the Swagger spec behind http://petstore.swagger.io/v2/swagger.json is changed and prefer application/xml over application/xml when responding to your requests.

To make the example in README worked, here is a modified version to specify application/json as produced response when making request:

from pyswagger import App, Security
from pyswagger.contrib.client.requests import Client
from pyswagger.utils import jp_compose

# load Swagger resource file into App object
app = App._create_('http://petstore.swagger.io/v2/swagger.json')

auth = Security(app)
auth.update_with('api_key', '12312312312312312313q') # api key
auth.update_with('petstore_auth', '12334546556521123fsfss') # oauth2

# init swagger client
client = Client(auth)

# a dict is enough for representing a Model in Swagger
pet_Tom=dict(id=1, name='Tom', photoUrls=['http://test'])
# a request to create a new pet
client.request(app.op['addPet'](body=pet_Tom))

# - access an Operation object via App.op when operationId is defined
# - a request to get the pet back
req, resp = app.op['getPetById'](petId=1)
req.produce('application/json')
pet = client.request((req, resp)).data
assert pet.id == 1
assert pet.name == 'Tom'

# new ways to get Operation object corresponding to 'getPetById'.
# 'jp_compose' stands for JSON-Pointer composition
req, resp = app.resolve(jp_compose('/pet/{petId}', base='#/paths')).get(petId=1)
req.produce('application/json')
pet = client.request((req, resp)).data
assert pet.id == 1

You can compare the diff I made here, or you can follow this tutorial to add application/xml as supported xml mime codec when using pyswagger.

I would update README to reflect the issue you reported when I find some free hours later.