pyswagger

repository·develop·Indexed 18 days ago

https://github.com/pyopenapi/pyswagger

A Python client for Swagger-enabled REST APIs designed as a user-friendly, type-safe alternative to Swagger-codegen. It supports various Swagger versions, providing tools to load API definitions via App, manage authorization with Security objects, and execute requests using SwaggerClient. Key features include operation access via operationId or JSON-Pointer, support for multipart/form-data file uploads, and the ability to load OpenAPI specifications from memory using Resolver and DictGetter.

Tokens
13.9K
Snippets
46
Records
59
Agent score
63%

What's inside pyswagger

  1. Conversion limitations from Swagger 1.2 to 2.0

    develop

    When converting from Swagger 1.2 to 2.0, be aware of the following structural changes and limitations:

    Parameter Mapping: allowMultiple to collectionFormat

    In Swagger 1.2, arrays were often defined using allowMultiple: true. In Swagger 2.0, this is replaced by the collectionFormat property. For example, a string with multiple allowed values will be converted to use collectionFormat: "csv" and an items object.

    Example Conversion:

    Input (1.2):

    {
        "allowMultiple":true,
        "type":"string",
        "enum":[
            "available",
            "pending",
            "sold"
        ]
    }

    Output (2.0):

    {
        "collectionFormat":"csv",
        "items":{
            "type":"string",
            "enum":["available", "pending", "sold"]
        }
    }

    basePath Restrictions

    Swagger 1.2 allows multiple basePath definitions. However, Swagger 2.0 only allows a single basePath. If your resource files define different basePath values, pyswagger will raise an Exception and refuse to proceed with the conversion.

  2. Access Operations via operationId and JSON-Pointer

    develop

    There are two primary ways to retrieve an Operation object from an App instance:

    1. Via operationId: If the Swagger definition defines an operationId, you can access it directly through the App.op dictionary. Example: app.op['getPetById'](param=value)

    2. Via JSON-Pointer: If you need to resolve an operation based on its path and method, use app.resolve() combined with jp_compose from pyswagger.utils. Example: app.resolve(jp_compose('/path/{param}', base='#/paths')).get(param=value)

  3. Use pyswagger primitives for data modeling

    develop

    The pyswagger.primitives module provides core data types used to represent Swagger/OpenAPI schema types within Python. These primitives allow you to define and validate data structures that correspond to Swagger definitions like Byte, Date, Datetime, Array, and Model.

    Available primitive classes include:

    • Byte: Represents byte data.
    • Date: Represents a date.
    • Datetime: Represents a date and time.
    • Array: Represents a collection of items.
    • Model: Represents a complex object or schema model.

    You can use is_primitive(obj) to check if a given object is a recognized pyswagger primitive, and prim_factory(type_name) to instantiate primitives dynamically based on their type name.

  4. Core components of pyswagger

    develop

    The library is built around three primary components:

    • App: Holds the Swagger API definition and manages operations.
    • Security: Manages authorization credentials and applies them to requests.
    • Client: An abstraction layer for executing HTTP requests (e.g., TornadoClient or requests-based clients).
  5. Handle multi-pass primitive creation with ctx

    develop

    When creating certain primitives (such as Model or Array) requires multiple passes over the specification, you should use the ctx (parsing context) argument provided to the primitive handler. The ctx object allows you to persist global state or data between these passes.

    Note: pyswagger currently uses a _2nd_pass mechanism internally for Model and Array creation to facilitate this.

  6. Initialize a pyswagger App instance

    develop

    To start using pyswagger, initialize an App instance using the App._create_(url) method. The url parameter can be either a remote URL or a local file path to a Swagger definition. The resulting App instance is used to manage security and access API operations.

    app = App._create_('path/to/swagger.json')
  7. Handle multiple external documents with DictGetter

    develop

    When dealing with multi-document specifications (such as Swagger 1.2 or Swagger 2.0 with $ref pointing to external files), you can use DictGetter by providing all resource paths and their corresponding loaded objects.

    Important: You must pass all URLs/paths to be resolved in the correct order as the first parameter (a list) to DictGetter. The dictionary mapping must then match these paths to the loaded objects.

    Note: This process is manual and requires careful ordering of the path list.

    from pyswagger import App
    from pyswagger.resolve import Resolver
    from pyswagger.getter import DictGetter
    
    # Example: multiple loaded objects in memory
    loaded_resource_list = { ... }
    pet = { ... }
    user = { ... }
    store = { ... }
    
    # The order in the list must match the keys in the dictionary
    getter = DictGetter([
        '',
        'pet.json',
        'user.json',
        'store.json',
    ], {
        '': loaded_resource_list,
        'pet.json': pet,
        'user.json': user,
        'store.json': store
    })
    
    app = App.load('', resolver=Resolver(default_getter=getter))
    app.prepare()
  8. Initialize a pyswagger App object

    develop

    To start using pyswagger, you must create a pyswagger.App object by providing the path to a Swagger resource file. You can use the App.create() method to initialize the application with a URL or a local file path.

    from pyswagger import App
    
    # Initialize using a remote URL
    app = App.create('http://petstore.swagger.io/v2/swagger.json')
  9. Migrating from Swagger 1.2 to 2.0

    develop

    When upgrading from Swagger 1.2 to 2.0, be aware of the following breaking changes in how pyswagger and the Swagger spec behave:

    • allowMultiple: This is no longer supported; you must always pass an array, even if it contains only a single value.
    • Host/BasePath: Swagger 2.0 does not support different hosts for different resources. Only one host and one basePath are allowed per swagger.json.
    • Body Parameters: The name of body parameters is no longer included in requests.

    For more detailed information, refer to the official Swagger Migration Guide.

  10. Access an Operation object

    develop

    You can retrieve an Operation object from an App instance using several methods depending on how your Swagger file is structured:

    1. Via operationId or tag + operationId

    If operationId is unique, you can access it directly via the app.op dictionary. If you need to disambiguate using a tag, provide a tuple of (tag, operationId).

    2. Via JSON Pointer

    Every object in a Swagger file can be referenced using a JSON Pointer. Use pyswagger.utils.jp_compose to build the pointer and app.resolve() to retrieve the object.

    3. Via Cascade Resolving

    You can resolve a path first (e.g., a specific resource) and then resolve the specific HTTP method (e.g., get, post) from that resource object. You can access methods as properties if they do not contain special characters.

    from pyswagger import App, utils
    
    app = App.create('http://petstore.swagger.io/v2/swagger.json')
    
    # Using operationId
    op = app.op['getUserByName']
    
    # Using tag + operationId
    op = app.op['user', 'getUserByName']
    
    # Using JSON Pointer
    op = app.resolve(utils.jp_compose(['#', 'paths', '/user/{username}', 'get']))
    
    # Cascade resolving
    username_api = app.resolve(utils.jp_compose(['#', 'paths', '/user/{username}']))
    op = username_api.resolve('get') # Method 1
    op = username_api.get            # Method 2 (property access)
  11. Load a Swagger resource into an App object

    develop

    Use the App._create_(url) method to load a Swagger specification from a remote URL. This creates an App instance that contains the mapping of all operations defined in the spec.

    app = App._create_('http://petstore.swagger.wordnik.com/api/api-docs')