Coder Social home page Coder Social logo

pyswagger's Introduction

pyswagger

Build Status Coverage Status

A python client for Swagger enabled REST API. It wouldn't be easier to try Swagger REST API by Swagger-UI. However, when it's time to unittest your API, the first option you find would be Swagger-codegen, but the better option is us.

This project is developed after swagger-py, which is a nicely implemented one, and inspired many aspects of this project. Another project is flex, which focuses on parameter validation, try it if you can handle other parts by yourselves. For other projects related to Swagger tools in python, check here.

pyswagger is much easier to use (compared to swagger-codegen, you don't need to prepare a scala environment) and tries hard to fully supports Swagger Spec in all aspects.


Features

  • convert Swagger Document from older version to newer one. (ex. convert from 1.2 to 2.0)
  • support Swagger 1.2, 2.0 on python 2.6, 2.7, 3.3, 3.5, 3.6
  • support YAML via Pretty-YAML
  • support $ref to External Document, multiple swagger.json will be organized into a group of App. And external document with self-describing resource is also supported (refer to issue).
  • type safe, input/output are converted to python types according to Data Type described in Swagger. You don't need to touch any json schema when using pyswagger. Limitations like minimum/maximum or enum are also checked. Model inheritance also supported.
  • provide function App.validate to check validity of the loaded API definition according to spec.
  • builtin client implementation based on various http clients in python. For usage of these clients, please refer to pyswagger.tests.contrib.client for details
  • not implemented parts, fire me a bug if you need it
    • Swagger 2.0
      • Schema.pattern
      • Scheme.patternProperties
      • Schema.readonly
      • Schema.allowEmptyValue
      • A scanner to validate schema
    • A WebSocket client
    • dump extension field

Tutorial


Quick Start

Before running this script, please make sure requests is installed on your environment.

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)
# prefer json as response
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

Installation

We support pip installtion.

pip install pyswagger

Additional dependencies must be prepared before firing a request. If you are going to access a remote/local web server, you must install requests first.

pip install requests

If you want to test a local tornado server, please make sure tornado is ready on your environment

pip install tornado

We also provide native client for flask app, but to use it, flask is also required

pip install flask

Reference

All exported API are described in following sections. A diagram about relations between components


Contributors


Contribution Guildeline

report an issue:

  • issues can be reported here
  • include swagger.json if possible
  • turn on logging and report with messages on console
import logging
logger = logging.getLogger('pyswagger')

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
console.setFormatter(formatter)

logger.addHandler(console)
logger.setLevel(logging.DEBUG)

... your stuff
  • describe expected behavior, or more specific, the input/output

submit a PR

  • test included
  • only PR to develop would be accepted

env preparation

pip install -r requirement-dev.txt

unit testing

python -m pytest -s -v --cov=pyswagger --cov-config=.coveragerc pyswagger/tests

pyswagger's People

Contributors

alexnigl avatar anmkh avatar dasevilla avatar gabrielc101 avatar ivocrnkovic avatar mission-liao avatar missionliao avatar n3x15 avatar olipratt avatar sobolevn avatar telepenin avatar thoppe avatar torwald-sergesson avatar tytodorov avatar vladimirkasatkin avatar wangjiannan avatar werwty avatar zadoev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyswagger's Issues

AttributeError: 'unicode' object has no attribute 'iteritems'

Hi, Mission
My project define two kinds of 'Accept' tpye, That meas the
"produces": [
"applicationcompute-v3+json",
"application/compute-v3+directory+json"
]
If produces is applicationcompute-v3+json and send request, the response Body should be like this a dic:
{
"result": [
{
"enabled": true,
"uri": "http://xxxxxx/sshkey/benguela/willa.luo/sshkey",
"key": "ssh-xxxxxxDPZQrSdUCD2e5MMf/SNWw",
"name": "/benguela/willa.luo/sshkey"
}
]
}'
And if produce is application/compute-v3+directory+json and send request, the response Body should be like this a list:
{
"result": [
"/benguela/willa.luo/"
]
}

