Skip to content

Feat : Add Nexios Asgi Framework #9970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions frameworks/Python/nexios/READEME.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@

## `NEXIOS`

<div align="left">

<a href="https://git.io/typing-svg"><img src="https://readme-typing-svg.demolab.com?font=Fira+Code&pause=1000&color=4CAF50&center=true&width=435&lines=Nexios+ASGI+Framework;Fast%2C+Simple%2C+Flexible" alt="Typing SVG" /></a>

<p align="center">
<a href="">
<img alt=Support height="350" src="https://nexios-docs.netlify.app/icon.svg">
</p>
<h1 align="center">Nexios 2.4.x<br></h1>

</a>
</p>

<!-- Badges Section -->
<p align="center">
<img src="https://img.shields.io/badge/Python-3.9+-blue?logo=python" alt="Python Version">
<img src="https://img.shields.io/badge/Downloads-10k/month-brightgreen" alt="Downloads">
<img src="https://img.shields.io/badge/Contributions-Welcome-orange" alt="Contributions">
<img src="https://img.shields.io/badge/Active Development-Yes-success" alt="Active Development">
</p>

<p align="center">
<a href="https://github.com/nexios-labs/Nexios?tab=followers"><img title="Followers" src="https://img.shields.io/github/followers/nexios-labs?label=Followers&style=social"></a>
<a href="https://github.com/nexios-labs/Nexios/stargazers/"><img title="Stars" src="https://img.shields.io/github/stars/nexios-labs/Nexios?&style=social"></a>
<a href="https://github.com/nexios-labs/Nexios/network/members"><img title="Fork" src="https://img.shields.io/github/forks/nexios-labs/Nexios?style=social"></a>
<a href="https://github.com/nexios-labs/Nexios/watchers"><img title="Watching" src="https://img.shields.io/github/watchers/nexios-labs/Nexios?label=Watching&style=social"></a>


</br>

<h2 align="center"> Star the repo if u like it🌟
</h2>

Nexios is a high-performance Python web framework. Designed for speed, flexibility, and simplicity, Nexios delivers exceptional performance through its native Rust engine while maintaining the simplicity and elegance of Python. It supports RESTful APIs, authentication, and integrates easily with any ORM. Built for modern web development, Nexios allows developers to quickly spin up scalable, modular apps with minimal boilerplate—ideal for startups, rapid prototyping, and custom backend solutions. Think Django's capability with Rust-powered speed.

---


## `Installation` 📦

To install **Nexios**, you can use several methods depending on your environment and preferred package manager. Below are the instructions for different package managers:

### 1. **From `pip`** (Standard Python Package Manager)

```bash
pip install nexios
```


## Features ✨

- [x] **Routing**
- [x] **Automatic OpenAPI Documentation**
- [x] **Session Management**
- [x] **File Router**
- [x] **Authentication (Limited)**
- [x] **Event Listener for Signals**
- [x] **Middleware Support**
- [x] **Express-like Functionality**
- [x] **JWT Authentication**
- [x] **Pydantic Support**
- [x] **Dependency Injection**
- [x] **In-built Support for CORS**
- [x] **Custom Decorators**
- [x] **WebSocket Support**
- [x] **Custom Error Handling**
- [x] **Pagination**
- [x] **HTTP/2 Support**
- [x] **High-Performance Async Processing**

### Upcoming Features

- [ ] **Inbuilt Database ORM Integration**
- [ ] **Asynchronous Task Queue**
- [ ] **Rate Limiting**
- [ ] **API Throttling**

### Basic Example

```py
from nexios import NexiosApp
from nexios.http import Request, Response

app = NexiosApp()

@app.get("/")
async def basic(request: Request, response: Response):
return {"message": "Hello, world!"}
# return response.json({"message":"Hello, world!"}) ## This will work for more control


```

### Another Basic Example

```py
from nexios import NexiosApp, Depend
from nexios.http import Request, Response

app = NexiosApp()

async def get_user():
return {"name": "John Doe"}


@app.get("/users")
async def get_user(request: Request, response: Response, user: Depend(get_user)):

return {"user": user}
```

Visit http://localhost:4000/docs to view the Swagger API documentation.



### Testimonies

> "Adopting Nexios at our startup has been a practical and effective choice. In a fast-moving development environment, we needed something lightweight and efficient — Nexios met that need.
>
> Its clean architecture and compatibility with different ORMs helped our team work more efficiently and keep things maintainable. One of its strengths is how straightforward it is — minimal overhead, just the tools we need to build and scale our backend services.
>
> Credit to Dunamis for introducing Nexios to the team. It’s now a steady part of our stack, and it’s serving us well.
> — Joseph Mmadubuike , Chief Technology Officer buzzbuntu.com

## See the full docs

👉 <a href="https://nexios-docs.netlify.app">https://nexios-docs.netlify.app</a>

## Contributors:
<a href="https://github.com/nexios-labs/nexios/graphs/contributors">
<img src="https://contrib.rocks/image?repo=nexios-labs/nexios" />
</a>




61 changes: 61 additions & 0 deletions frameworks/Python/nexios/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Nexios Framework Benchmark

This directory contains the Nexios framework implementation for the TechEmpower Web Framework Benchmarks.

## About Nexios

Nexios is a modern, high-performance ASGI web framework that combines high performance with developer-friendly features. Built on proven design patterns while introducing modern capabilities like dependency injection, automatic OpenAPI documentation, and comprehensive middleware support.

## Test Implementations

