Thunderlight is the fastest Python HTTP Server. It's dedicated for micro service and JSON API. In the future, a C version of this API is also supported. You can write Python or C in your server project to speed things up.
Install Thunderlight with pip
.
pip install thunderlight
Register a get request handler to the default app.
@get('/posts/:id')
async def posts(ctx: Ctx) -> None:
ctx.res.json((await Post.id(ctx.req.args.id)).tojson())
Register a post request handler to the default app.
@post('/posts')
async def posts(ctx: Ctx) -> None:
ctx.res.json(Post(**(await ctx.req.json())).save().tojson())
Register a patch request handler to the default app.
@patch('/posts/:id')
async def posts(ctx: Ctx) -> None:
ctx.res.json((await Post.id(ctx.req.args.id)).set(await ctx.req.json()).save().tojson())
Register a delete request handler to the default app.
@delete('/posts/:id')
async def posts(ctx: Ctx) -> None:
ctx.res.empty((await Post.id(ctx.req.args.id)).delete())
Append this middleware to the default app's middleware stack.
@use
async def measure_time(ctx: Ctx, next: Next) -> None:
start = time()
await next(ctx)
time_elapsed = time() - start
print(f'request {ctx.req.path} takes {time_elapsed} second.')
Apply a middleware to a request handler. This is aka middleware for a single request handler.
async def validate_user(ctx: Ctx, next: Next) -> None:
if ctx.req.headers['Authorization'] is not None:
await next(ctx)
else:
ctx.res.code = 401
ctx.res.json({"error": {"type": "Unauthorized"}})
@get('/users')
@apply(validate_user)
async def users(ctx: Ctx) -> None:
ctx.res.json(await User.find())
Create a new server application.
app = App()
@app.get('/articles')
async def articles(ctx: Ctx) -> None:
ctx.res.json(await Article.find())
The context represents a request session.
The request object. This object is readonly.
The response object. Modify this object to present data to the user.
The custom state object that is internal to your custom handling code.
This class represents the incoming request. This object is readonly.
The request client.
The request HTTP scheme.
The request HTTP version.
The request HTTP method.
The path of the request URL.
The args matched from url routing.
The query string of the request URL.
The request headers.
The raw request body.
The request's json body.
The request's form body.
The request's json body or form body.
The class represents the response returned to the frontend.
The status code.
The response headers.
The response body.
Response json to the frontend.
Response text to the frontend
Response html text to the frontend
Response a redirect request to the frontend
Response a file to the frontend
Empty response
You can attach anything to the state and fetch by key. This state shares the same state across middlewares and the route handler.
@app.get('/articles')
async def articles(ctx: Ctx) -> None:
ctx.state.user = custom_user
ctx.state.user # custom_user
- Added generic response headers
- Added wildcard URL route matching
- Added static file serving
- Temporarily add static file
- Revert to Python implementation as the C implementation is not stable
- Fixed a bug that causes patch and delete requests to crash
- Fixed a bug that causes errors in handlers not propagated
- Add
__contains__
method toReqHeaders
- Fixed a bug that would cause delete routes crashing
- Remove uvicorn and related dependencies
- Rewrite with C
- Fix req.json property
- Global methods added:
get
,post
,patch
,delete
,use
andapply
. - Classes added:
App
,Ctx
,Req
,Res
,State
. - Function definition added:
Handler
,Next
andMiddleware
. - Global helper methods added:
main
,gimme
andmake
.