Eve allows to effortlessly build and deploy a fully featured, REST-compliant, proprietary API. HATEOAS, Pagination, Persistent identifiers, Conditional requests, Concurrency control, versioning, JSON and XML responses: these features are supported and enabled by default.
Once Eve is installed this is what you will need to bring your glorified API online:
- A database
- A simple configuration file
- A minimal launch script
Support for MongoDB comes out of the box; extensions for other SQL/NoSQL
databases can be developed with relative ease. API settings are stored in
a standard Python module (defaults to settings.py
) in your project folder, you
can also use an environment variable). Overall, you will find that configuring
and fine-tuning your API is a very simple process. Most of the times the
launch script will be as simple as:
from eve import Eve app = Eve() app.run()
Check out the live demo of a Eve-powered API at https://github.com/nicolaiarocci/eve-demo. It comes with source code and usage examples for all common use cases (GET, POST, PATCH, DELETE and more).
There is also a sample client application available. It uses the phenomenal Requests library to consume the demo API. In fact, it has been quickly hacked togheter to reset the API every once in a while. Check it out at https://github.com/nicolaiarocci/eve-demo-client.
Emphasis on the REST. The Eve project aims to provide the best possibile REST-compliant API implementation. Basic REST principles like separation of concerns, stateless and layered system, cacheability, uniform interface, etc have been (hopefully!) kept into consideration while designing the core API.
Full range of CRUD operations via HTTP verbs. APIs can support the full range of CRUD (Create, Read, Update, Delete) operations. You can have a read-only resource accessible at one endpoint along with a fully editable resource at another endpoint within the same API. The following table shows Eve's implementation of CRUD via REST
Action
HTTP Verb
Context
Create
POST
Collection
Read
GET
Collection/Document
Update
PATCH
Document
Delete
DELETE
Collection/Document
Read-only by default. If all you need is a read-only API, then you can have it up and running real quick.
Customizable resource endpoints (persistent identifiers). By default Eve will make known database collections available as resource endpoints. A
contacts
collection in the database will be ready to be consumed atexample.com/contacts/
. You can customize the URIs of your resources so in our example the API endpoint could become, say,example.com/customers/
.Customizable, multiple item endpoints. Resources can or cannot provide access to their own individual items. API consumers could get access to
/contacts/
,/contacts/<ObjectId>/
and/contacts/smith/
, but only to/invoices/
if so you wish. When you do grant access to resource items, you can define up to two lookup endpoints, both defined via regex. The first will be the primary endpoint and will match your database primary key structure (i.e. an ObjectId in a MongoDB database). The second, which is optional, will match a field with unique values, since Eve will retrieve only the first match anyway.Filtering and sorting. Resource endpoints allow consumers to retrieve multiple documents. Query strings are supported, allowing for filtering and sorting.
Two query formats. Currently two query formats are supported: the mongo query syntax (
?where={"name": "john doe"}
), and the native python syntax (?where=name=='john doe'
). Both query formats allow for conditional and logical And/Or operators, however nested and combined.Pagination. Resource pagination is enabled by default in order to improve performance and preserve bandwith. When a consumer requests a resource, the first N items matching the query are serverd. Links to subsequent/previous pages are provided with the response. Default and maximum page size is customizable, and consumers can request specific pages via the query string (
?page=10
).HATEOAS. Hypermedia as the Engine of Application State is enabled by default. Each response includes a <links> section. Links provide details on their
relation
relative to the resource being accessed and atitle
. Titles and relations could be used by clients to dynamically updated their UI, or to navigate the API without knowing it structure beforehand. An example:"links": [ <link rel='parent' title='home' href='http://api.example.com/' />, <link rel='collection' title='contacts' href='http://api.example.com/contacts/' />, <link rel='next' title='next page' href='http://api.example.com/contacts/?page=2' />, ]
In fact, a GET request to the API home page (the API entry point) will be served with a list of links to accessible resources. From there any consumer could navigate the API just by following the links.
JSON and XML. Eve responses are automatically rendered as JSON or XML depending on the requested
Accept
header. Inbound documents (for inserts and edits) are in JSON format.Last-Modified and ETag (conditional requests).Each resource representation provides information on the last time it was updated along with an hash value computed on the representation itself (
Last-Modified
andETag
response headers). These allow consumers to only retrieve new or modified data via theIf-Modified-Since
andIf-None-Match
request headers.Data integrity and concurrency control. API responses include a
ETag
header, which allows for proper concurrency control. AnETag
is an hash value representing the current state of the resource on the server. Consumers are not allowed to edit or delete a resource unless they provide an up-to-dateETag
for the resource they are attempting to edit.Multiple inserts. Consumers can send a stream of multiple documents to be inserted for a given resource. The response will provide detailed state information about each item inserted (creation date, link to the item endpoint, primary key/id, etc.). Errors on one documnt won't prevent the insertion of other documents in the data stream.
Data validation. Data validation is provided out-of-the-box. Your configuration includes a schema definition for every resource managed by the API. Data sent to the API for insertion or edition will be validated against the schema, and a resource will be updated only if validation is passed. In case of multiple inserts the response will provide a success/error state for each individual item.
Extensible data validation. Data validation is based on the Cerberus validation system and therefore it is extensible so you can adapt it to your specific use case. Say that your API can only accept odd numbers for a certain field values: you can extend the validation class to validate that. Or say that you want to make sure that a VAT field actually matches your own country VAT algorithm: you can do that too. As a matter of fact, Eve's MongoDB data-layer itself is extending Cerberus' standard validation, implementing the
unique
schema field constraint.Resource-level cache control directives. You can set global and individual cache-control directives for each resource. Directives will be included in API response headers (
Cache-Control
,Expires
). This will minimize load on the server since cache-enbaled consumers will perform resource-intensive request only when really needed.Versioning. Define a default prefix and/or API version for all your endpoints. How about example.com/api/v1/<endpoint>? Both prefix and version are as easy to set up as setting a configuration variable.
Eve is on PyPI so all you need to do is
pip install eve
Just run
python setup.py test
Eve has been tested successfully under Python 2.7 and Python 2.6.
Eve is BSD licensed. See the LICENSE for details.
Consider this a public preview (Alpha). Best way to be notified about its availability is by starring/following the project repo at GitHub https://github.com/nicolaiarocci/eve. You can follow me on Twitter at http://twitter.com/nicolaiarocci.
At Gestionale Amica we had been working hard on a full featured, Python powered, RESTful Web API. We learned quite a few things on REST best patterns, and we got a chance to put Python's renowned web capabilities under review. Then, at EuroPython 2012, I got a chance to share what we learned and my talk sparked quite a bit of interest there. A few months have passed and still the slides are receiving a lot of hits each day, and I keep receiving emails about source code samples and whatnot. After all, a REST API lies in the future of every web-oriented developer, and who isn't these days?
So I thought that perhaps I could take the proprietary, closed code (codenamed 'Adam') and refactor it "just a little bit", so that it could fit a much wider number of use cases. I could then release it as an open source project. Well it turned out to be slightly more complex than that but finally here it is, and of course it's called Eve.
It still got a long way to go before it becomes the fully featured open source, out-of-the-box API solution I came to envision (see the Roadmap below), but I feel that at this point the codebase is ready enough for a public preview. This will hopefully allow for some constructive feedback and maybe, for some contributors to join the ranks.
PS: the slides of my EuroPython REST API talk are available online. You might want to check them to understand why and how certain design decisions were made, especially with regards to REST implementation.
In no particular order, here's a partial list of the features that I plan/would like to add to Eve, provided that there is enough interest in the project.
- Documentation (coming soon!)
- Granular exception handling
- Journaling/error logging
- Server side caching
- Alternative sort syntax (
?sort=name
) - Authorization (OAuth2?)
- Support for MySQL and/or other SQL/NoSQL databases