Kobin Documentation

Type Hints friendly WSGI Framework for Python3.

Kobin has following features.

  • Decorator based Routing System exploited Type Hints.
  • WSGI request and response Wrapper.
  • Provide type annotations from stub files.
  • and other convenient utilities…

And Kobin has NO following features:

  • WSGI Server Adapters: Please use WSGICLI or Gunicorn CLI.
  • Serving static contents: Please use WSGICLI and Nginx.
  • Template Engine: But Kobin provides template adapter.

Statuses

https://travis-ci.org/kobinpy/kobin.svg?branch=master https://badge.fury.io/py/kobin.svg https://coveralls.io/repos/github/kobinpy/kobin/badge.svg?branch=coveralls Code Climate Documentation Status

Kobin documentation contents

Tutorial

Installation

In this tutorial, we will use Python 3.6.

$ python --version
Python 3.6.0b4
$ pip install -U pip
$ pip install kobin wsgicli
  • Kobin: WSGI Framework
  • WSGICLI: Command line tools for developing your WSGI Application

Your first kobin app

Let’s make Kobin’s application. Please create a main.py:

from kobin import Kobin, Response, JSONResponse
app = Kobin()

@app.route('/')
def index() -> Response:
    return Response("Hello World!")

@app.route('/users/{user_id}')
def say_hello(user_id: int) -> JSONResponse:
    return JSONResponse({
        "message": f"Hello user{user_id}!"
    })

For those who have used the WSGI framework such as Bottle and Flask, it may be familiar with this code. One distinctive feature is the existence of type hints. Kobin casts the URL variable based on the type hinting and passes it to the View function.

Let’s actually move it. There are several ways to run WSGI’s application. In the development environment we recommend a command line tool called wsgicli.

$ wsgicli run main.py app
Start: 127.0.0.1:8000

When the server starts up successfully, let’s access following urls.

Did you see any message? Congratulations!

Deploy to production

In a production, let’s use gunicorn instead of using wsgicli for a performance reasons.

$ pip install gunicorn
$ gunicorn main:app