This benchmark includes multiple server configurations:

- **default**: Nexios with Uvicorn (standard configuration)
- **gunicorn**: Nexios with Gunicorn server
- **uvicorn**: Nexios with Uvicorn ASGI server
- **granian**: Nexios with Granian server (Rust-based ASGI server)
- **socketify-asgi**: Nexios with Socketify ASGI server (C++-based)

## Benchmark Tests

- **JSON**: Simple JSON serialization
- **DB**: Single database query
- **Queries**: Multiple database queries (1-500)
- **Fortunes**: HTML template rendering with database data
- **Updates**: Database updates with multiple queries
- **Plaintext**: Simple text response

## Running the Benchmarks

```bash
# Build all images
./run_benchmarks.sh

# Run individual containers
docker run -p 8080:8080 nexios-gunicorn
docker run -p 8080:8080 nexios-uvicorn
docker run -p 8080:8080 nexios-granian
docker run -p 8080:8080 nexios-socketify
```

## Configuration

- **Database**: PostgreSQL with connection pooling
- **Workers**: CPU count optimized
- **Port**: 8080 (standard for TechEmpower)
- **Host**: 0.0.0.0 (bind to all interfaces)
- **Logging**: Error level only for performance

## Framework Comparison

Nexios vs FastAPI:
- Similar ASGI foundation
- Built-in dependency injection
- Automatic OpenAPI documentation
- Comprehensive middleware system
- WebSocket support
- Pydantic integration

## License

This benchmark implementation is part of the TechEmpower Web Framework Benchmarks project.
158 changes: 158 additions & 0 deletions frameworks/Python/nexios/app-granian.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import multiprocessing
import os
import random
from contextlib import asynccontextmanager

import asyncpg
from nexios import NexiosApp, MakeConfig



READ_ROW_SQL = 'SELECT "id", "randomnumber" FROM "world" WHERE id = $1'
WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2'
ADDITIONAL_ROW = [0, "Additional fortune added at request time."]
MAX_POOL_SIZE = 1000 // multiprocessing.cpu_count()
MIN_POOL_SIZE = max(int(MAX_POOL_SIZE / 2), 1)

connection_pool = None


def get_num_queries(queries):
try:
query_count = int(queries)
except (ValueError, TypeError):
return 1

if query_count < 1:
return 1
if query_count > 500:
return 500
return query_count


async def setup_database():
return await asyncpg.create_pool(
user=os.getenv("PGUSER", "benchmarkdbuser"),
password=os.getenv("PGPASS", "benchmarkdbpass"),
database="hello_world",
host="tfb-database",
port=5432,
min_size=MIN_POOL_SIZE,
max_size=MAX_POOL_SIZE,
)


@asynccontextmanager
async def lifespan(app: NexiosApp):
# Setup the database connection pool
global connection_pool
connection_pool = await setup_database()
yield
# Close the database connection pool
await connection_pool.close()


# Create Nexios app with lifespan optimized for Granian
app = NexiosApp(
config=MakeConfig({
"debug": False,
"openapi": {
"enabled": False
}
}),
lifespan=lifespan
)


@app.get("/json")
async def json_serialization(request, response):
return response.json({"message": "Hello, world!"})


@app.get("/db")
async def single_database_query(request, response):
row_id = random.randint(1, 10000)
async with connection_pool.acquire() as connection:
number = await connection.fetchval(READ_ROW_SQL, row_id)

return response.json({"id": row_id, "randomNumber": number})


@app.get("/queries")
async def multiple_database_queries(request, response):
queries = request.query_params.get("queries")
num_queries = get_num_queries(queries)
row_ids = random.sample(range(1, 10000), num_queries)
worlds = []

async with connection_pool.acquire() as connection:
statement = await connection.prepare(READ_ROW_SQL)
for row_id in row_ids:
number = await statement.fetchval(row_id)
worlds.append({"id": row_id, "randomNumber": number})

return response.json(worlds)


@app.get("/fortunes")
async def fortunes(request, response):
async with connection_pool.acquire() as connection:
fortunes = await connection.fetch("SELECT * FROM Fortune")

fortunes.append(ADDITIONAL_ROW)
fortunes.sort(key=lambda row: row[1])

# Render fortune template
html_content = """
<!DOCTYPE html>
<html>
<head><title>Fortunes</title></head>
<body>
<table>
<tr><th>id</th><th>message</th></tr>
"""

for fortune in fortunes:
html_content += f"<tr><td>{fortune[0]}</td><td>{fortune[1]}</td></tr>"

html_content += """
</table>
</body>
</html>
"""

return response.html(html_content)


@app.get("/updates")
async def database_updates(request, response):
queries = request.query_params.get("queries")
num_queries = get_num_queries(queries)
# To avoid deadlock
ids = sorted(random.sample(range(1, 10000 + 1), num_queries))
numbers = sorted(random.sample(range(1, 10000), num_queries))
updates = list(zip(ids, numbers))

worlds = [
{"id": row_id, "randomNumber": number} for row_id, number in updates
]

async with connection_pool.acquire() as connection:
statement = await connection.prepare(READ_ROW_SQL)
for row_id, _ in updates:
await statement.fetchval(row_id)
await connection.executemany(WRITE_ROW_SQL, updates)

return response.json(worlds)


@app.get("/plaintext")
async def plaintext(request, response):
return response.text("Hello, world!")


if __name__ == "__main__":
# Granian will be called from the command line
# This is just for development/testing
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8080)
Loading
Loading