Easily document your Sanic API with Swagger UI, Plus param validation and model serialization.
Switch branches/tags
Nothing to show
Clone or download
Latest commit 5040819 Nov 21, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
docs update index.rst Nov 8, 2018
examples add code-to-ui in README.rst Nov 21, 2018
sanic_transmute release 0.1.3 Nov 21, 2018
tests fix test_swagger.py Oct 6, 2018
.gitignore unit tests Jun 5, 2017
.travis.yml Initial Commit May 30, 2017
LICENSE Initial commit May 30, 2017
README.rst update typo png uri Nov 21, 2018
conda.yml for readthedocs Jun 6, 2017
readthedocs.yml for readthedocs Jun 6, 2017
setup.py release 0.1.3 Nov 21, 2018
ubuild.py release 0.1.3 Nov 21, 2018
uranium implementing May 31, 2017

README.rst

sanic-transmute

Build
Travis-CI Build Status coverage status
Docs Documentation Status
Package

Easily document your Sanic API with Swagger UI, Plus param validation and model serialization.

You can find out more here:

http://sanic-transmute.readthedocs.io/en/latest/

What is sanic-transmute ?

A transmute framework for sanic. This framework provides:

  • declarative generation of http handler interfaces by parsing function annotations
  • validation and serialization to and from a variety of content types (e.g. json or yaml).
  • validation and serialization to and from native python objects, using attrs and schematics.
  • autodocumentation of all handlers generated this way, via swagger.

Quick Start

Overview:

code-to-ui.png

Find Examples here:

Simple example with schematics model.

from sanic import Sanic, Blueprint
from sanic.response import json
from sanic_transmute import describe, add_route, add_swagger, APIException
from sanic.exceptions import ServerError
from schematics.models import Model
from schematics.types import IntType


class User(Model):
    points = IntType()


app = Sanic()
bp = Blueprint("test_blueprints", url_prefix="/blueprint")


@describe(paths="/api/v1/user/{user}/", methods="GET")
async def test_transmute(request, user: str, env: str=None, group: [str]=None):
    """
    API Description: Transmute Get. This will show in the swagger page (localhost:8000/api/v1/).
    """
    return {
        "user": user,
        "env": env,
        "group": group,
    }


@describe(paths="/killme")
async def handle_exception(request) -> User:
    """
    API Description: Handle exception. This will show in the swagger page (localhost:8000/api/v1/).
    """
    raise ServerError("Something bad happened", status_code=500)


@describe(paths="/api/v1/user/missing")
async def handle_api_exception(request) -> User:
    """
    API Description: Handle APIException. This will show in the swagger page (localhost:8000/api/v1/).
    """
    raise APIException("Something bad happened", code=404)


@describe(paths="/multiply")
async def get_blueprint_params(request, left: int, right: int) -> str:
    """
    API Description: Multiply, left * right. This will show in the swagger page (localhost:8000/api/v1/).
    """
    res = left * right
    return "{left}*{right}={res}".format(left=left, right=right, res=res)


if __name__ == "__main__":
    add_route(app, test_transmute)
    add_route(app, handle_exception)
    add_route(app, handle_api_exception)
    # register blueprints
    add_route(bp, get_blueprint_params)
    app.blueprint(bp)
    # add swagger
    add_swagger(app, "/api/v1/swagger.json", "/api/v1/")
    app.run(host="0.0.0.0", port=8000)

Simple example with attrs model.

from sanic import Sanic, Blueprint
from sanic.response import json
from sanic_transmute import describe, add_route, add_swagger, APIException
from sanic.exceptions import ServerError
import attr


@attr.s
class User:
    points = attr.ib(type=int)


app = Sanic()
bp = Blueprint("test_blueprints", url_prefix="/blueprint")


@describe(paths="/api/v1/user/{user}/", methods="GET")
async def test_transmute_get(request, user: str, env: str=None, group: [str]=None):
    """
    API Description: Transmute Get. This will show in the swagger page (localhost:8000/api/v1/).
    """
    return {
        "user": user,
        "env": env,
        "group": group,
    }


@describe(paths="/api/v1/user/", methods="POST")
async def test_transmute_post(request, user: User) -> User:
    """
    API Description: Transmute Post. This will show in the swagger page (localhost:8000/api/v1/).
    """
    return user


@describe(paths="/killme")
async def handle_exception(request) -> User:
    """
    API Description: Handle exception. This will show in the swagger page (localhost:8000/api/v1/).
    """
    raise ServerError("Something bad happened", status_code=500)


@describe(paths="/api/v1/user/missing")
async def handle_api_exception(request) -> User:
    """
    API Description: Handle APIException. This will show in the swagger page (localhost:8000/api/v1/).
    """
    raise APIException("Something bad happened", code=404)


@describe(paths="/multiply")
async def get_blueprint_params(request, left: int, right: int) -> str:
    """
    API Description: Multiply, left * right. This will show in the swagger page (localhost:8000/api/v1/).
    """
    res = left * right
    return "{left}*{right}={res}".format(left=left, right=right, res=res)


if __name__ == "__main__":
    add_route(app, test_transmute_get)
    add_route(app, test_transmute_post)
    add_route(app, handle_exception)
    add_route(app, handle_api_exception)
    # register blueprints
    add_route(bp, get_blueprint_params)
    app.blueprint(bp)
    # add swagger
    add_swagger(app, "/api/v1/swagger.json", "/api/v1/")
    app.run(host="0.0.0.0", port=8000)

Development

Build.

./uranium

Run unit tests.

./uranium test