Quickstart
Creating Simple Handlers
rAPIdy
is based on
aiohttp
and supports all types of handler definitions.
Below, only the main types will be shown.
You can check all the available definitions here
Functional Handlers
from rapidy import Rapidy
from rapidy.http import post
@post('/')
async def handler() -> dict[str, str]:
return {'hello': 'rapidy'}
rapidy = Rapidy(http_route_handlers=[handler])
Registration without decorator
Class-based Handlers
from rapidy import Rapidy
from rapidy.http import PathParam, controller, get, post, put, patch, delete
@controller('/')
class UserController:
@get('/{user_id}')
async def get_by_id(self, user_id: str = PathParam()) -> dict[str, str]:
return {'user_id': user_id}
@get()
async def get_all_users(self) -> list[dict[str, str]]:
return [{'name': 'John'}, {'name': 'Felix'}]
@post()
async def create_user(self) -> str:
return 'ok'
@put()
async def update_user(self) -> str:
return 'ok'
@patch()
async def patch_user(self) -> str:
return 'ok'
@delete()
async def delete_user(self) -> str:
return 'ok'
rapidy = Rapidy(http_route_handlers=[UserController])
Registration without decorator
from rapidy import Rapidy
from rapidy.http import PathParam, controller, get
class UserController:
@get('/{user_id}')
async def get_by_id(self, user_id: str = PathParam()) -> dict[str, str]:
return {'user_id': user_id}
@get()
async def get_all_users(self) -> list[dict[str, str]]:
return [{'name': 'John'}, {'name': 'Felix'}]
rapidy = Rapidy(
http_route_handlers=[
controller.reg('/', UserController),
]
)
Middleware
Middleware are intermediate components that handle requests and responses at the web framework level.
They allow performing additional actions before and/or after the request is processed by the main handler.
from rapidy import Rapidy
from rapidy.http import Request, StreamResponse, get, middleware
from rapidy.typedefs import CallNext
@middleware
async def hello_middleware(request: Request, call_next: CallNext) -> StreamResponse:
request['data'] = {'hello': 'rapidy'}
return await call_next(request)
@get('/')
async def handler(request: Request) -> dict[str, str]:
return request['data']
rapidy = Rapidy(
http_route_handlers=[handler],
middlewares=[hello_middleware],
)
Note
In the middleware handler, the first argument should always be the Request, and the second — call_next.
HTTPRoute
HTTPRoute
allows you to register groups of handlers and plays a key role in routing,
helping to direct requests to the appropriate handlers based on the HTTP method, path, parameters, and other conditions.
HTTPRoute
is registered in exactly the same way as any HTTP handler.
from rapidy import Rapidy
from rapidy.http import HTTPRouter, controller, get
@get('/hello')
async def hello_handler() -> dict[str, str]:
return {'hello': 'rapidy'}
@controller('/hello_controller')
class HelloController:
@get()
async def get_hello(self) -> dict[str, str]:
return {'hello': 'rapidy'}
api_router = HTTPRouter('/api', [hello_handler, HelloController])
rapidy = Rapidy(http_route_handlers=[api_router])
Registering handlers in the router without a decorator
from rapidy import Rapidy
from rapidy.http import HTTPRouter, controller, get
async def hello_handler() -> dict[str, str]:
return {'hello': 'rapidy'}
class HelloController:
@get()
async def get_hello(self) -> dict[str, str]:
return {'hello': 'rapidy'}
api_router = HTTPRouter(
'/api',
[
get.reg('/hello', hello_handler),
controller.reg('/hello_controller', HelloController),
]
)
rapidy = Rapidy(http_route_handlers=[api_router])
Full example of registering a router and handlers
from rapidy import Rapidy
from rapidy.http import controller, get, HTTPRouter
@get('/hello')
async def hello_handler() -> dict[str, str]:
return {'hello': 'rapidy'}
@controller('/hello_controller')
class HelloController:
@get()
async def get(self) -> dict[str, str]:
return {'hello': 'rapidy'}
@get('/hi')
async def hi_handler() -> dict[str, str]:
return {'hi': 'rapidy'}
@controller('/hi_controller')
class HiController:
@get()
async def get(self) -> dict[str, str]:
return {'hi': 'rapidy'}
hello_api_router = HTTPRouter('/hello_api', [hello_handler, HelloController])
rapidy = Rapidy(
http_route_handlers=[
hello_api_router,
hi_handler,
HiController,
]
)
Simple Validation Example
from pydantic import BaseModel
from rapidy import Rapidy
from rapidy.http import Body, Request, Header, StreamResponse, middleware, post
from rapidy.typedefs import CallNext
TOKEN_REGEXP = '^[Bb]earer (?P<token>[A-Za-z0-9-_=.]*)'
class RequestBody(BaseModel):
username: str
password: str
class ResponseBody(BaseModel):
hello: str = 'rapidy'
@middleware
async def get_bearer_middleware(
request: Request,
call_next: CallNext,
bearer_token: str = Header(alias='Authorization', pattern=TOKEN_REGEXP),
) -> StreamResponse:
# process token here ...
return await call_next(request)
@post('/')
async def handler(body: RequestBody = Body()) -> ResponseBody:
return ResponseBody()
app = Rapidy(middlewares=[get_bearer_middleware], http_route_handlers=[handler])
Running the Web Server
Simple Start
Copy the code into the main.py
file.
from rapidy import Rapidy, run_app
from rapidy.http import post
@post('/')
async def handler() -> dict[str, str]:
return {'hello': 'rapidy'}
rapidy = Rapidy()
rapidy.add_http_router(handler)
if __name__ == '__main__':
run_app(rapidy)
Run the server in real-time mode:
You can also specify various startup parameters, such as host
or port
.
WSGI Start (Gunicorn)
Gunicorn is a Python WSGI HTTP server for UNIX.
What is WSGI
WSGI (Web Server Gateway Interface) is a simple and universal interface between the Web server and the Web application, first described in PEP-333.
More about gunicorn.org
Add Gunicorn to your project:
Copy the code into the main.py
file.
from rapidy import Rapidy
from rapidy.http import post
@post('/')
async def handler() -> dict[str, str]:
return {'hello': 'rapidy'}
rapidy = Rapidy()
rapidy.add_http_router(handler)
Run the command in the terminal:
The gunicorn main:rapidy
command accesses:
main
: themain.py
file (Python module).rapidy
: an object created inside themain.py
file in linerapidy = Rapidy()
.--reload
: restarts the server after the code is modified. Use only for development.