API spec validator and OpenAPI document generator for Python web frameworks.

Overview

Spectree

GitHub Actions pypi versions Language grade: Python Python document

Yet another library to generate OpenAPI document and validate request & response with Python annotations.

Features

  • Less boilerplate code, only annotations, no need for YAML
  • Generate API document with Redoc UI or Swagger UI 😋
  • Validate query, JSON data, response data with pydantic 😉
  • Current support:

Quick Start

install with pip: pip install spectree

Examples

Check the examples folder.

Step by Step

  1. Define your data structure used in (query, json, headers, cookies, resp) with pydantic.BaseModel
  2. create spectree.SpecTree instance with the web framework name you are using, like api = SpecTree('flask')
  3. api.validate decorate the route with
    • query
    • json
    • headers
    • cookies
    • resp
    • tags
  4. access these data with context(query, json, headers, cookies) (of course, you can access these from the original place where the framework offered)
    • flask: request.context
    • falcon: req.context
    • starlette: request.context
  5. register to the web application api.register(app)
  6. check the document at URL location /apidoc/redoc or /apidoc/swagger

If the request doesn't pass the validation, it will return a 422 with JSON error message(ctx, loc, msg, type).

Falcon response validation

For falcon response, this library only validates against media as it is the serializable object. Response.body(deprecated in falcon 3.0 and replaced by text) is a string representing response content and will not be validated. For no assigned media situation, resp parameter in api.validate should be like Response(HTTP_200=None)

Opt-in type annotation feature

This library also supports injection of validated fields into view function arguments along with parameter annotation based type declaration. This works well with linters that can take advantage of typing features like mypy. See examples section below.

How To

How to add summary and description to endpoints?

Just add docs to the endpoint function. The 1st line is the summary, and the rest is the description for this endpoint.

How to add description to parameters?

Check the pydantic document about description in Field.

Any config I can change?

Of course. Check the config document.

You can update the config when init the spectree like:

SpecTree('flask', title='Demo API', version='v1.0', path='doc')

What is Response and how to use it?

To build a response for the endpoint, you need to declare the status code with format HTTP_{code} and corresponding data (optional).

Response(HTTP_200=None, HTTP_403=ForbidModel)
Response('HTTP_200') # equals to Response(HTTP_200=None)

What should I return when I'm using the library?

No need to change anything. Just return what the framework required.

How to logging when the validation failed?

Validation errors are logged with INFO level. Details are passed into extra. Check the falcon example for details.

How can I write a customized plugin for another backend framework?

Inherit spectree.plugins.base.BasePlugin and implement the functions you need. After that, init like api = SpecTree(backend=MyCustomizedPlugin).

How can I change the response when there is a validation error? Can I record some metrics?

This library provides before and after hooks to do these. Check the doc or the test case. You can change the handlers for SpecTree or for a specific endpoint validation.

Demo

Try it with http post :8000/api/user name=alice age=18. (if you are using httpie)

Flask

from flask import Flask, request, jsonify
from pydantic import BaseModel, Field, constr
from spectree import SpecTree, Response


class Profile(BaseModel):
    name: constr(min_length=2, max_length=40) # Constrained Str
    age: int = Field(
        ...,
        gt=0,
        lt=150,
        description='user age(Human)'
    )

    class Config:
        schema_extra = {
            # provide an example
            'example': {
                'name': 'very_important_user',
                'age': 42,
            }
        }


class Message(BaseModel):
    text: str


app = Flask(__name__)
api = SpecTree('flask')


