This is a micro framework for building HTTP APIs on a high level of abstraction on top of aiohttp. It allows to create jsonapi-like HTTP interface to models in declarative way and leaves it possible to fine tune at any level.
Install the package
pip install aiohttp_baseapi
Creates project directory structure in current directory (it also contains two sample apps)
baseapi-start-project
Install the dependencies
cd src/
pip install -r .meta/packages
Configure Postgres DB connection
echo "DATABASE = {'host':'localhost','port':5432,'database':'test','user':'test','password':'test','minsize':1,'maxsize':10}" > ./settings_local.py
Create migrations
alembic revision --autogenerate -m "init"
Run migrations
alembic upgrade head
Run the application
python ./main.py --port=9000
That's it! You can try the API. It contains "default" app - it just prints all existing API methods under "/" location. And "demo" app - it contains two sample models.
http GET :9000
http POST :9000/authors <<< '{"data":{"name":"John", "surname": "Smith"}}'
http POST :9000/books <<< '{"data":{"category": "Fiction","name":"Birthday","is_available":true, "author_id": 1}}'
http GET ":9000/books?filter[name]=Birthday&include=authors"
http GET :9000/books/1
http PUT :9000/books/1 <<< '{"data":{"is_available":false}}'
http DELETE :9000/books/1
There are some built-in features you can use:
- filtration
- sorting
- fields selection
- pagination
- inclusion
- validation
Request and response formats are inspired by jsonapi.org, but have some differences.
Retrieved information can be filtered using filter
GET-parameter.
You can filter by multiple fields: filter[fieldname1]=foo&filter[fieldname2]=bar
.
In this case in response there are values for which the fieldname1
equals to foo
and fieldname2
equals to bar
.
Also you can filter enumerating desired values: filter[fieldname]=foo,bar
.
In this case in response there are values for which the fieldname
equals to foo
or bar
.
Retrieved information can be sorted using sort
GET-parameter.
Also you can sort enumerating multiple values: sort=fieldname1,-fieldname2
.
In this case values in response will be sorted by fieldname1
ascending, and then by fieldname2
descending.
Using parameter fields
you can retrieve only those fields which you need.
For example: fields=fieldname1,fieldname2
. In this case values in response will have only fieldname1
and fieldname2
fields.
Pagination (limit and offset) can be performed using page
parameter.
Usage: page[limit]=10&page[offset]=20
- standard pagination (20 items skipped, maximum 10 returned).
Also there is possibility to attach related entities using parameter include
.
One can apply described above features (filtration, sorting, etc.) to included entities. It will affect only included entities.
Examples:
filter[entity.fieldname]=foo
- filtration;
sort[entity]=fieldname
- sorting;
fields[entity]=fieldname
- choosing fields;
page[entity.limit]=10
- pagination.
The data passed in modifying requests (POST, PUT, etc.) can be validated using json-schema (which can be auto-generated from model description) or manually. Default data provider is database, but you can use anything you wish.
Run:
$ pip install -r .meta/packages_unit
$ cd src
$ make unit-test