# Endpoints
_Endpoints_ is a lightweight REST api framework written in python that supports both WSGI and ASGI. _Endpoints_ has been used in multiple production systems that handle millions of requests daily.
## Getting Started
### Installation
First, install endpoints with the following command.
$ pip install endpoints
If you want the latest and greatest you can also install from source:
$ pip install -U "git+https://github.com/jaymon/endpoints#egg=endpoints"
### Create a Controller Module
Create a controller file with the following command:
$ touch controllers.py
Add the following code to the `controllers.py` file:
```python
from endpoints import Controller
class Default(Controller):
"""The special class `Default` handles / requests"""
async def GET(self):
return "Default handler"
async def POST(self, **kwargs):
return 'hello {}'.format(kwargs['name'])
class Foo(Controller):
"""This class handles `/foo` requests"""
async def GET(self):
return "Foo handler"
```
### Start a WSGI Server
Now that you have your `controllers.py`, let's use the built-in WSGI server to serve them, we'll set our `controllers.py` file as the [controller prefix](docs/PREFIXES.md) so Endpoints will know where to find the [Controller classes](docs/CONTROLLERS.md) we just defined:
$ endpoints --prefix=controllers --host=localhost:8000
### Start an ASGI Server
Install [Daphne](https://github.com/django/daphne):
$ pip install -U daphne
And start it:
$ ENDPOINTS_PREFIX=controllers daphne -b localhost -p 8000 -v 3 endpoints.interface.asgi:Application.factory
### Test it out
Using curl:
$ curl http://localhost:8000
"Default handler"
$ curl http://localhost:8000/foo
"Foo handler"
$ curl http://localhost:8000/ -d "name=Awesome you"
"hello Awesome you"
That's it!
In the ***first request*** (`/`), the `controllers` module was accessed, then the `Default` class, and then the `GET` method.
In the ***second request*** (`/foo`), the `controllers` module was accessed, then the `Foo` class as specified in the path of the url, and then the `GET` method.
Finally, in the ***last request***, the `controllers` module was accessed, then the `Default` class, and finally the `POST` method with the passed in argument.
## How does it work?
*Endpoints* translates requests to python modules without any configuration.
It uses the following convention.
<HTTP-METHOD> /<MODULE-PATH>/<CLASS-PATH>/<POSITIONAL-ARGUMENTS>?<KEYWORD-ARGUMENTS>
_Endpoints_ will use the prefix module path you set as a reference point (either passed in via the environment variable `ENDPOINTS_PREFIX` or passed into the `Application(controller_prefix=...)` instance) to find the correct submodule using the path specified by the request.
Requests are translated from the left bit to the right bit of the path.
So for the path `/foo/bar/che/baz`, endpoints would first check for the `<PREFIX>.foo` module, then the `<PREFIX>.foo.bar` module, then the `<PREFIX>.foo.bar.che` module, etc. until it fails to find a valid module.
Once the module is found, endpoints will then attempt to find the class with the remaining path parts. If no matching class is found then a class named `Default` will be used if it exists.
Once if finds the class, it will use the `<HTTP-METHOD>` (eg, `GET`) to decide what method on the found class to call.
This makes it easy to bundle your controllers into a `controllers` package/module.
## Learn more about Endpoints
The [docs](https://github.com/jaymon/endpoints/tree/master/docs) contain more information about how _Endpoints_ works and what can be done with it.
Raw data
{
"_id": null,
"home_page": null,
"name": "endpoints",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "asgi, asgi-server, wsgi, wsgi-server, api, api-server, server, framework, web-framework, REST, rest-api",
"author": null,
"author_email": "Jay Marcyes <jay@marcyes.com>",
"download_url": "https://files.pythonhosted.org/packages/88/e1/7e4e9c69dbdd4f35c36f3aca72d6f9fa85c978732c40f4faac7da4ac6d3e/endpoints-9.1.0.tar.gz",
"platform": null,
"description": "# Endpoints\n\n_Endpoints_ is a lightweight REST api framework written in python that supports both WSGI and ASGI. _Endpoints_ has been used in multiple production systems that handle millions of requests daily.\n\n\n## Getting Started\n\n### Installation\n\nFirst, install endpoints with the following command.\n\n $ pip install endpoints\n\nIf you want the latest and greatest you can also install from source:\n\n $ pip install -U \"git+https://github.com/jaymon/endpoints#egg=endpoints\"\n\n\n### Create a Controller Module\n\nCreate a controller file with the following command:\n\n $ touch controllers.py\n\nAdd the following code to the `controllers.py` file:\n\n```python\nfrom endpoints import Controller\n\nclass Default(Controller):\n \"\"\"The special class `Default` handles / requests\"\"\"\n async def GET(self):\n return \"Default handler\"\n\n async def POST(self, **kwargs):\n return 'hello {}'.format(kwargs['name'])\n\nclass Foo(Controller):\n \"\"\"This class handles `/foo` requests\"\"\"\n async def GET(self):\n return \"Foo handler\"\n```\n\n\n### Start a WSGI Server\n\nNow that you have your `controllers.py`, let's use the built-in WSGI server to serve them, we'll set our `controllers.py` file as the [controller prefix](docs/PREFIXES.md) so Endpoints will know where to find the [Controller classes](docs/CONTROLLERS.md) we just defined:\n\n $ endpoints --prefix=controllers --host=localhost:8000\n\n\n### Start an ASGI Server\n\nInstall [Daphne](https://github.com/django/daphne):\n\n $ pip install -U daphne\n\nAnd start it:\n\n $ ENDPOINTS_PREFIX=controllers daphne -b localhost -p 8000 -v 3 endpoints.interface.asgi:Application.factory\n\n\n### Test it out\n\nUsing curl:\n\n $ curl http://localhost:8000\n \"Default handler\"\n $ curl http://localhost:8000/foo\n \"Foo handler\"\n $ curl http://localhost:8000/ -d \"name=Awesome you\"\n \"hello Awesome you\"\n\nThat's it!\n\nIn the ***first request*** (`/`), the `controllers` module was accessed, then the `Default` class, and then the `GET` method.\n\nIn the ***second request*** (`/foo`), the `controllers` module was accessed, then the `Foo` class as specified in the path of the url, and then the `GET` method.\n\nFinally, in the ***last request***, the `controllers` module was accessed, then the `Default` class, and finally the `POST` method with the passed in argument.\n\n\n## How does it work?\n\n*Endpoints* translates requests to python modules without any configuration.\n\nIt uses the following convention.\n\n <HTTP-METHOD> /<MODULE-PATH>/<CLASS-PATH>/<POSITIONAL-ARGUMENTS>?<KEYWORD-ARGUMENTS>\n\n_Endpoints_ will use the prefix module path you set as a reference point (either passed in via the environment variable `ENDPOINTS_PREFIX` or passed into the `Application(controller_prefix=...)` instance) to find the correct submodule using the path specified by the request.\n\nRequests are translated from the left bit to the right bit of the path.\nSo for the path `/foo/bar/che/baz`, endpoints would first check for the `<PREFIX>.foo` module, then the `<PREFIX>.foo.bar` module, then the `<PREFIX>.foo.bar.che` module, etc. until it fails to find a valid module.\n\nOnce the module is found, endpoints will then attempt to find the class with the remaining path parts. If no matching class is found then a class named `Default` will be used if it exists.\n\nOnce if finds the class, it will use the `<HTTP-METHOD>` (eg, `GET`) to decide what method on the found class to call.\n\nThis makes it easy to bundle your controllers into a `controllers` package/module.\n\n\n## Learn more about Endpoints\n\nThe [docs](https://github.com/jaymon/endpoints/tree/master/docs) contain more information about how _Endpoints_ works and what can be done with it.\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Get an api up and running quickly",
"version": "9.1.0",
"project_urls": {
"Homepage": "https://github.com/Jaymon/endpoints",
"Repository": "https://github.com/Jaymon/endpoints"
},
"split_keywords": [
"asgi",
" asgi-server",
" wsgi",
" wsgi-server",
" api",
" api-server",
" server",
" framework",
" web-framework",
" rest",
" rest-api"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "0675a4ea795fe9999033542e95c086497f63ee353a61f6e8f6d044544ccfcc90",
"md5": "530bde7247c0deb6a714af30ed39dbda",
"sha256": "f38f81f19e4f6133cd7b02617deb4c9e340eb7a51cb238968b0ccb2f6a813a30"
},
"downloads": -1,
"filename": "endpoints-9.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "530bde7247c0deb6a714af30ed39dbda",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 76202,
"upload_time": "2025-10-13T23:54:13",
"upload_time_iso_8601": "2025-10-13T23:54:13.073756Z",
"url": "https://files.pythonhosted.org/packages/06/75/a4ea795fe9999033542e95c086497f63ee353a61f6e8f6d044544ccfcc90/endpoints-9.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "88e17e4e9c69dbdd4f35c36f3aca72d6f9fa85c978732c40f4faac7da4ac6d3e",
"md5": "04141588aa4e25ea00351785c320b5fe",
"sha256": "f8dccfdd1c78073e0f1ee1382d6c01079cc09afa7828b42d27fc605776f90d19"
},
"downloads": -1,
"filename": "endpoints-9.1.0.tar.gz",
"has_sig": false,
"md5_digest": "04141588aa4e25ea00351785c320b5fe",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 68841,
"upload_time": "2025-10-13T23:54:14",
"upload_time_iso_8601": "2025-10-13T23:54:14.809183Z",
"url": "https://files.pythonhosted.org/packages/88/e1/7e4e9c69dbdd4f35c36f3aca72d6f9fa85c978732c40f4faac7da4ac6d3e/endpoints-9.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-13 23:54:14",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Jaymon",
"github_project": "endpoints",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "endpoints"
}