@app.route('/api/user', methods=['POST'])
@api.validate(json=Profile, resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
def user_profile():
    """
    verify user profile (summary of this endpoint)

    user's name, user's age, ... (long description)
    """
    print(request.context.json) # or `request.json`
    return jsonify(text='it works')


if __name__ == "__main__":
    api.register(app) # if you don't register in api init step
    app.run(port=8000)

Flask example with type annotation

# opt in into annotations feature
api = SpecTree("flask", annotations=True)


@app.route('/api/user', methods=['POST'])
@api.validate(resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
def user_profile(json: Profile):
    """
    verify user profile (summary of this endpoint)

    user's name, user's age, ... (long description)
    """
    print(json) # or `request.json`
    return jsonify(text='it works')

Falcon

import falcon
from wsgiref import simple_server
from pydantic import BaseModel, Field, constr
from spectree import SpecTree, Response


class Profile(BaseModel):
    name: constr(min_length=2, max_length=40)  # Constrained Str
    age: int = Field(
        ...,
        gt=0,
        lt=150,
        description='user age(Human)'
    )


class Message(BaseModel):
    text: str


api = SpecTree('falcon')


class UserProfile:
    @api.validate(json=Profile, resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
    def on_post(self, req, resp):
        """
        verify user profile (summary of this endpoint)

        user's name, user's age, ... (long description)
        """
        print(req.context.json)  # or `req.media`
        resp.media = {'text': 'it works'}


if __name__ == "__main__":
    app = falcon.API()
    app.add_route('/api/user', UserProfile())
    api.register(app)

    httpd = simple_server.make_server('localhost', 8000, app)
    httpd.serve_forever()

Falcon with type annotations

# opt in into annotations feature
api = SpecTree("falcon", annotations=True)


class UserProfile:
    @api.validate(resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
    def on_post(self, req, resp, json: Profile):
        """
        verify user profile (summary of this endpoint)

        user's name, user's age, ... (long description)
        """
        print(req.context.json)  # or `req.media`
        resp.media = {'text': 'it works'}

Starlette

import uvicorn
from starlette.applications import Starlette
from starlette.routing import Route, Mount
from starlette.responses import JSONResponse
from pydantic import BaseModel, Field, constr
from spectree import SpecTree, Response


class Profile(BaseModel):
    name: constr(min_length=2, max_length=40)  # Constrained Str
    age: int = Field(
        ...,
        gt=0,
        lt=150,
        description='user age(Human)'
    )


class Message(BaseModel):
    text: str


api = SpecTree('starlette')


@api.validate(json=Profile, resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
async def user_profile(request):
    """
    verify user profile (summary of this endpoint)

    user's name, user's age, ... (long description)
    """
    print(request.context.json)  # or await request.json()
    return JSONResponse({'text': 'it works'})


if __name__ == "__main__":
    app = Starlette(routes=[
        Mount('api', routes=[
            Route('/user', user_profile, methods=['POST']),
        ])
    ])
    api.register(app)

    uvicorn.run(app)

Starlette example with type annotations

# opt in into annotations feature
api = SpecTree("flask", annotations=True)


@api.validate(resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
async def user_profile(request, json=Profile):
    """
    verify user profile (summary of this endpoint)

    user's name, user's age, ... (long description)
    """
    print(request.context.json)  # or await request.json()
    return JSONResponse({'text': 'it works'})

FAQ

ValidationError: missing field for headers

The HTTP headers' keys in Flask are capitalized, in Falcon are upper cases, in Starlette are lower cases. You can use pydantic.root_validators(pre=True) to change all the keys into lower cases or upper cases.

ValidationError: value is not a valid list for query

Since there is no standard for HTTP query with multiple values, it's hard to find the way to handle this for different web frameworks. So I suggest not to use list type in query until I find a suitable way to fix it.

Comments
  • [Feature]Can't support list type swagger response

    [Feature]Can't support list type swagger response

    like:

    class Item(BaseModel):
        name: str
        price: float
    
    
    @app.route("/", method=["POST"])
    @api.validate(json=Item, resp=Response(HTTP_200=List[Item]), tags=["demo"])
    def demo():
        item = Item.parse_obj(request.context.json)
        return [item, item, item]
    
    opened by sunlin92 20
  • [Bug] supporting json array in request body

    [Bug] supporting json array in request body

    When I try to send an array as a request body, I get an exception.

    def request_validation(self, request, query, json, headers, cookies):
            req_query = request.args or {}
            if request.mimetype in self.FORM_MIMETYPE:
                req_json = request.form or {}
                if request.files:
                    req_json = dict(
                        list(request.form.items()) + list(request.files.items())
                    )
            else:
                req_json = request.get_json(silent=True) or {}
            req_headers = request.headers or {}
            req_cookies = request.cookies or {}
            request.context = Context(
                query.parse_obj(req_query.items()) if query else None,
    >           json.parse_obj(req_json.items()) if json else None,
                headers.parse_obj(req_headers.items()) if headers else None,
                cookies.parse_obj(req_cookies.items()) if cookies else None,
            )
    E       AttributeError: 'list' object has no attribute 'items'
    
    bug 
    opened by dima-engineer 13
  • [Feature request] Global validation error model override

    [Feature request] Global validation error model override

    It would be really cool to not only be able to override the validation_error_status globally but also the validation error model. e.g.

    spectree.spec.SpecTree(..., validation_error_model=MyPydanticErrorModel)
    

    What do you think? I would be happy to contribute.

    BR

    opened by dfkki123508 11
  • [BUG]: PyTest fails when using @api.validate

    [BUG]: PyTest fails when using @api.validate

    Describe the bug spectree doesnt appear to handle the test/simulated response, or gets in the way some how. It returns an empty media, which then fails validation

    To Reproduce See test files below

    Expected behavior expect response to be returned and validation not to fail.

    Error Message Paste the error message.

    Desktop (please complete the following information):

    • OS: Windows 10.0.19043

    Python Information (please complete the following information):

    • Python Version [ Python=3.9.7]
    • Library Version spectree:0.6.3
    • Other dependencies falcon=3.0.0, pytest 6.2.4, pydantic 1.8.2

    Additional context Works fine when run form server, but there's something different happening with the testing setup

    bug.zip

    opened by KhanMechAI 10
  • Feedback

    Feedback

    Thank you for this library, this will be very useful for people who wants to use pydantic in their APIs.

    I had some issues when I tried the lib:

    • The JSON body is always requested in swagger/redoc in every endpoint even if it's a GET or need no body
    • The headers are working for me when I use postman, but in documentation they are shown as an object and they are not passed to endpoints.
    • Can you add option to select what documentation to expose at registration step, and if possible option to change the doc url
    • I guess you are validating the response even if there is no validation is set up : The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a int.. I think you have to keep everything optional.
    • If possible to add description to each endpoint
    opened by assem-ch 10
  • add support for form data request

    add support for form data request

    taking over where #185 was left. This is still very much WIP

    • the previous PR made form and json exclusive (ie. only one can be defined at the time), which I dont think it should be enforced. Here's a use-case where we have right now: we have /login/ endpoint, which can be called either from a legacy web which submits <form>, and it can be also used on a new frontend, which submits JSON payload. As such, one route can have both form and json.

    • previous PR is adding usage of cgi, which is about to be deprecated, so it is again removed here

    opened by yedpodtrzitko 9
  • enable view function annotation based type detection

    enable view function annotation based type detection

    The current implementation of spectree uses arguments to validate method for declaration of types for query params, request body, cookies and headers and in turn adds a context attribute to request object for all three framework implementations like following:

    # flask view implementation
    @app.route("/api/user/<name>", methods=["POST"])
    @api.validate(
        query=Query,
        json=JSON,
        cookies=Cookies,
        resp=Response(HTTP_200=Resp, HTTP_401=None),
        tags=["api", "test"],
        after=api_after_handler,
    )
    def user_score(name):
        score = [randint(0, request.context.json.limit) for _ in range(5)]
        score.sort(reverse=request.context.query.order)
        assert request.context.cookies.pub == "abcdefg"
        assert request.cookies["pub"] == "abcdefg"
        return jsonify(name=request.context.json.name, score=score)
    

    While this is good, but static linters like mypy complain about context attribute missing from flask request object. If view functions itself are annotated with their type and we additionally inject kwargs in view, linters are happy and long request.context.query.order access is now just query.order. Following is an example of annotated view function:

    # flask view implementation with annotation
    @app.route("/api/user_annotated/<name>", methods=["POST"])
    @api.validate(
        resp=Response(HTTP_200=Resp, HTTP_401=None),
        tags=["api", "test"],
        after=api_after_handler,
    )
    def user_score_annotated(
        name,
        query: Query,
        json: JSON,
        cookies: Cookies
    ):
        score = [randint(0, json.limit) for _ in range(5)]
        score.sort(reverse=query.order)
        assert cookies.pub == "abcdefg"
        assert request.cookies["pub"] == "abcdefg"
        return jsonify(name=json.name, score=score)
    

    Current implementation is an opt-in feature disabled by default. To opt-in simple instantiate SpecTree instance with an additional parameter like following:

    api = SpecTree("flask", annotations=True)
    

    This feature doesn't change anything if not opted in. Once opted it, user can have a nice API.

    I'm willing to discuss the merits, demerits of this approach. It's much closer to FaskAPI usage and since we are already using pydantic and annotations inside spectree, why stop there.

    All tests are in place.

    enhancement 
    opened by yoursvivek 9
  • Swagger Oauth redirect not working

    Swagger Oauth redirect not working

    Describe the bug I am trying to set up swagger with oauth2 flow. I set the the authorizationUrl in the SecurityScheme that I pass to the SpecTree constructor. On the swagger page that is created by spectree I can click the Authorize button, which redirects me to my identity provider's login page. If I login, I am redirected back to the swagger with some query parameters that include the JWT. However, the URL that I am redirected to does not exist in the app.

    I am new to setting up swagger, is this URL endpoint created automatically by spectree on my falcon app, or is some work needed from my end?

    Expected behavior I should end up on the swagger page again with the Authorization header prepopulated such that I can send requests to the endpoints documented in the OpenAPI specs that already include the JWT.

    Desktop (please complete the following information):

    • docker image python:3.10-slim-buster

    Python Information (please complete the following information):

    • Python Version: 3.10
    • Library Version
      • spectree=0.7.1
    • Other dependencies:
      • falcon==3.0.1
      • uvicorn==0.17.0

    Additional context Maybe I am just missing some required steps to set this up. If that is the case, would it be possible for you to add documentation around this topic?

    enhancement 
    opened by ttekampe 8
  • How to add multiple fields in security?

    How to add multiple fields in security?

    I want to add multiple fields in one auth flow in Swagger. As a result, expected TWO fields (partner-id and token for example) and ONE button "Authorize"

    opened by dmitry-engineer 7
  • init spectree with plugin instead of name, use `body` instead of `json`

    init spectree with plugin instead of name, use `body` instead of `json`

    To keep the interface clean and flexible, it's better to pass the plugin class instead of backend framework name strings. Also, the sync/async flag should be written to the plugin class as described in https://github.com/0b01001001/spectree/pull/46/files#diff-485ad20a22f45089777317b26137dc90R13-R15

    Since the body can be serialized in multiple ways, like JSON, MessagePack, ProtoBuf, etc. Although JSON should be the most common way to do so, it's better to support other methods.

    RFC 
    opened by kemingy 7
  • Falcon ASGI support

    Falcon ASGI support

    Closes #45.

    This is a work-in-progress (in particular, I have not implemented any tests), but I wanted to solicit feedback on my initial working approach. Main changes:

    • Backend plug-in specifies whether it is async or not with IS_ASYNC class constant (defaults to False on BasePlugin)
    • Added light child class for FalconPlugin that switches to coroutines for methods that must be coroutines for Falcon to work
    • Added light child classes for the view classes, since they also need to be asynchronous

    The reason I didn't write any tests was that since Falcon 3.0 is currently in pre-release, I was leery of testing against it. I'm honestly not too sure how to handle this; maybe this PR doesn't really make sense to merge in until Falcon 3.0 is released. ¯_(ツ)_/¯

    Thoughts?

    opened by onecrayon 7
  • [Question] Is it possible to specify a BaseModel class as a Redoc Model?

    [Question] Is it possible to specify a BaseModel class as a Redoc Model?

    In the Redoc Interactive Demo, specific data models can be categorized under the "MODELS" tag. Does spectree provide a method to pull in / mark a BaseModel class as a model for redoc to illustrate?

    See The Pet Model as an example.

    image

    opened by jsmoliak 1
  • [BUG] SecurityScheme(name=

    [BUG] SecurityScheme(name="auth_apiKey)

    I dont know this is bug of spec_tree or openapi.

    I use SecurityScheme like here https://github.com/0b01001001/spectree/blob/master/tests/common.py#L84. But when i use this scheme and I register the token in the documentation (/apidoc/swagger). The token is not in the headers. I dont see it anywhere

    Code example

    from collections import OrderedDict
    
    from flask import Flask
    from flask_cors import CORS
    from pydantic import EmailStr
    from spectree import SpecTree
    from spectree.config import Contact
    from spectree.models import (
        Server,
        SecurityScheme,
        SecuritySchemeData,
        SecureType,
    )
    
    from ..config import cfg
    from ..database import db, migrate
    
    
    spec_tree = SpecTree(
        "flask",
        mode="strict",
        title="Docs AuthService API",
        version=cfg.API_VERSION,
        annotations=True,
        contact=Contact(
            name="Бекишев Матвей",
            email=EmailStr("[email protected]"),
        ),
        servers=[
            Server(
                url="http://127.0.0.1:5555/",
                description="Local Server",
            ),
        ],
        security_schemes=[
            SecurityScheme(
                # todo баг библиотеки
                name="auth_apiKey",
                data={"type": "apiKey", "name": "Authorization", "in": "header"},
            ),
            # SecurityScheme(
            #     name="ApiKey",
            #     data=SecuritySchemeData(
            #         type=SecureType.HTTP,
            #         description="Access Token in AuthService API",
            #         scheme="bearer",
            #         bearerFormat="UUID",
            #     ),
            # ),
        ],
        security=dict(
            ApiKey=[],
        ),
    )
    
    opened by bekishev04 3
  • [Question] Is it possible to load the Swagger UI offline?

    [Question] Is it possible to load the Swagger UI offline?

    The service I'm making runs on the localhost with not necessarily access to Internet. When I open the Swagger endpoint in the browser I can see the next messages in the console:

    Loading failed for the <script> with source “https://cdn.jsdelivr.net/npm/[email protected]/swagger-ui-bundle.js”. swagger:36:1
    Loading failed for the <script> with source “https://cdn.jsdelivr.net/npm/s[email protected]/swagger-ui-standalone-preset.js”. swagger:37:1
    

    So I want to know... How to load the Swagger interface offline?

    enhancement 
    opened by Joseda8 4
  • [QUESTION] Why are description strings joined with double newlines?

    [QUESTION] Why are description strings joined with double newlines?

    For me it causes problems when trying to render markdown, e.g.

    @validate()
    def fun():
        """summary
    
        | One | Two | Three |
        |-----|-----|-------|
        | a   | b   | c     |
    
        | One | Two | Three |
    
        |-----|-----|-------|
    
        | a   | b   | c     |
    
        """
    

    results in the spec as:

    "description": "| One | Two | Three | |-----|-----|-------| | a | b | c |\n\n| One | Two | Three |\n\n|-----|-----|-------|\n\n| a | b | c |"

    I did not find a possiblity to render single newlines. Can you help me? PS: I am referring to this line: https://github.com/0b01001001/spectree/blob/f04c9b79927cf4bc39eaf3ae2694297e611af2ef/spectree/utils.py#L46 Thanks!

    enhancement 
    opened by dfkki123508 3
  • improve falcon form data read part

    improve falcon form data read part

    @yedpodtrzitko It depends what you are trying to achieve. Do you want to buffer whole files in memory? Or do you want to spool them to temp files like some other frameworks do?

    Falcon even puts a cap on a maximum amount of data that can be referenced this way (await part.get_data()) in order to avoid surprises such as running out of memory.

    Use await part.stream.read() to read the whole part as a bytestring, or await part.stream.pipe(async_file), or read by chunks, and store the result somewhere. You'll probably need to introduce some new object type to hold these attributes.

    Originally posted by @vytas7 in https://github.com/0b01001001/spectree/pull/225#discussion_r936042043

    enhancement good first issue help wanted 
    opened by kemingy 4
Releases(v1.0.3)
  • v1.0.3(Nov 29, 2022)

    What's Changed

    • Allow endpoints to override its operationId by @gwaramadze in https://github.com/0b01001001/spectree/pull/281

    New Contributors

    • @gwaramadze made their first contribution in https://github.com/0b01001001/spectree/pull/281

    Full Changelog: https://github.com/0b01001001/spectree/compare/v1.0.2...v1.0.3

    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Nov 19, 2022)

    What's Changed

    • feat: support customize 422 validation error type by @dfkki123508 in https://github.com/0b01001001/spectree/pull/260
    • test: fix starlette cookie in test client by @kemingy in https://github.com/0b01001001/spectree/pull/277
    • chore: change to pyproject, drop py3.6, add py3.11 test by @kemingy in https://github.com/0b01001001/spectree/pull/265

    New Contributors

    • @dfkki123508 made their first contribution in https://github.com/0b01001001/spectree/pull/260

    Full Changelog: https://github.com/0b01001001/spectree/compare/v1.0.1...v1.0.2

    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Nov 9, 2022)

  • v1.0.0(Nov 9, 2022)

    Breaking Changes

    • drop support for Falcon 2 by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/239
    • add support for form data request by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/225
    • Dmitry/quart plugin by @dima-engineer in https://github.com/0b01001001/spectree/pull/262
    • fix: only call after at the end of the validation by @kemingy in https://github.com/0b01001001/spectree/pull/274

    What's Changed

    • fix: use mypy.ignore_missing_imports instead of suppressing them everywhere manually by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/238
    • hotfix: add bound for werkzeug dependency due to breaking change by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/241
    • add copy of werkzeug.parse_rule which is now marked as internal by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/244
    • prerelease of 1.0.0a0 by @kemingy in https://github.com/0b01001001/spectree/pull/245
    • chore(pip): update flake8 requirement from ~=4.0 to >=4,<6 by @dependabot in https://github.com/0b01001001/spectree/pull/252
    • Use typing.get_type_hints instead of .annotations by @kageurufu in https://github.com/0b01001001/spectree/pull/250
    • fix rest annotations in test by @kemingy in https://github.com/0b01001001/spectree/pull/253
    • fix: root properties by @kemingy in https://github.com/0b01001001/spectree/pull/255
    • chore: move mypy config to setup.cfg by @kemingy in https://github.com/0b01001001/spectree/pull/256
    • Fix: Replace slash from generated operationId by @harish2704 in https://github.com/0b01001001/spectree/pull/264
    • feat: import plugin using import_module by @kemingy in https://github.com/0b01001001/spectree/pull/266
    • chore: update ci by @kemingy in https://github.com/0b01001001/spectree/pull/267
    • chore: add quart demo to readme by @kemingy in https://github.com/0b01001001/spectree/pull/268
    • AND/OR root security configuration by @kageurufu in https://github.com/0b01001001/spectree/pull/269
    • Add CodeQL workflow for GitHub code scanning by @lgtm-com in https://github.com/0b01001001/spectree/pull/272

    New Contributors

    • @harish2704 made their first contribution in https://github.com/0b01001001/spectree/pull/264
    • @dima-engineer made their first contribution in https://github.com/0b01001001/spectree/pull/262
    • @lgtm-com made their first contribution in https://github.com/0b01001001/spectree/pull/272

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.3...v1.0.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0a4(Nov 9, 2022)

    What's Changed

    • AND/OR root security configuration by @kageurufu in https://github.com/0b01001001/spectree/pull/269
    • Add CodeQL workflow for GitHub code scanning by @lgtm-com in https://github.com/0b01001001/spectree/pull/272
    • fix: only call after at the end of the validation by @kemingy in https://github.com/0b01001001/spectree/pull/274

    New Contributors

    • @lgtm-com made their first contribution in https://github.com/0b01001001/spectree/pull/272

    Full Changelog: https://github.com/0b01001001/spectree/compare/v1.0.0a3...v1.0.0a4

    Source code(tar.gz)
    Source code(zip)
  • v0.12.1(Nov 9, 2022)

    Breaking changes

    • fix: only call after at the end of the validation #274 by @kemingy

    Chore

    • AND/OR root security configuration #269 by @kageurufu

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.12.0...v0.12.1

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0a3(Oct 18, 2022)

    What's Changed

    • Dmitry/quart plugin by @dima-engineer in https://github.com/0b01001001/spectree/pull/262
    • chore: add quart demo to readme by @kemingy in https://github.com/0b01001001/spectree/pull/268

    New Contributors

    • @dima-engineer made their first contribution in https://github.com/0b01001001/spectree/pull/262

    Full Changelog: https://github.com/0b01001001/spectree/compare/v1.0.0a2...v1.0.0a3

    Source code(tar.gz)
    Source code(zip)
  • v0.12.0(Oct 18, 2022)

    • cherry picked from commit 54a2b1d296ff9d319863a7a40a42c63ec7cef4cc (support Quart) by @dmitry-engineer

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.11.0...v0.12.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0a2(Oct 15, 2022)

    What's Changed

    • chore: move mypy config to setup.cfg by @kemingy in https://github.com/0b01001001/spectree/pull/256
    • Fix: Replace slash from generated operationId by @harish2704 in https://github.com/0b01001001/spectree/pull/264
    • feat: import plugin using import_module by @kemingy in https://github.com/0b01001001/spectree/pull/266
    • chore: update ci by @kemingy in https://github.com/0b01001001/spectree/pull/267

    New Contributors

    • @harish2704 made their first contribution in https://github.com/0b01001001/spectree/pull/264

    Full Changelog: https://github.com/0b01001001/spectree/compare/v1.0.0a1...v1.0.0a2

    Source code(tar.gz)
    Source code(zip)
  • v0.11.0(Oct 15, 2022)

    • cherry picked from commit b96a490bd6a2a43e76f34e1b4fe9cecbc0ac5c88 by @harish2704
    • cherry picked from commit ebcb3d664374d82e6facaea60ad625f9f9e2c47f by @kemingy

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.6...v0.11.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0a1(Aug 24, 2022)

    What's Changed

    • add support for form data request by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/225
    • chore(pip): update flake8 requirement from ~=4.0 to >=4,<6 by @dependabot in https://github.com/0b01001001/spectree/pull/252
    • Use typing.get_type_hints instead of .annotations by @kageurufu in https://github.com/0b01001001/spectree/pull/250
    • fix rest annotations in test by @kemingy in https://github.com/0b01001001/spectree/pull/253
    • fix: root properties by @kemingy in https://github.com/0b01001001/spectree/pull/255

    Full Changelog: https://github.com/0b01001001/spectree/compare/v1.0.0a0...v1.0.0a1

    Source code(tar.gz)
    Source code(zip)
  • v0.10.6(Aug 24, 2022)

    • fix: __root__ properties in https://github.com/0b01001001/spectree/pull/255 by @kemingy

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.5...v0.10.6

    Source code(tar.gz)
    Source code(zip)
  • v0.10.5(Aug 7, 2022)

    What's Changed

    • Use typing.get_type_hints instead of .__annotations__ by @kageurufu in https://github.com/0b01001001/spectree/pull/251

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.4...v0.10.5

    Source code(tar.gz)
    Source code(zip)
  • v0.10.4(Aug 3, 2022)

    What's Changed

    • fix: use mypy.ignore_missing_imports instead of suppressing them everywhere manually by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/238
    • hotfix: add bound for werkzeug dependency due to breaking change by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/241
    • fix: werkzeug by @yedpodtrzitko #244

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.3...v0.10.4

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0a0(Aug 1, 2022)

    What's Changed

    • fix: use mypy.ignore_missing_imports instead of suppressing them everywhere manually by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/238
    • hotfix: add bound for werkzeug dependency due to breaking change by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/241
    • drop support for Falcon 2 by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/239
    • add copy of werkzeug.parse_rule which is now marked as internal by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/244
    • prerelease of 1.0.0a0 by @kemingy in https://github.com/0b01001001/spectree/pull/245

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.3...v1.0.0a0

    Source code(tar.gz)
    Source code(zip)
  • v0.10.3(Jul 14, 2022)

    What's Changed

    • Make email-validator an optional dependency by @MarkKoz in https://github.com/0b01001001/spectree/pull/236

    New Contributors

    • @MarkKoz made their first contribution in https://github.com/0b01001001/spectree/pull/236

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.2...v0.10.3

    Source code(tar.gz)
    Source code(zip)
  • v0.10.2(Jul 7, 2022)

    What's Changed

    • Create dependabot.yml by @kemingy in https://github.com/0b01001001/spectree/pull/230
    • chore(actions): bump actions/setup-python from 2 to 4 by @dependabot in https://github.com/0b01001001/spectree/pull/231
    • fix: log the validation error in the default handler by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/233
    • misc: upgrade Swagger UI to v4 by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/234

    New Contributors

    • @dependabot made their first contribution in https://github.com/0b01001001/spectree/pull/231

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.1...v0.10.2

    Source code(tar.gz)
    Source code(zip)
  • v0.10.1(Jun 13, 2022)

    What's Changed

    • use 'furo' as the new doc theme by @kemingy in https://github.com/0b01001001/spectree/pull/223
    • Flask: add trailing slash to apidoc routes by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/224
    • fix: dont validate JSON data in request which cant provide it by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/228
    • refactoring: define flask tests in single place and reuse them by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/227

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.10.0...v0.10.1

    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(May 4, 2022)

    What's Changed

    • support list resp with List[Model] by @kemingy in https://github.com/0b01001001/spectree/pull/222

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.9.2...v0.10.0

    Source code(tar.gz)
    Source code(zip)
  • v0.10.0a1(May 1, 2022)

    What's Changed

    • support list resp with List[Model] by @kemingy in https://github.com/0b01001001/spectree/pull/222

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.9.2...v0.10.0a1

    Source code(tar.gz)
    Source code(zip)
  • v0.9.2(Apr 26, 2022)

    What's Changed

    • update readme: add pydantic instance response by @kemingy in https://github.com/0b01001001/spectree/pull/218
    • fix falcon plugin by @ttekampe in https://github.com/0b01001001/spectree/pull/220
    • Fix falcon async test by @kemingy in https://github.com/0b01001001/spectree/pull/221

    New Contributors

    • @ttekampe made their first contribution in https://github.com/0b01001001/spectree/pull/220

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.9.1...v0.9.2

    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(Apr 24, 2022)

    What's Changed

    • fix: handle case when no view response is defined by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/216

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.9.0...v0.9.1

    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Apr 24, 2022)

    What's Changed

    • Support skipping validation and returning models by @danstewart in https://github.com/0b01001001/spectree/pull/212
    • misc: use hash suffix instead of prefix in get_model_key by @yedpodtrzitko in https://github.com/0b01001001/spectree/pull/214
    • Release 0.9.0 by @kemingy in https://github.com/0b01001001/spectree/pull/215

    New Contributors

    • @danstewart made their first contribution in https://github.com/0b01001001/spectree/pull/212
    • @yedpodtrzitko made their first contribution in https://github.com/0b01001001/spectree/pull/214

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.8.0...v0.9.0

    Source code(tar.gz)
    Source code(zip)
  • v0.8.0(Apr 17, 2022)

    What's Changed

    • change to [email protected] by @kemingy in https://github.com/0b01001001/spectree/pull/209
    • add type hint by @kemingy in https://github.com/0b01001001/spectree/pull/210
    • release 0.8.0 by @kemingy in https://github.com/0b01001001/spectree/pull/211

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.7.6...v0.8.0

    Source code(tar.gz)
    Source code(zip)
  • v0.7.6(Feb 22, 2022)

    What's Changed

    • Add description argument to Response.add_model() by @DataGhost in https://github.com/0b01001001/spectree/pull/206
    • add more doc for Response by @kemingy in https://github.com/0b01001001/spectree/pull/207

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.7.5...v0.7.6

    Source code(tar.gz)
    Source code(zip)
  • v0.7.5(Feb 21, 2022)

    What's Changed

    • fix flask ImmutableMultiDict and EnvironHeaders parser by @kemingy in https://github.com/0b01001001/spectree/pull/205
    • fix #204 JSON array in Flask

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.7.4...v0.7.5

    Source code(tar.gz)
    Source code(zip)
  • v0.7.4(Feb 17, 2022)

    What's Changed

    • Refact build by @kemingy in https://github.com/0b01001001/spectree/pull/201
    • fix req + args parse in starlette by @kemingy in https://github.com/0b01001001/spectree/pull/203 (fix #202)

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.7.3...v0.7.4

    Source code(tar.gz)
    Source code(zip)
  • v0.7.3(Feb 10, 2022)

    What's Changed

    • add flask blueprint spec path test by @kemingy in https://github.com/0b01001001/spectree/pull/197
    • Restored docstring paragraph formatting by @DataGhost in https://github.com/0b01001001/spectree/pull/199
    • Upgrade dev version by @kemingy in https://github.com/0b01001001/spectree/pull/200

    New Contributors

    • @DataGhost made their first contribution in https://github.com/0b01001001/spectree/pull/199

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.7.2...v0.7.3

    Source code(tar.gz)
    Source code(zip)
  • v0.7.2(Jan 26, 2022)

    What's Changed

    • Fix blueprint find_routes method by @guilhermelou in https://github.com/0b01001001/spectree/pull/193
    • Fix swagger oauth2 redirect by @kemingy in https://github.com/0b01001001/spectree/pull/196

    New Contributors

    • @guilhermelou made their first contribution in https://github.com/0b01001001/spectree/pull/193

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.7.1...v0.7.2

    Source code(tar.gz)
    Source code(zip)
  • v0.7.1(Jan 8, 2022)

    What's Changed

    • Fix terms of service case by @kemingy in https://github.com/0b01001001/spectree/pull/192

    Full Changelog: https://github.com/0b01001001/spectree/compare/v0.7.0...v0.7.1

    Source code(tar.gz)
    Source code(zip)
Owner
1001001
73 is the sole Sheldon prime
1001001
A set of Python libraries that assist in calling the SoftLayer API.

SoftLayer API Python Client This library provides a simple Python client to interact with SoftLayer's XML-RPC API. A command-line interface is also in

SoftLayer 155 Sep 20, 2022
Your Project with Great Documentation.

Read Latest Documentation - Browse GitHub Code Repository The only thing worse than documentation never written, is documentation written but never di

Timothy Edmund Crosley 809 Dec 28, 2022
Literate-style documentation generator.

888888b. 888 Y88b 888 888 888 d88P 888 888 .d8888b .d8888b .d88b. 8888888P" 888 888 d88P" d88P" d88""88b 888 888 888

Pycco 808 Dec 27, 2022
The source code that powers readthedocs.org

Welcome to Read the Docs Purpose Read the Docs hosts documentation for the open source community. It supports Sphinx docs written with reStructuredTex

Read the Docs 7.4k Dec 25, 2022
Course Materials for Math 340

UBC Math 340 Materials This repository aims to be the one repository for which you can find everything you about Math 340. Lecture Notes Lecture Notes

2 Nov 25, 2021
A system for Python that generates static type annotations by collecting runtime types

MonkeyType MonkeyType collects runtime types of function arguments and return values, and can automatically generate stub files or even add draft type

Instagram 4.1k Jan 07, 2023
API spec validator and OpenAPI document generator for Python web frameworks.

API spec validator and OpenAPI document generator for Python web frameworks.

1001001 249 Dec 22, 2022
YAML metadata extension for Python-Markdown

YAML metadata extension for Python-Markdown This extension adds YAML meta data handling to markdown with all YAML features. As in the original, metada

Nikita Sivakov 14 Dec 30, 2022
💯 Coolest snippets

nvim-snippets This was originally included in my personal Neovim setup, but I didn't like having all the snippets there so I decided to have them sepa

Eliaz Bobadilla 6 Aug 31, 2022
Reproducible Data Science at Scale!

Pachyderm: The Data Foundation for Machine Learning Pachyderm provides the data layer that allows machine learning teams to productionize and scale th

Pachyderm 5.7k Dec 29, 2022
A complete kickstart devcontainer repository for python3

A complete kickstart devcontainer repository for python3

Viktor Freiman 3 Dec 23, 2022
A tool that allows for versioning sites built with mkdocs

mkdocs-versioning mkdocs-versioning is a plugin for mkdocs, a tool designed to create static websites usually for generating project documentation. mk

Zayd Patel 38 Feb 26, 2022
A website for courses of Major Computer Science, NKU

A website for courses of Major Computer Science, NKU

Sakura 0 Oct 06, 2022
Project created to help beginner programmers to study, despite the lack of internet!

Project created to help beginner programmers to study, despite the lack of internet!

Dev4Dev 2 Oct 25, 2021
Automated generation of real Swagger/OpenAPI 2.0 schemas from Django REST Framework code.

drf-yasg - Yet another Swagger generator Generate real Swagger/OpenAPI 2.0 specifications from a Django Rest Framework API. Compatible with Django Res

Cristi Vîjdea 3k Dec 31, 2022
Template repo to quickly make a tested and documented GitHub action in Python with Poetry

Python + Poetry GitHub Action Template Getting started from the template Rename the src/action_python_poetry package. Globally replace instances of ac

Kevin Duff 89 Dec 25, 2022
A Python library for setting up projects using tabular data.

A Python library for setting up projects using tabular data. It can create project folders, standardize delimiters, and convert files to CSV from either individual files or a directory.

0 Dec 13, 2022
Always know what to expect from your data.

Great Expectations Always know what to expect from your data. Introduction Great Expectations helps data teams eliminate pipeline debt, through data t

Great Expectations 7.8k Jan 05, 2023
Leetcode Practice

LeetCode Practice Description This is my LeetCode Practice. Visit LeetCode Website for detailed question description. The code in this repository has

Leo Hsieh 75 Dec 27, 2022
Fully typesafe, Rust-like Result and Option types for Python

safetywrap Fully typesafe, Rust-inspired wrapper types for Python values Summary This library provides two main wrappers: Result and Option. These typ

Matthew Planchard 32 Dec 25, 2022