ValueError: Can't resolve type from:(number, int32)
Kyria opened this issue · 5 comments
>>> from pyswagger import App
>>> app = App.create('https://esi.tech.ccp.is/latest/swagger.json?datasource=tranquility')
>>> app.op['get_markets_region_id_orders']( region_id=1002, type_id=34, order_type='all')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/spec/v2_0/objects.py", line 283, in __call__
_convert_parameter(final(p))
File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/spec/v2_0/objects.py", line 264, in _convert_parameter
c = p._prim_(v, self._prim_factory, ctx=dict(read=False))
File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/spec/v2_0/objects.py", line 184, in _prim_
return prim_factory.produce(self.schema, v, ctx) if i == 'body' else prim_factory.produce(self, v, ctx)
File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/__init__.py", line 178, in produce
raise ValueError('Can\'t resolve type from:(' + str(obj.type) + ', ' + str(obj.format) + ')')
ValueError: Can't resolve type from:(number, int32)
>>> app.op['get_markets_structures_structure_id'](structure_id=12345)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/spec/v2_0/objects.py", line 283, in __call__
_convert_parameter(final(p))
File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/spec/v2_0/objects.py", line 264, in _convert_parameter
c = p._prim_(v, self._prim_factory, ctx=dict(read=False))
File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/spec/v2_0/objects.py", line 184, in _prim_
return prim_factory.produce(self.schema, v, ctx) if i == 'body' else prim_factory.produce(self, v, ctx)
File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/__init__.py", line 178, in produce
raise ValueError('Can\'t resolve type from:(' + str(obj.type) + ', ' + str(obj.format) + ')')
ValueError: Can't resolve type from:(number, int32)
Link the the swagger.json used: https://esi.tech.ccp.is/latest/swagger.json?datasource=tranquility
It looks like every endpoints that have this issue use a referenced parameters which is a "number" / "int32" format.
"page": {
"default": 1,
"description": "Which page of results to return",
"format": "int32",
"in": "query",
"name": "page",
"type": "number"
},
If I understand correctly types defined in the JSON-Schema Draft 4. Models, used by swagger,
integer A JSON number without a fraction or exponent part.
number Any JSON number. Number includes integer.
number also contains integer by definition, so integer/int32
should work (which is not the case currently).
(also swagger validator do not report any issues with number/int32
and number/int64
. )
Can you correct this ?
Thanks in advance !
You can extend the supported primitives by following this tutorial. If it doesn't work or not fit your needs, please feel free to let me know.
Is that the correct way to do it ?
>>> from pyswagger import App
>>> from pyswagger.primitives import Primitive
>>> from pyswagger.primitives._int import create_int, validate_int
>>> factory = Primitive()
>>> factory.register('number', 'int64', create_int, validate_int)
>>> factory.register('number', 'int32', create_int, validate_int)
>>> app = App.load('https://esi.tech.ccp.is/latest/swagger.json?datasource=tranquility', prim=factory)
>>> app.prepare(True)
>>> app.op['get_markets_structures_structure_id'](structure_id=12345)
(<pyswagger.io.Request object at 0x700383b36c10>, <pyswagger.io.Response object at 0x700382d9fc50>)
FYI: your doc is missing app.prepare(strict=True)
at the end (just in case people don't know that)
About the issue itself: i don't mind having to implement myself primitive builder for custom types.
But I still feel sad that pyswagger do not support swagger defined primitives itself, because they are a bit edgy (number/int32
and number/int64
which are defined in the spec by the fact that number includes integer).
Imho, you should support these: because swagger-codegen didn't throw any errors with that type/format, neither does other libs like bravado for example... and swagger validators do not yell at these either.
But well, it's up to you at the end.
At least I have a solution for this :)
Thanks !
Do you know this one is outdated https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/2.0.md#data-types ?
(no update since early 2016, and https://swagger.io/specification/ redirects to https://github.com/OAI/OpenAPI-Specification/blob/master//versions/2.0.md ) (branch master)
To quote the spec (from swagger.io):
Primitive data types in the Swagger Specification are based on the types supported by the JSON-Schema Draft 4. Models are described using the Schema Object which is a subset of JSON Schema Draft 4.
And if you follow the JSON-Schema Draft 4 link, you get what I quoted before :
integer A JSON number without a fraction or exponent part.
number Any JSON number. Number includes integer.
FYI, from my test, this is how is defined the "number/int32" using swagger-codegen in the API class comments:
:param float page: Which page of results to return
But tbh, since there are no validation in the client, I don't believe that having it as float is the right solution (especially since it's an int32
, it's supposed to be an integer, not a float).
Also testing the endpoint with a float (the server have a validator integrated) it returns an error because it waits for an integer (number/int32) and not a float (number/float).
Hopes this helps / explains better everything :)
And thanks for your work ! 👍
number/int32
, number/int64
are added as supported primitives in v0.8.31