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

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)

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

fastify-1.5.3.tar.gz (40.5 kB view details)

Uploaded Source

Built Distribution

fastify-1.5.3-py3-none-any.whl (52.2 kB view details)

Uploaded Python 3

File details

Details for the file fastify-1.5.3.tar.gz.

File metadata

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

File hashes

Hashes for fastify-1.5.3.tar.gz
Algorithm Hash digest
SHA256 744bd3df22a3e1c702ccc24e886b84b334dfd81446feb1d6cc357595698ddaf2
MD5 5d099efe578c74ab9c6821f379b27697
BLAKE2b-256 40c51efec7299a71753367611eb6f35573136955e23079668cf05617164ac421

See more details on using hashes here.

File details

Details for the file fastify-1.5.3-py3-none-any.whl.

File metadata

  • Download URL: fastify-1.5.3-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 fastify-1.5.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5b460239568bce660161217ef5a8e7d1c18d330ab4ab5b31107bc4ccc2e94806
MD5 0d61365f0eb6ad952676598f852beb06
BLAKE2b-256 01d9263a7a4f2084da73a1d49ac19ba7ce4d8ed871c1fcf08d4b5c755bab2ee2

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