Skip to main content

Fastipy is a fast and easy-to-use open source Python library for developing RESTful APIs. Inspired by the FastAPI and Fastify syntax and powered by uvicorn ASGI web server.

Project description

Fastipy

CI codecov PyPI version

What is it and what is it for

Fastipy is a fast and easy-to-use open source Python library for developing RESTful APIs.

Powered by uvicorn

Installation

pip install fastipy

Examples

Example for GET Route with Query Params

from fastipy import Fastipy, Request, Reply

app = Fastipy()

# Routes can be async or sync functions, but reply send functions are async
# The handler returns the default HTTP status code 200
@app.get("/")
def home(req: Request, _):
  # Get query params age
  age = req.query["age"]
  # Example: Recovery all persons from database with this age and print the html
  print("<h1>Retrieving all persons</h1><ul><li>A Person</li></ul>")

Example for GET Route with Params, CORS and multiple methods

from fastipy import Fastipy, Request, Reply

app = Fastipy().cors()

@app.get("/user/:id")
@app.post("/user/:id")
async def getUser(req: Request, reply: Reply):
  # get users from database
  for i in users:
    if i["id"] == req.params["id"]:
      # All response functions are asynchronous
      return await reply.send(i)

  await reply.send_code(404)

Example for POST Route with Body

from fastipy import Fastipy, Request, Reply

app = Fastipy()

@app.post("/user")
async def createUser(req: Request, reply: Reply):
  user = req.body.json
  # Save user in database
  await reply.code(201).send("Created")

Example for PUT Route with Body

from fastipy import Fastipy, Request, Reply

app = Fastipy()

@app.put("/user")
async def createUser(req: Request, reply: Reply):
  user = req.body.json
  # Update user in database
  await reply.type("text/html").code(201).send("<h1>Created</h1>")

Example for GET Route with file stream

from fastipy import Fastipy, Request, Reply

app = Fastipy()

@app.get("/stream")
async def streamFile(_, reply: Reply):
  # It could be an asynchronous generator
  def generator():
    with open("file.txt") as f:
        for line in f:
            yield line

  await reply.send(generator())

Adding custom serializer to Reply send

from fastipy import Fastipy, Request, Reply

app = Fastipy()

app.add_serializer(
    validation=lambda data: isinstance(data, str),
    serializer=lambda data: ("application/json", json.dumps({"error": data})),
)

@app.get("/")
async def customSerializer(_, reply: Reply):
    await reply.code(404).send("Field not found")

Running

Running Fastipy application in development is easy

import uvicorn

if __name__ == "__main__":
  # main:app indicates the FILE:VARIABLE

  # The file is the main file where Fastipy() is instantiated
  # The variable is the name of the variable that contains the instance of Fastipy()

  # You can find more configurations here https://www.uvicorn.org/

  # set reload to True for automatic reloading!
  uvicorn.run("main:app", log_level="debug", port=8000, reload=True, loop="asyncio")

See more examples in examples folder

Creating plugins

# chat.py
from fastipy import FastipyInstance, Reply

# Plugins can be asynchronous or synchronized functions
# Plugins have access to the main instance, which means they can use all of Fastipy's functions
def chatRoutes(app: FastipyInstance, options: dict):
  @app.get("/")
  async def index(_, reply: Reply):
    await reply.send_code(200)

  @app.get("/chat")
  async def test(_, reply: Reply):
    await reply.send_code(200)
# message.py
from fastipy import FastipyInstance, Reply

async def messageRoutes(app: FastipyInstance, options: dict):
  @message.get("/")
  async def index(_, reply: Reply):
    await reply.send_code(200)

  @message.get("/message")
  async def test(_, reply: Reply):
    await reply.send_code(200)

  app.name("custom plugin name")
# main.py
from fastipy import Fastipy

from message import messageRoutes
from chat import chatRoutes

app = Fastipy().cors()

app.register(messageRoutes, {"prefix": "/message"})
app.register(chatRoutes, {"prefix": "/chat"})

Hooks

from fastipy import Fastipy, Request, Reply

app = Fastipy()

# The preHandler hook is called before the request handler
@app.hook("preHandler")
def preHandler(req: Request, reply: Reply):
  print("onRequest hook")

# The onRequest hook is called when the request is handled
@app.hook("onRequest")
def onRequest(req: Request, reply: Reply):
  print("onRequest hook")

# The onResponse hook is called when the reply sends a response
@app.hook("onResponse")
def onResponse(req: Request, reply: Reply):
  print("onResponse hook")

# The onError hook is called when an error occurs
@app.hook("onError")
def onError(error: Exception, req: Request, reply: Reply):
  print(f"onError hook exception: {error}")

# A hook will only be linked to a route if its declaration precedes the route
# The order of hooks of the same type is important
@app.get("/")
async def index(_, reply: Reply):
  await reply.send_code(200)

End to End tests

# See more in https://www.starlette.io/testclient/
from fastipy import TestClient
from main import app

client = TestClient(app)

response = client.post("/")
assert response.status_code == 200
assert response.text == "Hello World"

Application Deploy

For production deployment, please refer to this uvicorn guide.

Change Log

Development Version 1.5.4

Todo

Added

  • CI with Github Actions.
  • Code Coverage with Codecov.

Changed

  • Change the routes handler to use the Raw Path instead of the Path (This Change allow the use of %20 %2F and other special characters in the path).
  • Improve functionality to handle asynchronous functions in synchronous environments (This change probably fix Memory Leak in the Fastipy).

Fixed

  • Fix the bug in the search route where special characters are not being URL-escaped.

Contributors

How to Contributing

Open pull request

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

fastipy-1.5.4.tar.gz (40.6 kB view details)

Uploaded Source

Built Distribution

fastipy-1.5.4-py3-none-any.whl (52.2 kB view details)

Uploaded Python 3

File details

Details for the file fastipy-1.5.4.tar.gz.

File metadata

  • Download URL: fastipy-1.5.4.tar.gz
  • Upload date:
  • Size: 40.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.4 CPython/3.12.5 Windows/11

File hashes

Hashes for fastipy-1.5.4.tar.gz
Algorithm Hash digest
SHA256 6bcda22b54f1548b97026eb7c98954a354e96531215206b7ead738af831433ec
MD5 fa2b2b7ed716bb7ba307a8a1099f5b7f
BLAKE2b-256 aa45ba82180bff27c32ed5225eac7c1d7743cd8aecf4ade12396984b9d26396c

See more details on using hashes here.

File details

Details for the file fastipy-1.5.4-py3-none-any.whl.

File metadata

  • Download URL: fastipy-1.5.4-py3-none-any.whl
  • Upload date:
  • Size: 52.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.4 CPython/3.12.5 Windows/11

File hashes

Hashes for fastipy-1.5.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e679b3ee54b2f87889c618991a22e1613623e170f7f7a2655cf6fdd277fa1a1b
MD5 dfb2e8baaea9029bf7df1693e8bf119b
BLAKE2b-256 b146b52bdf8e96fb354ba2cbdb47ba672f9de515f50185b92805941b27424f0d

See more details on using hashes here.

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