Skip to main content

rAPIdy - write quickly - write beautifully

Project description

rAPIdy 💮

write quickly 🚀 write beautifully 🌸

rAPIdy is a minimalistic, asynchronous, fast web framework based in aiohttp and pydantic.

pip install rapidy

Key Features:

Quickstart

Create endpoint using RouteTableDef

rAPIdy inherits the basic functionality of aiohttp quickstart

from rapidy import web
from typing_extensions import Annotated

routes = web.RouteTableDef()


@routes.get('/hello')
async def hello(
        request: web.Request,
        username: Annotated[str, web.JsonBody(min_length=3, max_length=20)],
        password: Annotated[str, web.JsonBody(min_length=8, max_length=40)],
) -> web.Response:
  # write you business code here
  return web.json_response({'username': username, 'password': password})


app = web.Application()
app.add_routes(routes)

if __name__ == '__main__':
  web.run_app(app, port=8000)

Create endpoint using web.<method_name>

from rapidy import web
from typing_extensions import Annotated


async def hello(
        request: web.Request,
        username: Annotated[str, web.JsonBody(min_length=3, max_length=20)],
        password: Annotated[str, web.JsonBody(min_length=8, max_length=40)],
) -> web.Response:
  # write you business code here
  return web.json_response({'username': username, 'password': password})


app = web.Application()
app.add_routes([web.post('/hello', hello)])

if __name__ == '__main__':
  web.run_app(app, port=8000)

Create endpoint using web.view

from rapidy import web
from typing_extensions import Annotated


class Handler(web.View):
  async def post(
          self,
          username: Annotated[str, web.JsonBody(min_length=3, max_length=20)],
          password: Annotated[str, web.JsonBody(min_length=8, max_length=40)],
  ) -> web.Response:
    # write you business code here
    return web.json_response({'username': username, 'password': password})


app = web.Application()
app.add_routes([web.view('/hello', Handler)])

if __name__ == '__main__':
  web.run_app(app, port=8000)

Pydantic native support

from rapidy import web
from typing_extensions import Annotated


async def hello_handler(
        request: web.Request,
        username: Annotated[str, web.JsonBody(min_length=3, max_length=20)],
        password: Annotated[str, web.JsonBody(min_length=8, max_length=40)],
) -> web.Response:
  # write you business code here
  return web.json_response({'username': username, 'password': password})


app = web.Application()
app.add_routes([web.post('/hello', hello_handler)])
web.run_app(app, port=8000)

✅✅✅ Success request validation ✅✅✅

curl -X POST \
-H "Content-Type: application/json" -d '{"username": "Max", "password": "myAwesomePass"}' -v \
http://127.0.0.1:8000/hello

< HTTP/1.1 200 OK ... {"username": "Max", "password": "myAwesomePass"}

❌❌❌ Request validation failure ❌❌❌

curl -X POST \
-H "Content-Type: application/json" -d '{"username": "M", "password": "m"}' -v \
http://127.0.0.1:8000/hello

< HTTP/1.1 422 Unprocessable Entity ...
{
    "errors": [
        {
            "loc": ["body", "username"],
            "type": "string_too_short",
            "msg": "String should have at least 3 characters",
            "ctx": {"min_length": 3}
        },
        {
            "type": "string_too_short",
            "loc": ["body", "password"],
            "msg": "String should have at least 8 characters",
            "ctx": {"min_length": 8}
        }
    ]
}

Choose your path

  • You can create APIs the way you want.
  • rAPIdy supports 3 basic types for defining incoming parameters
    • 🌒 param
      • Path
      • Header
      • Cookie
      • Query
      • BodyJson
      • FormDataBody
      • MultipartBody
    • 🌕 schema
      • PathSchema
      • HeaderSchema
      • CookieSchema
      • QuerySchema
      • BodyJsonSchema
      • FormDataBodySchema
      • MultipartBodySchema
    • 🌑 raw data (no validate with pydantic)
      • PathRaw - Dict[str, str]
      • HeaderRaw - Dict[str, str]
      • CookieRaw - Dict[str, str]
      • QueryRaw - Dict[str, str]
      • BodyJsonRaw - Dict[str, Any]
      • FormDataBodyRaw - Dict[str, Any]
      • MultipartBodyRaw - Dict[str, Any]
      • TextBody - str
      • BytesBody - bytes
      • StreamBody - aiohttp.streams.StreamReader
# defining request attributes as param 🌒
from rapidy import web
from typing_extensions import Annotated


async def hello_handler(
        request: web.Request,
        # path params
        path_param: Annotated[str, web.Path],
        # headers
        host: Annotated[str, web.Header(alias='Host')],
        user_agent: Annotated[str, web.Header(alias='User-Agent')],
        # cookie
        user_cookie1: Annotated[str, web.Cookie(alias='UserCookie1')],
        user_cookie2: Annotated[str, web.Cookie(alias='UserCookie2')],
        # query params
        user_param1: Annotated[str, web.Query(alias='UserQueryParam1')],
        user_param2: Annotated[str, web.Cookie(alias='UserQueryParam2')],
        # body
        username: Annotated[str, web.JsonBody(min_length=3, max_length=20)],
        password: Annotated[str, web.JsonBody(min_length=8, max_length=40)],
) -> web.Response:
  # write you business code here
  # ...
  return web.Response()


app = web.Application()
app.add_routes([web.post('/hello/{path_param}', hello_handler)])
# defining request attributes as schema 🌕
from pydantic import BaseModel, Field

class PathRequestSchema(BaseModel):
    path_param: str

class HeaderRequestSchema(BaseModel):
    host: str = Field(alias='Host')
    user_agent: str = Field(alias='User-Agent')

class CookieRequestSchema(BaseModel):
    user_cookie1: str = Field(alias='UserCookie1')
    user_cookie2: str = Field(alias='UserCookie2')

class QueryRequestSchema(BaseModel):
    user_cookie1: str = Field(alias='UserQueryParam1')
    user_cookie2: str = Field(alias='UserQueryParam1')

class BodyRequestSchema(BaseModel):
    username: str = Field(min_length=3, max_length=20)
    password: str = Field(min_length=8, max_length=40)

async def hello_handler(
        request: web.Request,
        path: Annotated[PathRequestSchema, web.PathSchema],
        headers: Annotated[HeaderRequestSchema, web.HeaderSchema],
        cookies: Annotated[CookieRequestSchema, web.Cookie],
        query: Annotated[QueryRequestSchema, web.QuerySchema],
        body: Annotated[BodyRequestSchema, web.JsonBodySchema],
) -> web.Response:
# defining request attributes as raw 🌑
async def hello_handler(
        request: web.Request,
        path: Annotated[Dict[str, str], web.PathRaw],
        headers: Annotated[Dict[str, str], web.HeaderRaw],
        cookies: Annotated[Dict[str, str], web.CookieRaw],
        query: Annotated[Dict[str, str], web.QueryRaw],
        body: Annotated[Dict[str, Any], web.JsonBodyRaw],
) -> web.Response:
# also you may to combine 🌒 🌕 🌑
async def hello_handler(
        request: web.Request,
        path_param: Annotated[str, web.Path],
        headers: Annotated[Dict[str, str], web.HeaderRaw],
        body: Annotated[BodyRequestSchema, web.JsonBodySchema],
) -> web.Response:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rapidy-0.1.1.tar.gz (22.0 kB view hashes)

Uploaded Source

Built Distribution

rapidy-0.1.1-py3-none-any.whl (25.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page