When I use pyswagger, it seems like the response body don't support a list ? When I set produces to
"application/compute-v3+directory+json" calling reps = client.request((req,reps), )
it Occur errors:

ValueError from example (due to type: object?)

Using the latest pyswagger from github, I get the following error when I run the example from the tutorial:

Traceback (most recent call last):
  File "./example.py", line 20, in <module>
    client.request(app.op['addPet'](body=pet_Tom))
  File "/usr/local/lib/python2.7/dist-packages/pyswagger/spec/v2_0/objects.py", line 280, in __call__
    _convert_parameter(deref(p))
  File "/usr/local/lib/python2.7/dist-packages/pyswagger/spec/v2_0/objects.py", line 264, in _convert_parameter
    c = p._prim_(v)
  File "/usr/local/lib/python2.7/dist-packages/pyswagger/spec/v2_0/objects.py", line 186, in _prim_
    return prim_factory(self.schema, v) if i == 'body' else prim_factory(self, v)
  File "/usr/local/lib/python2.7/dist-packages/pyswagger/primitives.py", line 433, in prim_factory
    raise ValueError('Can\'t resolve type from:(' + str(obj.type) + ', ' + str(obj.format) + ')')
ValueError: Can't resolve type from:(object, None)

If I modify the swagger json spec file and remove the line

  "type": "object",

from the Pet, Tag and Category definitions, then things seem to work correctly.

How to get the name of the parameter for "path" in request "GET" just like "/user/{username}"

I have a definition file and there is a path like this:
"/user/{username}"

when I will get this op and run it I can write the code like the following sample:
response = client.request(myop(username="Tom"))

But when I want to traverse each op and test it, how can I know the parameter "{username}", is there any native method to get it. my meaning is I have only a swaggerAPP object and no the original json file. so I don't know whether the parameter is "username" or "user" or other value.

Top-level security requirements aren't inherited by operations

I have one API key security definition that's listed as a requirement for all the operations in my API, but it's not being applied when I make the request:

In [10]: c.app.raw.security
Out[10]: [{'api_token': []}]

In [11]: c.app.raw.securityDefinitions
Out[11]: {'api_token': <pyswagger.spec.v2_0.objects.SecurityScheme at 0x10d6729d0>}

In [12]: print c.app.op['post_import'].security
None

Data is POSTed in invalid format

in my swagger file (tried both v1.2 and v2) I have one "body" parameter:

{
  "name": "body",
  "paramType": "body" // "in" in v2
  "type": "LoginData"
}
//...
    "LoginData": {
      "id": "LoginData",
      "properties": {
        "username": {
          "type": "string"
        },
        "password": {
          "type": "string"
        }
      }
    }

I'd like my client to POST data as {"username":"","password":""} but it's instead wrapped in "body" parameter. If I change my swaggerfile to include 2 body params I get: body parameter with invalid name

problem loading resource from url

Hi, I just tried your package and I am having an issue loading my swagger resource file.

I tried:

>>> app = SwaggerApp.create('http://10.0.0.10:8080/swaggerapi/api/v1beta2')

As you can see it is not served from a swagger.json file but returned directly from a get request as json.

The SwaggerApp.create returns a 404 Not Found.

I tried saving it to a json file, but ran into other type of issues...

External $ref in paths doesn't follow a relative URI

Example (another_file.yaml is hosted alongside the parent yaml file, and works with swagger-ui):

paths:
  $ref: 'another_file.yaml'
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/core.py", line 359, in create
    app.prepare(strict=strict)
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/core.py", line 324, in prepare
    self._prepare_obj(strict=strict)
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/core.py", line 267, in _prepare_obj
    s.scan(root=self.__root, route=[Resolve()])
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/scan.py", line 125, in scan
    handle_cls(cls)
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/scan.py", line 118, in handle_cls
    ret = ff(the_self, path, obj, self.app)
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/scanner/v2_0/resolve.py", line 78, in _path_item
    _merge(obj, app, '#/paths', PathItemContext)
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/scanner/v2_0/resolve.py", line 44, in _merge
    _resolve(cur, app, prefix, ctx)
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/scanner/v2_0/resolve.py", line 26, in _resolve
    ro = app.resolve(normalize_jr(r, prefix), parser)
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/core.py", line 400, in resolve
    obj = self.root.resolve(utils.jp_split(jp)[1:]) # heading element is #, mapping to self.root
  File "---/.virtualenvs/uad/lib/python2.7/site-packages/pyswagger/spec/base.py", line 276, in resolve
    obj = obj[t]
