[![Build Status](https://travis-ci.org/algoo/hapic.svg?branch=master)](https://travis-ci.org/algoo/hapic)
[![Coverage Status](https://coveralls.io/repos/github/algoo/hapic/badge.svg?branch=master)](https://coveralls.io/github/algoo/hapic?branch=master)
# hapic in a nutshell
hapic is a framework-agnostic library for coding professionnal REST APIs.
# Philosophy
hapic as been developed by algoo in the context of a large service oriented project. The lack of a tool allowing real auto-documentation of Rest API has decided us to develop hapic.
target usage is not for "quick and dirty" stuff but for professionnal, maintainable, long-term targeted projects.
The separation of concerns between REST APIs layer and business stuff layer is in the DNA of hapic.
hapic is *just* the HTTP layer glue code over your business code.
# Direct benefits of using hapic
When you decide to base your development on hapic, you'll get direct benefits:
## Ready-to-use
- supports aiohttp, flask, pyramid and bottle
- ready-to-use with your existing libraries
- effortless mapping of exceptions to HTTP errors
- serialisation based on marshmallow schemas or serpyco dataclasses
## Full API documentation ready
- your code *IS* the documentation
- swagger generated documentation
- embed the documentation in 1 line of code
- supports python 3.5, 3.6 and 3.7
## Professionnal and maintanable source code
- separation of concerns between business logic and HTTP stuff
- very fast when used in conjunction with both aiohttp and serpyco
- extensible framework for supporting other web framework and serialisation libraries
# Licence
hapic is licenced under the MIT licence. You can use it in your projects, closed or open sourced.
## status, contributions
hapic source code is ready for production. Some refactoring are identified and required for maintainability, but public APIs are stable so you can rely on hapic for your developments.
hapic is under active development, based on different professional projects. we will answer your questions and accept merge requests if you find bugs or want to include features.
hapic is automatically tested on python 3.5, 3.6 and 3.7
## TODO references
TODOs in the code can include some `#xxx` - these are github issues references.
## Installation
For better performances with yaml module, you can install following (debian instruction):
sudo apt-get install libyaml-dev
`libyaml-dev` package can be removed after hapic install.
## From source code
``` bash
virtualenv -p /usr/bin/python3 venv
source venv/bin/activate
python setup.py develop
```
To work with Marshmallow schemas, install necessary dependencies:
pip install -e ".[marshmallow]"
To work with Serpyco dataclasses, install necessary dependencies:
pip install -e ".[serpyco]"
To have full environment (for developpers):
pip install -e ".[dev"]
## From pypi
To work with Marshmallow schemas, install necessary dependencies:
pip install hapic[marshmallow]
To work with Serpyco dataclasses, install necessary dependencies:
pip install hapic[serpyco]
## Give it a try
### short Flask example
``` python
from datetime import datetime
import flask
import marshmallow
import hapic
from hapic.ext.flask import FlaskContext
import json
hapic = hapic.Hapic()
app = flask.Flask(__name__)
class UriPathSchema(marshmallow.Schema): # schema describing the URI and allowed values
name = marshmallow.fields.String(required=True)
age = marshmallow.fields.Integer(required=False)
class HelloResponseSchema(marshmallow.Schema): # schema of the API response
name = marshmallow.fields.String(required=True)
now = marshmallow.fields.DateTime(required=False)
greetings = marshmallow.fields.String(required=False)
@app.route('/hello/<name>') # flask route. must always be before hapic decorators
@hapic.with_api_doc() # the first hapic decorator. Register the method for auto-documentation
@hapic.input_path(UriPathSchema()) # validate the URI structure
@hapic.output_body(HelloResponseSchema()) # define output structure
def hello(name='<No name>', hapic_data=None):
return {
'name': name,
'now': datetime.now(),
'dummy': { 'some': 'dummy' } # will be ignored
}
class UriPathSchemaWithAge(marshmallow.Schema): # schema describing the URI and allowed values
name = marshmallow.fields.String(required=True)
age = marshmallow.fields.Integer(required=False)
@app.route('/hello/<name>/age/<age>')
@hapic.with_api_doc()
@hapic.input_path(UriPathSchemaWithAge())
@hapic.output_body(HelloResponseSchema())
def hello2(name='<No name>', age=42, hapic_data=None):
return {
'name': name,
'age': age,
'greetings': 'Hello {name}, it looks like you are {age}'.format(
name=name,
age=age
),
'now': datetime.now(),
'dummy': { 'some': 'dummy' } # will be ignored
}
hapic.set_context(FlaskContext(app))
print(json.dumps(hapic.generate_doc(title='API Doc', description='doc desc.'))) # Generate the documentation
app.run('127.0.0.1', 8080, debug=True)
```
How to use it:
Nominal cases:
``` bash
$ curl "http://127.0.0.1:8080/hello/michel"
# {"now": "2017-12-18T12:37:10.751623+00:00", "name": "michel"}
```
``` bash
$ curl "http://127.0.0.1:8080/hello/michel/age/17"
# {"name": "damien", "greetings": "Hello damien, it looks like you are 17", "now": "2017-12-18T12:41:58.229679+00:00"}
```
Error case (returns a 400):
``` bash
$ curl "http://127.0.0.1:8080/hello/michel/age/mistaken"
# {"details": {"age": ["Not a valid integer."]}, "message": "Validation error of input data"}
```
### A complete user API
In the `example/usermanagement` directory you can find a complete example of an API allowing to manage users.
Features are:
- get list of all users
- get detail of a given user
- create a user
- delete a user
In order to test it :
Install the required dependencies:
``` bash
pip install bottle flask pyramid`
```
Run the instance you wan to test (one of the three following lines):
``` bash
python example/usermanagement/serve_bottle.py
python example/usermanagement/serve_flask.py
python example/usermanagement/serve_pyramid.py
```
Features shown :
- auto-generation of the documentation
- managing parameters in the uri path
- managing input schemas
- managing output schema
- management of error cases (404, 500, etc)
- nice exception handling
- automatic dict/object serialization
Raw data
{
"_id": null,
"home_page": "https://github.com/algoo/hapic",
"name": "hapic",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "http api validation",
"author": "Algoo Development Team",
"author_email": "contact@algoo.fr",
"download_url": "https://files.pythonhosted.org/packages/05/d2/844e43e29f68d6bc35c1ca2b119db6b8f10ccf81b9ed08c389a9086ccfea/hapic-0.98.tar.gz",
"platform": null,
"description": "[![Build Status](https://travis-ci.org/algoo/hapic.svg?branch=master)](https://travis-ci.org/algoo/hapic)\n[![Coverage Status](https://coveralls.io/repos/github/algoo/hapic/badge.svg?branch=master)](https://coveralls.io/github/algoo/hapic?branch=master)\n\n# hapic in a nutshell\n\nhapic is a framework-agnostic library for coding professionnal REST APIs.\n\n# Philosophy\n\nhapic as been developed by algoo in the context of a large service oriented project. The lack of a tool allowing real auto-documentation of Rest API has decided us to develop hapic.\n\ntarget usage is not for \"quick and dirty\" stuff but for professionnal, maintainable, long-term targeted projects.\n\nThe separation of concerns between REST APIs layer and business stuff layer is in the DNA of hapic.\n\nhapic is *just* the HTTP layer glue code over your business code.\n\n# Direct benefits of using hapic\n\nWhen you decide to base your development on hapic, you'll get direct benefits:\n\n## Ready-to-use\n\n- supports aiohttp, flask, pyramid and bottle \n- ready-to-use with your existing libraries\n- effortless mapping of exceptions to HTTP errors\n- serialisation based on marshmallow schemas or serpyco dataclasses\n\n## Full API documentation ready\n\n- your code *IS* the documentation\n- swagger generated documentation\n- embed the documentation in 1 line of code\n- supports python 3.5, 3.6 and 3.7 \n\n## Professionnal and maintanable source code\n\n- separation of concerns between business logic and HTTP stuff\n- very fast when used in conjunction with both aiohttp and serpyco\n- extensible framework for supporting other web framework and serialisation libraries\n\n# Licence\n\nhapic is licenced under the MIT licence. You can use it in your projects, closed or open sourced.\n\n## status, contributions\n\nhapic source code is ready for production. Some refactoring are identified and required for maintainability, but public APIs are stable so you can rely on hapic for your developments.\n\nhapic is under active development, based on different professional projects. we will answer your questions and accept merge requests if you find bugs or want to include features.\n\nhapic is automatically tested on python 3.5, 3.6 and 3.7\n\n## TODO references\n\nTODOs in the code can include some `#xxx` - these are github issues references.\n\n## Installation\n\nFor better performances with yaml module, you can install following (debian instruction):\n\n sudo apt-get install libyaml-dev\n\n`libyaml-dev` package can be removed after hapic install.\n\n## From source code\n\n``` bash\nvirtualenv -p /usr/bin/python3 venv\nsource venv/bin/activate\npython setup.py develop\n```\n\nTo work with Marshmallow schemas, install necessary dependencies:\n\n pip install -e \".[marshmallow]\"\n\nTo work with Serpyco dataclasses, install necessary dependencies:\n\n pip install -e \".[serpyco]\"\n\nTo have full environment (for developpers):\n\n pip install -e \".[dev\"]\n\n## From pypi\n\nTo work with Marshmallow schemas, install necessary dependencies:\n\n pip install hapic[marshmallow]\n\nTo work with Serpyco dataclasses, install necessary dependencies:\n\n pip install hapic[serpyco]\n \n## Give it a try\n\n### short Flask example\n\n``` python\nfrom datetime import datetime\nimport flask\nimport marshmallow\nimport hapic\nfrom hapic.ext.flask import FlaskContext\nimport json\n\nhapic = hapic.Hapic()\napp = flask.Flask(__name__)\n\n\nclass UriPathSchema(marshmallow.Schema): # schema describing the URI and allowed values\n name = marshmallow.fields.String(required=True)\n age = marshmallow.fields.Integer(required=False)\n\n\nclass HelloResponseSchema(marshmallow.Schema): # schema of the API response\n name = marshmallow.fields.String(required=True)\n now = marshmallow.fields.DateTime(required=False)\n greetings = marshmallow.fields.String(required=False)\n\n\n@app.route('/hello/<name>') # flask route. must always be before hapic decorators\n@hapic.with_api_doc() # the first hapic decorator. Register the method for auto-documentation\n@hapic.input_path(UriPathSchema()) # validate the URI structure\n@hapic.output_body(HelloResponseSchema()) # define output structure\ndef hello(name='<No name>', hapic_data=None):\n return {\n 'name': name,\n 'now': datetime.now(),\n 'dummy': { 'some': 'dummy' } # will be ignored\n }\n\nclass UriPathSchemaWithAge(marshmallow.Schema): # schema describing the URI and allowed values\n name = marshmallow.fields.String(required=True)\n age = marshmallow.fields.Integer(required=False)\n\n\n@app.route('/hello/<name>/age/<age>')\n@hapic.with_api_doc()\n@hapic.input_path(UriPathSchemaWithAge())\n@hapic.output_body(HelloResponseSchema())\ndef hello2(name='<No name>', age=42, hapic_data=None):\n return {\n 'name': name,\n 'age': age,\n 'greetings': 'Hello {name}, it looks like you are {age}'.format(\n name=name,\n age=age\n ),\n 'now': datetime.now(),\n 'dummy': { 'some': 'dummy' } # will be ignored\n }\n\n\nhapic.set_context(FlaskContext(app))\nprint(json.dumps(hapic.generate_doc(title='API Doc', description='doc desc.'))) # Generate the documentation\napp.run('127.0.0.1', 8080, debug=True)\n```\n\nHow to use it:\n\nNominal cases:\n\n``` bash\n$ curl \"http://127.0.0.1:8080/hello/michel\"\n# {\"now\": \"2017-12-18T12:37:10.751623+00:00\", \"name\": \"michel\"}\n```\n\n``` bash\n$ curl \"http://127.0.0.1:8080/hello/michel/age/17\"\n# {\"name\": \"damien\", \"greetings\": \"Hello damien, it looks like you are 17\", \"now\": \"2017-12-18T12:41:58.229679+00:00\"}\n```\n\nError case (returns a 400):\n\n``` bash\n$ curl \"http://127.0.0.1:8080/hello/michel/age/mistaken\"\n# {\"details\": {\"age\": [\"Not a valid integer.\"]}, \"message\": \"Validation error of input data\"}\n```\n\n\n### A complete user API\n\nIn the `example/usermanagement` directory you can find a complete example of an API allowing to manage users.\n\nFeatures are: \n\n- get list of all users\n- get detail of a given user\n- create a user\n- delete a user\n\nIn order to test it :\n\nInstall the required dependencies:\n\n``` bash\npip install bottle flask pyramid`\n```\n\nRun the instance you wan to test (one of the three following lines):\n\n``` bash\npython example/usermanagement/serve_bottle.py\npython example/usermanagement/serve_flask.py\npython example/usermanagement/serve_pyramid.py\n```\n\nFeatures shown :\n\n- auto-generation of the documentation\n- managing parameters in the uri path\n- managing input schemas\n- managing output schema\n- management of error cases (404, 500, etc)\n- nice exception handling\n- automatic dict/object serialization",
"bugtrack_url": null,
"license": "MIT",
"summary": "HTTP api input/output manager",
"version": "0.98",
"split_keywords": [
"http",
"api",
"validation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "05d2844e43e29f68d6bc35c1ca2b119db6b8f10ccf81b9ed08c389a9086ccfea",
"md5": "61666c817332bf93a0b892e6d7454f5e",
"sha256": "d9e05960dab04205ec2b6e3a252d0a6224313aa00e1ac28c504ab5a204b82655"
},
"downloads": -1,
"filename": "hapic-0.98.tar.gz",
"has_sig": false,
"md5_digest": "61666c817332bf93a0b892e6d7454f5e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 612944,
"upload_time": "2023-03-21T10:39:09",
"upload_time_iso_8601": "2023-03-21T10:39:09.036510Z",
"url": "https://files.pythonhosted.org/packages/05/d2/844e43e29f68d6bc35c1ca2b119db6b8f10ccf81b9ed08c389a9086ccfea/hapic-0.98.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-21 10:39:09",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "algoo",
"github_project": "hapic",
"travis_ci": true,
"coveralls": true,
"github_actions": false,
"lcname": "hapic"
}