Home

Awesome

Apiphant

Simple Python Web API framework, based on Gevent, JSON, CRUD.

Features:

    mkdir -p myproduct/api/v0
    touch {myproduct,myproduct/api,myproduct/api/v0}/__init__.py

    cat <<END >myproduct/api/v0/echo.py
    # from myproduct.api import anything
    def read(request):
        response = request.copy()
        response.server = 'myproduct'
        return response
    END

    sudo apt-get install --yes gcc libevent-dev python-dev
    sudo pip install apiphant
    apiphant myproduct 127.0.0.1:8001

    # POST http://{host}:{port}/api/{version}/{t/a/r/g/e/t}/{action}
    curl -X POST http://127.0.0.1:8001/api/v0/echo/read -d '{"hello": "world"}'
    {"hello": "world", "server": "myproduct"}
    apiphant myproduct 127.0.0.1:8888

    cat <<END >test.py
    from apiphant.test import test
    test('echo', 'read', {"hello": "world"}, 200, {"hello": "world", "server": "myproduct"})
    END

    python test.py
    POST http://127.0.0.1:8888/api/v0/echo/read {"hello": "world"} --> 200 {'hello': 'world', 'server': 'myproduct'}
* Please see how this shell script [test.sh][] can help to run Python tests in [test.py][].
    from apiphant.validation import ApiError, field, Invalid

    def read(request):
        id = field(request, 'id', is_required=True, valid_type=int)
        # More options: default_value, valid_value, valid_length, max_length, explain.

        item = get_item(id)
        if not item:
            raise Invalid('id')
            # that is a shortcut for:
            raise ApiError(400, {"field": "id", "state": "invalid"})

        raise Invalid('id', id) # {"field": "id", "state": "invalid", "explain": -1}
    cat <<END >myproduct/api/background.py # Or background/__init__.py importing modules of tasks.
    from apiphant.background import seconds

    @seconds(60)
    def update_something():
        pass
    END

    apiphant-background myproduct

    INFO at background.main:107 [2013-08-12 13:16:52,624] Task update_something: OK.
    INFO at background.main:107 [2013-08-12 13:17:53,012] Task update_something: OK.
* Error tracebacks are logged and may be e.g. emailed:
    def on_error(error):
        send_email_message(to=email_config['user'], subject='Error', text=error, **email_config)
        # See https://pypi.python.org/pypi/send_email_message

    @seconds(60)
    def update_something():
        1/0

    apiphant-background myproduct

    ERROR at background.main:92 [2013-08-12 13:22:41,205] Task update_something failed:
    Traceback (most recent call last):  File "...myproduct/api/background.py", line 18, in update_something
        1/0
    ZeroDivisionError: integer division or modulo by zero

    INFO at background.main:104 [2013-08-12 13:22:43,229] on_error: OK.
    (Email is sent)
    sudo pip install multipart

    from multipart import parse_form_data
    from apiphant.server import raw_environ

    @raw_environ
    def create(environ):
        forms, files = parse_form_data(environ)
    from apiphant.server import raw_environ, raw_response

    @raw_environ
    @raw_response
    def create(environ, start_response):
        try:
            ...
        except:
            ...
        finally:
            start_response(status, headers)
            return [response]

apiphant version 0.2.5
Copyright (C) 2013 by Denis Ryzhkov denisr@denisr.com
MIT License, see http://opensource.org/licenses/MIT