KeyError: 'another_file.yaml'

SchemaError when json without operation_id

My json file has 2 paths without operationId and identical tags:

"paths": {
    "/api/1/game/login": {
        "post": {
            "summary": "Login to game",
            "tags": [
                "game"
            ],
            "description": "Some description here",
            "parameters": [],
            "responses": {}
        }
    },
    "/api/1/game/start": {
        "post": {
            "summary": "Start the game",
            "tags": [
                "game"
            ],
            "description": "Some description here",
            "parameters": [],
            "responses": {}
            }
        }
    }
}

I try create app

SwaggerApp.create(args.path)

Error in output:

Traceback (most recent call last):
  File ".../pyswagger/core.py", line 359, in create
app.prepare(strict=strict)
  File ".../pyswagger/core.py", line 330, in prepare
s.scan(root=self.__root, route=[tr, cy])
  File ".../pyswagger/scan.py", line 125, in scan
handle_cls(cls)
  File ".../pyswagger/scan.py", line 118, in handle_cls
ret = ff(the_self, path, obj, self.app)
  File ".../pyswagger/scanner/type_reducer.py", line 26, in _op
raise SchemaError('duplicated key found: ' + new_scope)
pyswagger.errs.SchemaError: duplicated key found: game

The problem in method _op. I suggest to make a name if specification hasn't operationId from the path and the method of operation. For example post_api_1_game_login or a similar. I could make a pull request if needed

pyswagger can handle the properties of object type is empty or not ?

Hi mission,
I wonder whether pyswagger can handle this situation or not?

"plan":{
   "type":"object",
   "additionalProperties":true,
   "properties":{

   }
},
"oplans":{
   "items":{
      "$ref":"#/definitions/plan"
   },
   "type":"array",
   "description":"List of oplans"
},

When I run client, the parameter of plan can't be validate successfully.
Thanks,
Shuang

encoding problem regarding to SwaggerRequest, SwaggerResponse

Usually, "utf-8" works for most cases. However, it's possible that servers responding something else. Now pyswagger expects everything is utf-8, and would fail when it's not.

In short, we need to take care of this case:

text/html; charset=UTF-16

One thing we can do is always decode what we go in byte-stream by the encoding method indicated by "charset", and default value is "utf-8".

Generate request template for operation

In http://petstore.swagger.io/#!/pet/addPet, click the right yellow block, a request template is generated and auto-filled in the parameter value area.

This feature is cool and it's very convenient for users. Could anyone help to support it in pyswagger?

My proposal is add a function in class Operation:

def generate_request_template(self, minimal, primitive_type_generator):
    """
    minimal: boolean, only generate 'required' fields if True
    primitive_type_generator: function to generate value for primitive type,
                              function parameter list: type, format, name
    """

Format in validation length will cause error

In primitives lines 116 - 119

if obj.minItems and len(self) < obj.minItems:
            raise errs.ValidationError('Array should be more than {0}, not {1}'.format(o.minItems, len(self)))
if obj.maxItems and len(self) > obj.maxItems:
            raise errs.ValidationError('Array should be less than {0}, not {1}'.format(o.maxItems, len(self)))

o is not defined and should be replaced to obj

Patch Requests with Body and Path param

Hey,

How do I use patch request type with both path attribute and body param for some url definition like,

Eg.,
/some/{id}
Http body:
{}

Swagger Def:
patch:
operationId: "patchSample"
parameters:
- name: id
description: some id
in: path
type: string
required: true
- name: patch
in: body
schema:
type: array

