{ "info": { "author": "Tim Martin", "author_email": "tim.martin@vertical-knowledge.com", "bugtrack_url": null, "classifiers": [], "description": "# How to turn your database into a ReSTful API in under 10 lines of code\n\nA package to turn your database into a ReSTful API in just 10 lines of code.\n\nYou can either install the package and simply start the API from the\ncommand line or you can follow this tutorial to build it yourself.\n\n## Installation\n\n```bash\npip install ripozo-oasis\n```\n\n## Running your API\n\nTo turn your database into a ReSTful API simply run the following command.\n\n```bash\nauto-api \"mysql://localhost:3306/mydatabase\"\n```\n\nYou will need to pass a Database URI according to the \n[SQLALchemy Engine Configuration documentation](http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html).\nThe format is `'dialect+driver://username:password@host:port/database_name'`.\nThe driver is optional and only necessary if you do not wish to use the default. If you get import errors\nyou will need to install a specific driver for your database. For example, with MySQL you'll need\nto run ``pip install mysql-python`` or for postgresql you'll need to run ``pip install psycopg2``.\n\nNow we can curl the base to get all available endpoints\n\n```bash\ncurl -X OPTIONS http://localhost:5000/\n```\n\nWe may see something like this assuming we had two tables, groups and users.\n\n```javascript\n{\n \"_embedded\": {},\n \"_links\": {\n \"group\": {\n \"href\": \"/group/\"\n },\n \"user\": {\n \"href\": \"/user/\"\n },\n \"self\": {\n \"href\": \"http://localhost:5000/\"\n }\n }\n}\n```\n\nWe could additionally vary the accept type to get a SIREN formatted response\n\n```bash\ncurl -X OPTIONS -H \"Accept: application/vnd.siren+json\" http://localhost:5000/\n```\n\n```javascript\n{\n \"entities\": [],\n \"class\": [\n \"\"\n ],\n \"links\": [\n {\n \"href\": \"http://localhost:5000/\",\n \"rel\": [\n \"self\"\n ]\n },\n {\n \"href\": \"http://localhost:5000/group/\",\n \"rel\": [\n \"group_list\"\n ]\n },\n {\n \"href\": \"http://localhost:5000/group//\",\n \"rel\": [\n \"group\"\n ]\n },\n {\n \"href\": \"http://localhost:5000/user/\",\n \"rel\": [\n \"user_list\"\n ]\n },\n {\n \"href\": \"http://localhost:5000/user//\",\n \"rel\": [\n \"user\"\n ]\n }\n ],\n \"actions\": [\n {\n \"fields\": [],\n \"href\": \"http://localhost:5000/\",\n \"title\": \"All Options\",\n \"method\": \"OPTIONS\",\n \"name\": \"all_options\"\n }\n ],\n \"properties\": {}\n}\n```\n\nWe have full CRUD+L (Create, Retrieve, Update, Delete and List) operations: a POST to ``/user/`` creates\na new user, a GET to ``/user/`` returns a list of all users, a GET on ``/user//``\nreturns an individual user and so forth.\n\n## Tutorial\n\nThis tutorial uses a powerful and extensible ReST framework called\n[ripozo](https://github.com/vertical-knowledge/ripozo) and a couple\npackages in the ripozo ecosystem: [flask-ripozo](https://github.com/vertical-knowledge/flask-ripozo)\nand [ripozo-sqlalchemy](https://github.com/vertical-knowledge/ripozo-sqlalchemy). Ripozo\nis web framework independent, meaning you can use it in any desired web framework.\nOfficial integrations include [flask-ripozo](https://github.com/vertical-knowledge/flask-ripozo)\nand [django-ripozo](https://github.com/vertical-knowledge/django-ripozo) with more to come.\nIn addition to building seamless ReSTful API's, ripozo can expose [Hypermedia/HATEOAS](http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)\ndriven API's with *no additional effort*.\n\n### Step 1: Create the Flask App\n\nThe first step is to setup our [Flask](https://github.com/mitsuhiko/flask) application.\nYou can use [django-ripozo](https://github.com/vertical-knowledge/django-ripozo) \nwith minimal deviations from this tutorial.\nUnfortunately, bootstrapping a django project requires more than 10 lines of code.\n\nFirst, install Flask.\n\n```bash\npip install Flask\n```\n\nNow instantiate a Flask Application.\n\n```python\nfrom flask import Flask\napp = Flask(__name__)\n```\n\n### Step 2: Setup SQLAlchemy\n\n[SQLAlchemy](http://www.sqlalchemy.org/) is another favorite tool of mine. It provides\nan excellent ORM and allows us to generate an ORM from an existing database\nwith no additional work.\n\n```bash\npip install SQLAlchemy\n```\n\nCreating a sqlalchemy engine is incredibly simple. We simply\npass SQLAlchemy a database URI in the expected format. See\nthe [Engine Configuration documentation](http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html)\nfor more details. TL;DR this is the general format: \n`'dialect+driver://username:password@host:port/database_name'`\n\n```python\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.automap import automap_base\n\ndatabase_uri = 'mysql://localhost:3306/mydatabase'\nengine = create_engine(database_uri)\nbase = automap_base()\nbase.prepare(engine, reflect=True)\n```\n\nThis creates an ORM where we can access tables in the database\nas python objects.\n\n### Step 3: Bind ripozo\n\nNow that we have our database and web application working, we need to bind \n[ripozo](https://github.com/vertical-knowledge/ripozo) to Flask and SQLAlchemy.\n\n```bash\npip install ripozo flask-ripozo ripozo-sqlalchemy\n```\n\n```python\nfrom flask_ripozo import FlaskDispatcher\nfrom ripozo import adapters\nfrom ripozo_sqlalchemy import ScopedSessionHandler\n\n# Attach the previously create Flask application\ndispatcher = FlaskDispatcher(app)\n# Adapters inform ripozo how to represent the resources over HTTP (typically a\n# protocol for a JSON response). In this case, we've chosen the Hal and SIREN protocols.\ndispatcher.register_adapters(adapters.SirenAdapter, adapters.HalAdapter)\n# Create a session handler to cleanly handle database transactions and cleanup\nsession_handler = ScopedSessionHandler(engine)\n```\n\n### Step 4: Expose our database\n\nNow that we have completed all necessary setup, we can\nexpose our database as a ReSTful API.\n\n```python\n# The create_resource method is a shortcut for creating ripozo resources \n# containing common sets of endpoints.\n# We need to pass append_slash=True due to a quirk in how flask handles routing\nresources = [create_resource(model, session_handler, append_slash=True) for model in base.classes]\n# Register the resources with the adapter to expose them in the API.\ndispatcher.register_resources(*resources)\n\n# and now we run our Flask app\napp.run()\n```\n\nThe ``create_resource`` method is highly customizable. Additionally, you can use a\ndeclarative, class based implementation that is incredibly flexible. In fact,\nthe ``create_resource`` method uses the declarative implementation under the covers.\n\n### Step 5: Putting it all together\n\nNow that we have everything we need, let's put it all together\ninto one function.\n\n```python\nfrom flask import Flask\nfrom flask_ripozo import FlaskDispatcher\nfrom ripozo import adapters\nfrom ripozo_sqlalchemy import ScopedSessionHandler, create_resource\nfrom sqlalchemy.ext.automap import automap_base\nfrom sqlalchemy import create_engine\n\n\ndef create_app(database_uri):\n app = Flask(__name__)\n \n engine = create_engine(database_uri)\n base = automap_base()\n base.prepare(engine, reflect=True)\n\n dispatcher = FlaskDispatcher(app)\n dispatcher.register_adapters(adapters.HalAdapter, adapters.SirenAdapter)\n session_handler = ScopedSessionHandler(engine)\n\n resources = [create_resource(model, session_handler, append_slash=True) for model in base.classes]\n dispatcher.register_resources(*resources)\n \n app.run()\n```\n\nAnd just like that we have exposed our database as a ReSTful API. Additionally,\nbecause this is [ripozo](https://github.com/vertical-knowledge/ripozo), if a table\nhas a relationship to another table, a link to the corresponding row/resource is \nautomatically generated. For example, consider a user table has a Many-to-One relationship with a group table.\nWhen we go to a user's endpoint, we'll get a fully qualified URL linking to the associated group's endpoint.\n\n\n## Conclusion\n\nWe can see how easy [ripozo](https://github.com/vertical-knowledge/ripozo) makes\ncreating ReSTful API's. With [ripozo](https://github.com/vertical-knowledge/ripozo),\nyou can include authentication and authorization, additional endpoints and much more.\n[Ripozo](https://github.com/vertical-knowledge/ripozo) is designed to be flexible and \nefficient at the same time. It provides shortcuts\nwhile priotizing extensibility. It unleashes more flexibility and power than \nany other Hypermedia/HATEOAS ReSTful framework. Ripozo: less effort, better APIs. \n\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "ripozo-oasis", "package_url": "https://pypi.org/project/ripozo-oasis/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/ripozo-oasis/", "project_urls": null, "release_url": "https://pypi.org/project/ripozo-oasis/1.0.1/", "requires_dist": null, "requires_python": "", "summary": "", "version": "1.0.1" }, "last_serial": 1842667, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "8a69cace5054213dece933089194fdab", "sha256": "dbadd2a081abf7f46c54ae28e02c6a6ec78d1a80ee05161e686102c444c06d3e" }, "downloads": -1, "filename": "ripozo-oasis-0.1.0.tar.gz", "has_sig": false, "md5_digest": "8a69cace5054213dece933089194fdab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1051, "upload_time": "2015-12-01T06:14:30", "url": "https://files.pythonhosted.org/packages/09/c4/a67a067b8d0fd26fa5893759e43bdda67088610a4d7340a6c2277db92180/ripozo-oasis-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "e51ade1445669c3664853756d7fc4b86", "sha256": "1964ece147027e7be13dbe769cfb50cecae78c83e0c9b4ae1ab00b02da31f819" }, "downloads": -1, "filename": "ripozo-oasis-0.1.1.tar.gz", "has_sig": false, "md5_digest": "e51ade1445669c3664853756d7fc4b86", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1054, "upload_time": "2015-12-01T06:19:20", "url": "https://files.pythonhosted.org/packages/8d/40/c5e740d240ab340ae2caa9da2adee3d0247a5ccdd3ffd2ab5df685a61611/ripozo-oasis-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "32c7edad976b42f7b5ba61d0014e523b", "sha256": "9e5aad59f39f5002297312371c12ccddfe2c1d71888780d92154e98b7cdbb003" }, "downloads": -1, "filename": "ripozo-oasis-0.1.2.tar.gz", "has_sig": false, "md5_digest": "32c7edad976b42f7b5ba61d0014e523b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1060, "upload_time": "2015-12-01T06:41:02", "url": "https://files.pythonhosted.org/packages/e2/ae/870c935e68d8808bd346b8690ce4032b2f272ef4a9182933abf310e02fe4/ripozo-oasis-0.1.2.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "49f36cc8eb57f6ed075da425059d23e5", "sha256": "be26dc0cd99ad1dcf6c63f6ee81417b4bb74a1076684d96ee9f2e18a7b429448" }, "downloads": -1, "filename": "ripozo-oasis-1.0.0.tar.gz", "has_sig": false, "md5_digest": "49f36cc8eb57f6ed075da425059d23e5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11526, "upload_time": "2015-12-02T01:52:56", "url": "https://files.pythonhosted.org/packages/8b/91/446a0d9718c77b7a84ccc38b40eabb583718b9143653a182100e55dfe6ab/ripozo-oasis-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "e8f4f6845fa2088e4925ab5ec8b5ff1c", "sha256": "25537084177ad102dff836571d8185e7374bc44a1101b32c42dabbc6f4a3453c" }, "downloads": -1, "filename": "ripozo-oasis-1.0.1.tar.gz", "has_sig": false, "md5_digest": "e8f4f6845fa2088e4925ab5ec8b5ff1c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11967, "upload_time": "2015-12-02T02:16:55", "url": "https://files.pythonhosted.org/packages/e7/cd/6489a0d35c7a2db753503534aa15a94b6871669c33ef3b43bae07c279756/ripozo-oasis-1.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e8f4f6845fa2088e4925ab5ec8b5ff1c", "sha256": "25537084177ad102dff836571d8185e7374bc44a1101b32c42dabbc6f4a3453c" }, "downloads": -1, "filename": "ripozo-oasis-1.0.1.tar.gz", "has_sig": false, "md5_digest": "e8f4f6845fa2088e4925ab5ec8b5ff1c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11967, "upload_time": "2015-12-02T02:16:55", "url": "https://files.pythonhosted.org/packages/e7/cd/6489a0d35c7a2db753503534aa15a94b6871669c33ef3b43bae07c279756/ripozo-oasis-1.0.1.tar.gz" } ] }