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
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)
Built Distribution
fastipy-1.5.4-py3-none-any.whl
(52.2 kB
view details)
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6bcda22b54f1548b97026eb7c98954a354e96531215206b7ead738af831433ec |
|
MD5 | fa2b2b7ed716bb7ba307a8a1099f5b7f |
|
BLAKE2b-256 | aa45ba82180bff27c32ed5225eac7c1d7743cd8aecf4ade12396984b9d26396c |
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | e679b3ee54b2f87889c618991a22e1613623e170f7f7a2655cf6fdd277fa1a1b |
|
MD5 | dfb2e8baaea9029bf7df1693e8bf119b |
|
BLAKE2b-256 | b146b52bdf8e96fb354ba2cbdb47ba672f9de515f50185b92805941b27424f0d |