How to iterate all of the apis in the app.op?

I try to get the apis with app.op.keys(), but it return "path!##!Id".
I only want to get the ID.

And How can iterate all of the path and then get the supported method in it.
is there a sample or guide to do this?

Swagger is renamed to OpenAPI

I'm considering to provide a renamed repo/package: pyopenapi, and everything in pyswagger should be renamed, too

  • pyswagger -> pyopenapi

The version of new package would stay up with this project.

In this project, all SwaggerXXX would be renamed to XXX, (original SwaggerXXX would still be kept as fallback), they are:

  • pyswagger.SwaggerApp -> App
  • pyswagger.resolve.SwaggerResolver -> Resolver
  • pyswagger.primitives.SwaggerPrimitive -> Primitive
  • pyswagger.SwaggerSecurity -> Security

I'm not going to move the whole code base to the new repo, instead, the new repo is only an wrapper on pyswagger (better to keep all commit history in one place)

OverflowError: mktime argument out of range

Python Version: various 2.7.10+ and 3.3+
Platform: Windows 10
Traceback on import.

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    from pyswagger import SwaggerApp, SwaggerSecurity
  File "Python27\lib\site-packages\pyswagger\__init__.py", line 2, in <module>
    from .core import SwaggerApp, SwaggerSecurity
  File "Python27\lib\site-packages\pyswagger\core.py", line 4, in <module>
    from .primitives import SwaggerPrimitive
  File "Python27\lib\site-packages\pyswagger\primitives\__init__.py", line 14, in <module>
    from .render import Renderer
  File "Python27\lib\site-packages\pyswagger\primitives\render.py", line 98, in <module>
    max_date = time.mktime(datetime.date.max.timetuple())
OverflowError: mktime argument out of range

Load local files problem

I hope it's not my mistake, but maybe there is an issue if you try to refer to local files on Windows:

app = SwaggerApp._create_('file:///C:/Users/me/.../my.yaml')

I thought it would be a general python problem, but didn't found anything...

AttributeError: 'dict' object has no attribute 'merge'

I'm attempting to use pyswagger with http://api.bitbucket.org/swagger.json but can't get it to parse since it raises this error. It seems to be in AdditionalPropertiesContext.produce. The self._obj variable is set to an empty dictionary {} so the comparison to None is false:

def produce(self):
    if self._obj:
        return self._obj
    else:
        return AdditionalPropertiesContext._TmpObj(self)

I don't know the code well enough to say what it should be returning here. Any thoughts?

add requests in setup.py

After reading document. I know request is abstracted. however, the simple example in README.md will fail because the lack of request package. how about add requests in your setup.py so the basic sample in README.MD can execute without error.

YAML support

Hi, most people seem to prefer YAML for manually writing swagger specs. Would be nice if you could add support, so a lot more examples etc. can be invoked directly, without converting it manually to JSON etc :-)

The url is somethins strange for my request

I run my request and found the log like the following:
pyswagger.core - INFO - request.url: //myserver//user/

I think it should be:
http://myserver/user/

1, there is no scheme in the begin of the url
2, there are double '//" between the server and the path.

Is this correct?

multipart/form-data implementation

Tend to provide an implementation. However, the encoding spec of filename, field name with non-ASCII chars is really a mess.

At first, I think the right way is to apply RFC2047, but it states this algorithm can't apply on a "a MIME Content-Type or Content-Disposition field". Then the second spec I found is RFC2231. And I plan to do it until I finally found another SO question.

In short, they suggested to send those names, attributes in utf-8, which is not official but supported by most major web servers, because almost all browsers did this part in this way...

After all this survey, now I feel ready for multipart/form-data.
https://github.com/AntXlab/pyswagger/labels

Get a typeerror when using renderer

Hi, recently i'm trying to use pyswagger(in python 2.7) to test my swagger spec. When i use renderer to test APIs, i got: TypeError: call() takes exactly 1 argument (2 given).
My code is the same as the tutorial/render.md:

