├── AUTHORS ├── LICENSE ├── Procfile ├── README.rst ├── requirements.txt ├── run-auth.py ├── run-hello.py ├── run-hooks.py ├── run-simple.py ├── run.py ├── runtime.txt └── settings.py /AUTHORS: -------------------------------------------------------------------------------- 1 | Eve Demo is written and maintained by Nicola Iarocci and various contributors 2 | (I wish!): 3 | 4 | Development Lead 5 | ```````````````` 6 | 7 | - Nicola Iarocci 8 | 9 | Patches and Suggestions 10 | ``````````````````````` 11 | 12 | - 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 by Nicola Iarocci and contributors. See AUTHORS 2 | for more details. 3 | 4 | Some rights reserved. 5 | 6 | Redistribution and use in source and binary forms of the software as well 7 | as documentation, with or without modification, are permitted provided 8 | that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following 15 | disclaimer in the documentation and/or other materials provided 16 | with the distribution. 17 | 18 | * The names of the contributors may not be used to endorse or 19 | promote products derived from this software without specific 20 | prior written permission. 21 | 22 | THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 24 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 26 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 33 | DAMAGE. 34 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: python run.py 2 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Eve-Demo 2 | ======== 3 | 4 | A fully featured RESTful Web API powered by Eve_. With Eve setting up an API is 5 | very simple. You just need a launch script (run.py_) and a configuration file 6 | (settings.py_). Check out the settings.py_ module in this repo to get an idea 7 | of how configuration is handled. Don't forget to visit Eve_ website for 8 | a complete list of features and examples. 9 | 10 | If you need a gentle introduction to the wondeful world of RESTful WEB APIs, 11 | check out my EuroPython 2012 talk: `Developing RESTful Web APIs with Python, 12 | Flask and MongoDB 13 | `_ 14 | 15 | There is also a sample client application available. It uses the Requests 16 | library to consume the demo. In fact it has been quickly hacked together to 17 | reset the API every once in a while. Check it out at 18 | https://github.com/pyeve/eve-demo-client. 19 | 20 | .. _Eve: http://python-eve.org 21 | .. _run.py: https://github.com/pyeve/eve-demo/blob/master/run.py 22 | .. _settings.py: https://github.com/pyeve/eve-demo/blob/master/settings.py 23 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Eve>=0.8,<0.9 2 | -------------------------------------------------------------------------------- /run-auth.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Eve Demo 5 | ~~~~~~~~ 6 | 7 | A demostration of a simple API powered by Eve REST API. 8 | 9 | The live demo is available at eve-demo.herokuapp.com. Please keep in mind 10 | that the it is running on Heroku's free tier using a free MongoHQ 11 | sandbox, which means that the first request to the service will probably 12 | be slow. The database gets a reset every now and then. 13 | 14 | :copyright: (c) 2016 by Nicola Iarocci. 15 | :license: BSD, see LICENSE for more details. 16 | """ 17 | 18 | from eve import Eve 19 | from eve.auth import BasicAuth 20 | 21 | 22 | class MyBasicAuth(BasicAuth): 23 | def check_auth(self, username, password, allowed_roles, resource, method): 24 | return username == 'admin' and password == 'secret' 25 | 26 | app = Eve(auth=MyBasicAuth) 27 | 28 | if __name__ == '__main__': 29 | app.run() 30 | -------------------------------------------------------------------------------- /run-hello.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Eve Demo 5 | ~~~~~~~~ 6 | 7 | A demostration of a simple API powered by Eve REST API. 8 | 9 | The live demo is available at eve-demo.herokuapp.com. Please keep in mind 10 | that the it is running on Heroku's free tier using a free MongoHQ 11 | sandbox, which means that the first request to the service will probably 12 | be slow. The database gets a reset every now and then. 13 | 14 | :copyright: (c) 2016 by Nicola Iarocci. 15 | :license: BSD, see LICENSE for more details. 16 | """ 17 | 18 | from eve import Eve 19 | 20 | app = Eve() 21 | 22 | 23 | @app.route('/hello') 24 | def hello_world(): 25 | return 'hello world!' 26 | 27 | if __name__ == '__main__': 28 | app.run() 29 | -------------------------------------------------------------------------------- /run-hooks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Eve Demo 5 | ~~~~~~~~ 6 | 7 | A demostration of a simple API powered by Eve REST API. 8 | 9 | The live demo is available at eve-demo.herokuapp.com. Please keep in mind 10 | that the it is running on Heroku's free tier using a free MongoHQ 11 | sandbox, which means that the first request to the service will probably 12 | be slow. The database gets a reset every now and then. 13 | 14 | :copyright: (c) 2016 by Nicola Iarocci. 15 | :license: BSD, see LICENSE for more details. 16 | """ 17 | 18 | from eve import Eve 19 | 20 | 21 | def pyconweb(endpoint, response): 22 | for document in response['_items']: 23 | document['PYCONWEB'] = 'IS SO COOL!' 24 | 25 | app = Eve() 26 | app.on_fetched_resource += pyconweb 27 | 28 | if __name__ == '__main__': 29 | app.run() 30 | -------------------------------------------------------------------------------- /run-simple.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Eve Demo 5 | ~~~~~~~~ 6 | 7 | A demostration of a simple API powered by Eve REST API. 8 | 9 | The live demo is available at eve-demo.herokuapp.com. Please keep in mind 10 | that the it is running on Heroku's free tier using a free MongoHQ 11 | sandbox, which means that the first request to the service will probably 12 | be slow. The database gets a reset every now and then. 13 | 14 | :copyright: (c) 2016 by Nicola Iarocci. 15 | :license: BSD, see LICENSE for more details. 16 | """ 17 | 18 | from eve import Eve 19 | 20 | app = Eve() 21 | app.run() 22 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | Eve Demo 5 | ~~~~~~~~ 6 | 7 | A demostration of a simple API powered by Eve REST API. 8 | 9 | The live demo is available at eve-demo.herokuapp.com. Please keep in mind 10 | that the it is running on Heroku's free tier using a free MongoHQ 11 | sandbox, which means that the first request to the service will probably 12 | be slow. The database gets a reset every now and then. 13 | 14 | :copyright: (c) 2016 by Nicola Iarocci. 15 | :license: BSD, see LICENSE for more details. 16 | """ 17 | 18 | import os 19 | from eve import Eve 20 | 21 | # Heroku support: bind to PORT if defined, otherwise default to 5000. 22 | if 'PORT' in os.environ: 23 | port = int(os.environ.get('PORT')) 24 | # use '0.0.0.0' to ensure your REST API is reachable from all your 25 | # network (and not only your computer). 26 | host = '0.0.0.0' 27 | else: 28 | port = 5000 29 | host = '127.0.0.1' 30 | 31 | app = Eve() 32 | 33 | 34 | if __name__ == '__main__': 35 | app.run(host=host, port=port) 36 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.6.5 2 | -------------------------------------------------------------------------------- /settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | eve-demo settings 5 | ~~~~~~~~~~~~~~~~~ 6 | 7 | Settings file for our little demo. 8 | 9 | PLEASE NOTE: We don't need to create the two collections in MongoDB. 10 | Actually, we don't even need to create the database: GET requests on an 11 | empty/non-existant DB will be served correctly ('200' OK with an empty 12 | collection); DELETE/PATCH will receive appropriate responses ('404' Not 13 | Found), and POST requests will create database and collections when needed. 14 | Keep in mind however that such an auto-managed database will most likely 15 | perform poorly since it lacks any sort of optimized index. 16 | 17 | :copyright: (c) 2016 by Nicola Iarocci. 18 | :license: BSD, see LICENSE for more details. 19 | """ 20 | 21 | import os 22 | 23 | # We want to seamlessy run our API both locally and on Heroku. If running on 24 | # Heroku, sensible DB connection settings are stored in environment variables. 25 | MONGO_URI = os.environ.get('MONGODB_URI', 'mongodb://user:user@localhost:27017/evedemo') 26 | 27 | 28 | # Enable reads (GET), inserts (POST) and DELETE for resources/collections 29 | # (if you omit this line, the API will default to ['GET'] and provide 30 | # read-only access to the endpoint). 31 | RESOURCE_METHODS = ['GET', 'POST', 'DELETE'] 32 | 33 | # Enable reads (GET), edits (PATCH) and deletes of individual items 34 | # (defaults to read-only item access). 35 | ITEM_METHODS = ['GET', 'PATCH', 'DELETE'] 36 | 37 | # We enable standard client cache directives for all resources exposed by the 38 | # API. We can always override these global settings later. 39 | CACHE_CONTROL = 'max-age=20' 40 | CACHE_EXPIRES = 20 41 | 42 | # Our API will expose two resources (MongoDB collections): 'people' and 43 | # 'works'. In order to allow for proper data validation, we define beaviour 44 | # and structure. 45 | people = { 46 | # 'title' tag used in item links. 47 | 'item_title': 'person', 48 | 49 | # by default the standard item entry point is defined as 50 | # '/people//'. We leave it untouched, and we also enable an 51 | # additional read-only entry point. This way consumers can also perform GET 52 | # requests at '/people//'. 53 | 'additional_lookup': { 54 | 'url': 'regex("[\w]+")', 55 | 'field': 'lastname' 56 | }, 57 | 58 | # Schema definition, based on Cerberus grammar. Check the Cerberus project 59 | # (https://github.com/pyeve/cerberus) for details. 60 | 'schema': { 61 | 'firstname': { 62 | 'type': 'string', 63 | 'minlength': 1, 64 | 'maxlength': 10, 65 | }, 66 | 'lastname': { 67 | 'type': 'string', 68 | 'minlength': 1, 69 | 'maxlength': 15, 70 | 'required': True, 71 | # talk about hard constraints! For the purpose of the demo 72 | # 'lastname' is an API entry-point, so we need it to be unique. 73 | 'unique': True, 74 | }, 75 | # 'role' is a list, and can only contain values from 'allowed'. 76 | 'role': { 77 | 'type': 'list', 78 | 'allowed': ["author", "contributor", "copy"], 79 | }, 80 | # An embedded 'strongly-typed' dictionary. 81 | 'location': { 82 | 'type': 'dict', 83 | 'schema': { 84 | 'address': {'type': 'string'}, 85 | 'city': {'type': 'string'} 86 | }, 87 | }, 88 | 'born': { 89 | 'type': 'datetime', 90 | }, 91 | } 92 | } 93 | 94 | works = { 95 | # if 'item_title' is not provided Eve will just strip the final 96 | # 's' from resource name, and use it as the item_title. 97 | #'item_title': 'work', 98 | 99 | # We choose to override global cache-control directives for this resource. 100 | 'cache_control': 'max-age=10,must-revalidate', 101 | 'cache_expires': 10, 102 | 103 | 'schema': { 104 | 'title': { 105 | 'type': 'string', 106 | 'required': True, 107 | }, 108 | 'description': { 109 | 'type': 'string', 110 | }, 111 | 'owner': { 112 | 'type': 'objectid', 113 | 'required': True, 114 | # referential integrity constraint: value must exist in the 115 | # 'people' collection. Since we aren't declaring a 'field' key, 116 | # will default to `people._id` (or, more precisely, to whatever 117 | # ID_FIELD value is). 118 | 'data_relation': { 119 | 'resource': 'people', 120 | # make the owner embeddable with ?embedded={"owner":1} 121 | 'embeddable': True 122 | }, 123 | }, 124 | } 125 | } 126 | 127 | # The DOMAIN dict explains which resources will be available and how they will 128 | # be accessible to the API consumer. 129 | DOMAIN = { 130 | 'people': people, 131 | 'works': works, 132 | } 133 | --------------------------------------------------------------------------------