Then please try accessing your website. If you use the function of static file serving in wsgicli, maybe the layout and styles have gone wrong. Actually, gunicorn doesn’t have the function of serving static content such as CSS, JS, and image files. Generally, the reverse proxy server such as Nginx is used for serving static content in production (See Serving Static Content - Nginx .

If you absolutely need to serve static contents in Python’s application side (ex: Using Heroku), Please use kobinpy/wsgi-static-middleware .

Next Step

More practical example is kobin-example . If you want to know the best practices in Kobin, Please check it.

Kobin Example Demo Animation

API Documentation

This documentations is generated from kobin’s source code.

Kobin class

The Kobin instance are callable WSGI Application.

Usage
from kobin import Kobin, Response
app = Kobin()

@app.route('/')
def index() -> Response:
    return Response('Hello World')
class kobin.app.Kobin(config=None)[source]

This class is a WSGI application implementation. Create a instance, and run using WSGI Server.

kobin.app.current_config(key, default=None)[source]

Get the configurations of your Kobin’s application.

Request

When a page is requested, automatically created a Request object that contains metadata about the request. Since this object is global within the thread, you can freely import from anywhere and retrieve request information.

class kobin.requests.LocalRequest(environ=None)[source]
bind(environ=None)

Initialize self. See help(type(self)) for accurate signature.

environ

Thread-local property

class kobin.requests.Request(environ=None)[source]

A wrapper for WSGI environment dictionaries.

method

The REQUEST_METHOD value as an uppercase string.

path

The value of PATH_INFO with exactly one prefixed slash (to fix broken clients and avoid the “empty path” edge case).

kobin.requests.accept_best_match(accept_header, mimetypes)[source]

Return a mimetype best matched the accept headers.

>>> accept_best_match('application/json, text/html', ['application/json', 'text/plain'])
'application/json'
>>> accept_best_match('application/json;q=0.5, text/*', ['application/json', 'text/plain'])
'text/plain'

Response

In contrast to Request objects, which are created automatically, Response objects are your responsibility. Each view functions you write is responsible for instantiating and returning an Response or its child classes.

In addition to the Response class, Kobin provides TemplateResponse ,
JSONResponse , RedirectResponse and HTTPError.
class kobin.responses.BaseResponse(body=None, status=None, headers=None)[source]

Base class for Response.

headerlist

WSGI conform list of (header, value) tuples.

status

The HTTP status line as a string (e.g. 404 Not Found).

status_code

The HTTP status code as an integer (e.g. 404).

exception kobin.responses.HTTPError(body, status, headers=None, charset='utf-8')[source]

Return the error message when raise this class.

class kobin.responses.JSONResponse(dic, status=200, headers=None, charset='utf-8', **dump_args)[source]

Returns a HTML text from dict or OrderedDict.

class kobin.responses.RedirectResponse(url)[source]

Redirect the specified url.

class kobin.responses.Response(body='', status=None, headers=None, charset='utf-8')[source]

Returns a plain text from unicode object.

class kobin.responses.TemplateResponse(filename, status=200, headers=None, charset='utf-8', **tpl_args)[source]

Returns a html using jinja2 template engine

Routing

Kobin’s routing system may be slightly distinctive.

Rule Syntax

Kobin use decorator based URL dispatch.

  • Dynamic convert URL variables from Type Hints.
from kobin import Kobin, Response, RedirectResponse
app = Kobin()

@app.route('/')
def index() -> Response:
    return Response('Hello World')

@app.route('/users/{user_id}')
def index(user_id: str) -> Response:
    return Response('User List')
Reverse Routing

app.router.reverse function returns URL. The usage is like this:

from kobin import Kobin, Response
app = Kobin()

@app.route('/', 'top-page')
def index() -> Response:
    return Response('Hello World')

@app.route('/users/{user_id}', 'user-detail')
def user_detail(user_id: int) -> Response:
    return Response('Hello User{}'.format(user_id))

print(app.router.reverse('top-page'))
# http://hostname/

print(app.router.reverse('user-detail', user_id=1))
# http://hostname/users/1
Reverse Routing and Redirecting

RedirectResponse The usage is like this:

from kobin import Kobin, Response, RedirectResponse
app = Kobin()

@app.route('/', 'top-page')
def index() -> Response:
    return Response('Hello World')

@app.route('/404')
def user_detail() -> Response:
    top_url = app.router.reverse('top-page')
    return RedirectResponse(top_url)
kobin.routes.match_path(rule, path)[source]

Match path.

>>> match_path('/foo', '/foo')
(True, {})
>>> match_path('/foo', '/bar')
(False, {})
>>> match_path('/users/{user_id}', '/users/1')
(True, {'user_id': '1'})
>>> match_path('/users/{user_id}', '/users/not-integer')
(True, {'user_id': 'not-integer'})
kobin.routes.match_url_vars_type(url_vars, type_hints)[source]

Match types of url vars.

>>> match_url_vars_type({'user_id': '1'}, {'user_id': int})
(True, {'user_id': 1})
>>> match_url_vars_type({'user_id': 'foo'}, {'user_id': int})
(False, {})

Developer guide

Bug Reports and Feature Requests

If you have encountered a problem with Kobin or have an idea for a new feature, please submit it to the issue tracker on Github.

Including or providing a link to the source files involved may help us fix the issue. If possible, try to create a minimal project that produces the error and post that instead.

Documentation

Build
  • English: make html
  • Japanese: make -e SPHINXOPTS="-D language='ja'" html
Translation

Updating your po files by new pot files.

$ make gettext
$ sphinx-intl update -p build/locale
# edit doc/source/locale/*.po files
$ make -e SPHINXOPTS="-D language='ja'" html

Reference: Internationalization – Sphinx documentation

Testing

The following test are running in Kobin project. If you add the changes to Kobin, Please run tox testing.

  • test: python setup.py test
  • coverage: coverage run setup.py test && coverage report
  • mypy: mypy --check-untyped-defs --fast-parser --python-version 3.6 kobin
  • Flake8: flake8
  • doctest: cd docs; make doctest
  • Run all with tox: tox

Requirements

Supported python versions are python 3.6. And Kobin has no required dependencies other than the Python Standard Libraries.

The following packages are optional:

  • wsgicli - Command Line Interface for developing WSGI application.
  • jinja2 - Jinja2 is a full featured template engine for Python.

Indices and tables