app = SwaggerApp.create('http://petstore.swagger.io/v2/swagger.json')
client = Client()
renderer = Renderer()
input_ = renderer.render_all(app.s('user').post)
resp = client.request(app.s('user').post(input_))

I'm new in python, so who can tell me what's the problem?Thank you!

A 1.2 to 2.0 converter

When processing 1.2 document, pyswagger would convert them into pyswagger.spec.v2_0.objects. If we could provide a way for pyswagger.spec.base.BaseObj to dump into JSON, pyswagger would become a useful converter.

Since there are many community tools only provides 1.2 spec, it's really useful to have a 1.2 to 2.0 converter in python.

BTW, it's not straight for converting from 2.0 to 1.2, because we need to split one document into multiple. Thus what I plan here is a forward converter, I believe versions after 1.2 would all be single document.

boolean type doesn't work

Adding a property with type "boolean" to a model definition gives an error when retrieving something containing that model with the property set.

Using python 3.4 and swagger 2.0

Example not working

Hi there, call me wrong, but the example doesn't seem to work anymore?

I tried to fix it (URL, auth, brackets, ...) but unfortunatly got lost in the deeps of some ipython sessions.
Can anybody confirm, if the example is still working (so I'm just working on a broken setup?)

When no host specified by spec, entire spec url is used as host

If I do not specify a 'host' in my swagger spec, pyswagger attempts to use the entire spec URL I gave it for the host. Swagger spec states "If the host is not included, the host serving the documentation is to be used (including the port)."

Example, if I do:
URL = hostname/api/spec
app = pyswagger.SwaggerApp.create(URL)

It then attempts to use URL as the host for all requests.
request.url: hostname/api/spec/api/auth

when it should be 'hostname/api/auth'

Thanks! This should be a simple one.

python 3.5 fails

python3.5

test_swagger.py is code got from quick start example with some codec modifications. Becase quick start example fails with unknown xml codec error

Error:
Traceback (most recent call last):
File "test_swagger.py", line 61, in
body=pet_Tom
File "/home/cd/data/projects/python/pyswagger/pyswagger/contrib/client/requests.py", line 55, in request
raw=six.StringIO(rs.content).getvalue()
TypeError: initial_value must be str or None, not bytes

It's because in python3 rs.content is binary string. So it fails here.

Full output also attached.
log.txt

test_swagger.py.txt

'unicode' object has no attribute 'scope'

while I parse swagger 1.2 protocol. I meet the error code.

it happens in upgrade.py

    166         if _auth:
    167             for name, scopes in six.iteritems(_auth):
--> 168                 o.security.append({name: [v.scope for v in scopes]})
    169 
    170         # Operation return value

ValueError: Can't resolve type from:(integer, None)

Hi,
I meet a problem. When I use pyswagger generate a client to call api, I first do Authenticate which is the api my project provide, and then call an api whose OperationId is "discoverImageList".
The first authenticate call is correct, but the second call occur error, I don't know why.

Traceback (most recent call last):
File "/scratch/shuluo/swagger/swagger_sdk/compute-controlplane/devscripts/swaggerclient/new 2.py", line 16, in
aa = client.request(app.op"discoverImageList")
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/contrib/client/requests.py", line 55, in request
raw=six.StringIO(rs.content).getvalue()
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/io.py", line 361, in apply_with
self.data = r.schema.prim(data, self.__op._prim_factory)
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/spec/v2_0/objects.py", line 92, in prim
return prim_factory.produce(self, v)
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/primitives/__init
.py", line 184, in produce
val = ret.apply_with(obj, val, ctx)
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/primitives/_model.py", line 26, in apply_with
self[k] = ctx['factory'].produce(pobj, v)
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/primitives/init.py", line 180, in produce
val = _2nd(obj, ret, val, ctx)
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/primitives/comm.py", line 40, in _2nd_pass_obj
return ret.apply_with(obj, val, ctx)
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/primitives/_array.py", line 37, in apply_with
self.extend(map(functools.partial(ctx['factory'].produce, obj.items), val))
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/primitives/init.py", line 184, in produce
val = ret.apply_with(obj, val, ctx)
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/primitives/_model.py", line 26, in apply_with
self[k] = ctx['factory'].produce(pobj, v)
File "/scratch/shuluo/swagger/swagger_sdk/pyclient/compute-controlplane/virtualenv/lib/python2.6/site-packages/pyswagger/primitives/init.py", line 176, in produce
raise ValueError('Can't resolve type from:(' + str(obj.type) + ', ' + str(obj.format) + ')')
ValueError: Can't resolve type from:(integer, None)

Can't use reponses other than 'default'

Responses other than 'default' are never selected by pyswagger.
After looking into code I realized you use returned status (int) as lookup, but schema is parsed from json, so keys in responses dict are strings. In json you can have only strings as keys.

Optional parameters are sent as 'None'

When I create a request, all my optional parameters are sent as None, and it causes problems for String enum, and date parameters. I think if an optional parameter is not given, it should be left out from the request.

Feature request - friendlier API for calling operations

I've written a wrapper for working with pyswagger that makes it easier to call operations. Maybe someday you can include some of this to make calling a simple operation a bit easier. It has a lot of magic in it (the exec is ugly, I know), but it's the best way I could find to get functions with the right signature.

import functools
from pyswagger import SwaggerApp, SwaggerSecurity
from pyswagger.contrib.client.requests import Client


OP_FUNC = '''def op_func(client, op, override_url, {}):
    kwargs = locals()
    del kwargs['client']
    del kwargs['op']
    del kwargs['override_url']

    return client.request(
        op(**kwargs),
        opt={{'url_netloc': override_url}},
    )'''


class SwaggerWrapper(object):
    def __init__(self, swagger_path, oauth_token='', override_url=''):
        self.app = SwaggerApp._create_(swagger_path)

        if oauth_token:
            auth = SwaggerSecurity(self.app)
            auth.update_with('api_token', oauth_token)
            self.client = Client(auth)
        else:
            self.client = Client()

        self.override_url = override_url

        for op in self.app.op.values():
            exec(OP_FUNC.format(', '.join(p.name for p in op.parameters)))

            op_func = functools.partial(op_func, self.client, op, self.override_url)

            op_func.__name__ = op.operationId
            op_func.__doc__ = op.description
            setattr(self, op.operationId, op_func)

It's made just for my use case (single API token), but having the function signature be based off of the docs is helpful. It also has the docstring on it based off of the description from the swagger document (I suppose I should also have it fall back to summary if description is missing).

In the example below I can just call c.post_import(some_data=data) and it returns the response. I find this a lot easier than calling the operation to get the request/response tuple, and then calling client.

In [1]: from swagger_wrapper import SwaggerWrapper
In [2]: c = SwaggerWrapper('http://swagger.dev.mysite.com/v1.yaml', 'mytoken123', 'my.local.instance:8003')

In [3]: c.post_import?
Type:            partial
String form:     <functools.partial object at 0x111d2be68>
File:            ~/.pyenv/versions/2.7.10/lib/python2.7/functools.py
Signature:       c.post_import(import_definition, property_id)
Docstring:
This is the description of the operation from the swagger doc.
Class docstring:
partial(func, *args, **keywords) - new function with partial application
of the given arguments and keywords.

pyswagger is not working with valid swagger v2 schema

Version: 0.0.2
Python 3.4.2

Steps to reproduce:

>>> from pyswagger import SwaggerApp
>>> app = SwaggerApp._create_('http://petstore.swagger.wordnik.com/v2/swagger.json')
>>> app.op
{}

Expected: list of operations

python library for creating swagger 2.0 rest api

Hi, I was trying to create a swagger 2.0 python rest api and consume the same towards client side using pyswagger. I tried django-rest-swagger but it has generated a swagger 1.2 doc. Could you help me with any python library which would help me create swagger 2.0 python rest api app towards server side.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.