TCrudge - simple async CRUDL based on Tornado and Peewee ORM (Peewee Async)
Full documentation (http://tcrudge.readthedocs.io/en/latest/)
Simple configurable framework to create CRUDL (Create, Read, Update, Delete, List) for models. TCrudge is under heavy development - tons of bugs are expected. You can use it in production, but API can be broken at any moment.
Tornado is fast. Peewee is great. REST is wonderful.
- Tornado (https://github.com/tornadoweb/tornado)
- Peewee (https://github.com/coleifer/peewee)
- Peewee-async (https://github.com/05bit/peewee-async)
tcrudge is distributed via pypi: https://pypi.python.org/pypi/tcrudge/
pip install tcrudge
You can manually install latest version via GitHub:
pip install git+https://github.com/CodeTeam/tcrudge.git
Describe models using Peewee ORM. Subclass tcrudge.ApiListHandler
and tcrudge.ApiItemHandler
. Connect handlers with models using model_cls handler attribute. Add urls to tornado.Application url dispatcher.
For detailed example see tests (also, tests are available in Docker container with py.test).
You can run tests in docker container only. You'll need docker and docker-compose.
- Go to project root directory
- Run docker-compose up, it builts and runs containers.
- Go to tcrudge container bash: docker exec -ti tcrudge_tcrudge_1 bash
- Run: DATABASE_URL=postgresql://user:dbpass@pg/test pytest
- DELETE request on item is disabled by default. To enable it implement _delete method in your model.
- Models are fat. _create, _update, _delete methods are supposed to provide different logic on CRUD operations
- Django-style filtering in list request:
__gt
,__gte
,__lt
,__lte
,__in
,__isnull
,__like
,__ilike
,__ne
are supported. Use/?model_field__<filter_type>=<filter_condition>
for complex or/?model_field=<filter_condition>
for simple filtering. - Django-style order by: use
/?order_by=<field_1>,<field_2>
etc - Serialization is provided by Peewee:
playhouse.shortcuts.model_to_dict
.recurse
,exclude
andmax_depth
params are implemented in base class for better experience. If you want to serialize recurse foreign keys, do not forget to modifyget_queryset
method (see Peewee docs for details, use.join()
and.select()
) - Validation is provided out-of-the box via jsonschema. Just set input schemas for base methods (e.g. post_schema_input, get_schema_input etc). Request query is validated for GET and HEAD. Request body is validated for POST, PUT and DELETE.
- Pagination is activated by default for lists. Use
default_limit
andmax_limit
for customization. Pagination params are set through headers (X-Limit, X-Offset) or query:/?limit=100&offset=5
. Total amount of items is not returned by default. HEAD request should be sent or total param set to 1:/?total=1
- List handler supports default filtering and ordering. Use
default_filter
anddefault_order_by
class properties.
import asyncio
import peewee
import peewee_async
from playhouse.db_url import parse
from tornado import web
from tornado.ioloop import IOLoop
from tcrudge.handlers import ApiListHandler, ApiItemHandler
from tcrudge.models import BaseModel
# Configure Tornado to use asyncio
IOLoop.configure('tornado.platform.asyncio.AsyncIOMainLoop')
# Create database
DATABASE_URL = 'postgresql://user:dbpass@pg/test'
db_param = parse(DATABASE_URL)
db = peewee_async.PooledPostgresqlDatabase(**db_param)
# CRUDL Model
class Company(BaseModel):
name = peewee.TextField()
active = peewee.BooleanField()
class Meta:
database = db
# CL Handler
class CompanyDetailHandler(ApiItemHandler):
model_cls = Company
# RUD Handler
class CompanyListHandler(ApiListHandler):
model_cls = Company
default_filter = {'active': True}
app_handlers = [
('^/api/v1/companies/', CompanyListHandler),
('^/api/v1/companies/([^/]+)/', CompanyDetailHandler)
]
application = web.Application(app_handlers)
# ORM
application.objects = peewee_async.Manager(db)
with application.objects.allow_sync():
# Creates table, if not exists
Company.create_table(True)
application.listen(8080, '0.0.0.0')
loop = asyncio.get_event_loop()
# Start application
loop.run_forever()
- [Borisov Sergey] (https://github.com/juntatalor)
- [Shalamov Maxim] (https://github.com/mvshalamov)
- [Nikolaev Alexander] (https://github.com/wokli)
- [Krasavina Alina] (https://github.com/thaelathy)
- [Ivanov Denis] (https://github.com/steinerr)