# Agni API
A unified REST API framework that combines the best features of Flask and FastAPI with built-in Model Context Protocol (MCP) support.
## Features
### ๐ฅ **Unified Framework**
- **Flask-style** blueprints and routing
- **FastAPI-style** async support and type hints
- **Seamless integration** between sync and async code
- **Automatic API documentation** with OpenAPI/Swagger
### โก **High Performance**
- Full async/await support
- ASGI and WSGI compatibility
- Optimized request handling
- Built-in middleware system
### ๐ค **Built-in MCP Support**
- **MCP Server** capabilities out of the box
- **MCP Client** for connecting to other servers
- **Easy tool registration** with decorators
- **Resource and prompt management**
### ๐ก๏ธ **Security First**
- OAuth2, JWT, and API key authentication
- Built-in security schemes
- CORS, HTTPS redirect, and trusted host middleware
- Password hashing utilities
### ๐งช **Developer Experience**
- **Type hints** throughout
- **Dependency injection** system
- **WebSocket** support
- **Testing utilities** for both sync and async
- **CLI tools** for development
## Quick Start
### Installation
```bash
pip install agniapi
```
For MCP support:
```bash
pip install agniapi[mcp]
```
For development:
```bash
pip install agniapi[dev]
```
### Basic Application
```python
from agniapi import AgniAPI, JSONResponse
app = AgniAPI(title="My API", version="1.0.0")
@app.get("/")
async def root():
return {"message": "Hello, World!"}
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id, "name": f"User {user_id}"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
```
**Access your API:**
- **API**: http://localhost:8000
- **OpenAPI Docs**: http://localhost:8000/docs
- **ReDoc**: http://localhost:8000/redoc
### Run the Example
```bash
# Try the complete example
python examples/simple_api.py
```
### With Type Validation
```python
from agniapi import AgniAPI
from pydantic import BaseModel
app = AgniAPI()
class User(BaseModel):
name: str
email: str
age: int
@app.post("/users")
async def create_user(user: User):
return {"message": f"Created user {user.name}"}
```
### Flask-style Blueprints
```python
from agniapi import AgniAPI, Blueprint
app = AgniAPI()
users_bp = Blueprint("users", __name__, url_prefix="/users")
@users_bp.get("/")
async def list_users():
return {"users": []}
@users_bp.post("/")
async def create_user():
return {"message": "User created"}
app.register_blueprint(users_bp)
```
### MCP Integration
```python
from agniapi import AgniAPI, mcp_tool, mcp_resource
app = AgniAPI(mcp_enabled=True)
@mcp_tool("get_weather", "Get weather information")
async def get_weather(location: str) -> dict:
return {"location": location, "temperature": "22ยฐC", "condition": "sunny"}
@mcp_resource("database://users", "User Database")
async def get_users_resource() -> list:
return [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
@app.get("/")
async def root():
return {"message": "API with MCP support"}
```
### Dependency Injection
```python
from agniapi import AgniAPI, Depends
app = AgniAPI()
async def get_database():
# Database connection logic
return {"db": "connected"}
async def get_current_user(db = Depends(get_database)):
# User authentication logic
return {"user": "authenticated"}
@app.get("/protected")
async def protected_route(user = Depends(get_current_user)):
return {"message": f"Hello {user['user']}"}
```
### WebSocket Support
```python
from agniapi import AgniAPI
from agniapi.websockets import WebSocket
app = AgniAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Echo: {data}")
except:
pass
```
## CLI Usage
### Create a new project
```bash
agniapi new my-project
cd my-project
pip install -r requirements.txt
```
### Run development server
```bash
agniapi run --reload --debug
```
### Generate OpenAPI documentation
```bash
agniapi openapi --output api-spec.json
```
### List all routes
```bash
agniapi routes
```
### Run MCP server
```bash
agniapi mcp --transport stdio
agniapi mcp --transport sse --host localhost --port 8080
agniapi mcp --transport websocket --host localhost --port 8080
```
### Run tests
```bash
agniapi test --coverage
```
## Advanced Features
### Middleware
```python
from agniapi import AgniAPI
from agniapi.middleware import CORSMiddleware
app = AgniAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
```
### Security
```python
from agniapi import AgniAPI, Depends
from agniapi.security import HTTPBearer, JWTManager
app = AgniAPI()
security = HTTPBearer()
jwt_manager = JWTManager("your-secret-key")
async def get_current_user(token: str = Depends(security)):
payload = jwt_manager.verify_token(token)
return payload
@app.get("/protected")
async def protected(user = Depends(get_current_user)):
return {"user": user}
```
### Testing
```python
from agniapi.testing import TestClient
from main import app
def test_api():
client = TestClient(app)
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Hello, World!"}
# Async testing
async def test_async():
response = await client.aget("/users/1")
assert response.status_code == 200
```
## Comparison with Flask and FastAPI
| Feature | Flask | FastAPI | Agni API |
|---------|-------|---------|----------|
| Async Support | โ | โ
| โ
|
| Type Hints | โ | โ
| โ
|
| Auto Documentation | โ | โ
| โ
|
| Blueprints | โ
| โ | โ
|
| Dependency Injection | โ | โ
| โ
|
| WebSocket Support | โ | โ
| โ
|
| MCP Support | โ | โ | โ
|
| WSGI Compatible | โ
| โ | โ
|
| ASGI Compatible | โ | โ
| โ
|
## Migration Guides
### From Flask
```python
# Flask
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/users/<int:user_id>')
def get_user(user_id):
return jsonify({"user_id": user_id})
# Agni API
from agniapi import AgniAPI
app = AgniAPI()
@app.get('/users/{user_id}')
async def get_user(user_id: int):
return {"user_id": user_id}
```
### From FastAPI
```python
# FastAPI
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id}
# Agni API (same syntax!)
from agniapi import AgniAPI
app = AgniAPI()
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id}
```
## Documentation
- **API Reference**: [docs.agniapi.dev](https://docs.agniapi.dev)
- **User Guide**: [docs.agniapi.dev/guide](https://docs.agniapi.dev/guide)
- **MCP Integration**: [docs.agniapi.dev/mcp](https://docs.agniapi.dev/mcp)
- **Examples**: [github.com/agniapi/examples](https://github.com/agniapi/examples)
## Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Acknowledgments
- **Flask** - For the blueprint system and WSGI patterns
- **FastAPI** - For async support and type validation patterns
- **Starlette** - For ASGI implementation
- **Pydantic** - For data validation
- **MCP** - For the Model Context Protocol specification
Raw data
{
"_id": null,
"home_page": null,
"name": "agniapi",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": "AIMLDev726 <aistudentlearn4@gmail.com>",
"keywords": "api, rest, web, framework, async, flask, fastapi, mcp, model-context-protocol",
"author": null,
"author_email": "AIMLDev726 <aistudentlearn4@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/65/ed/f07ab32470faf905890ff5af96f2e70afd492956c15a88c1ec84c5c83831/agniapi-0.1.1.tar.gz",
"platform": null,
"description": "# Agni API\r\n\r\nA unified REST API framework that combines the best features of Flask and FastAPI with built-in Model Context Protocol (MCP) support.\r\n\r\n## Features\r\n\r\n### \ud83d\udd25 **Unified Framework**\r\n- **Flask-style** blueprints and routing\r\n- **FastAPI-style** async support and type hints\r\n- **Seamless integration** between sync and async code\r\n- **Automatic API documentation** with OpenAPI/Swagger\r\n\r\n### \u26a1 **High Performance**\r\n- Full async/await support\r\n- ASGI and WSGI compatibility\r\n- Optimized request handling\r\n- Built-in middleware system\r\n\r\n### \ud83e\udd16 **Built-in MCP Support**\r\n- **MCP Server** capabilities out of the box\r\n- **MCP Client** for connecting to other servers\r\n- **Easy tool registration** with decorators\r\n- **Resource and prompt management**\r\n\r\n### \ud83d\udee1\ufe0f **Security First**\r\n- OAuth2, JWT, and API key authentication\r\n- Built-in security schemes\r\n- CORS, HTTPS redirect, and trusted host middleware\r\n- Password hashing utilities\r\n\r\n### \ud83e\uddea **Developer Experience**\r\n- **Type hints** throughout\r\n- **Dependency injection** system\r\n- **WebSocket** support\r\n- **Testing utilities** for both sync and async\r\n- **CLI tools** for development\r\n\r\n## Quick Start\r\n\r\n### Installation\r\n\r\n```bash\r\npip install agniapi\r\n```\r\n\r\nFor MCP support:\r\n```bash\r\npip install agniapi[mcp]\r\n```\r\n\r\nFor development:\r\n```bash\r\npip install agniapi[dev]\r\n```\r\n\r\n### Basic Application\r\n\r\n```python\r\nfrom agniapi import AgniAPI, JSONResponse\r\n\r\napp = AgniAPI(title=\"My API\", version=\"1.0.0\")\r\n\r\n@app.get(\"/\")\r\nasync def root():\r\n return {\"message\": \"Hello, World!\"}\r\n\r\n@app.get(\"/users/{user_id}\")\r\nasync def get_user(user_id: int):\r\n return {\"user_id\": user_id, \"name\": f\"User {user_id}\"}\r\n\r\nif __name__ == \"__main__\":\r\n import uvicorn\r\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, reload=True)\r\n```\r\n\r\n**Access your API:**\r\n- **API**: http://localhost:8000\r\n- **OpenAPI Docs**: http://localhost:8000/docs\r\n- **ReDoc**: http://localhost:8000/redoc\r\n\r\n### Run the Example\r\n\r\n```bash\r\n# Try the complete example\r\npython examples/simple_api.py\r\n```\r\n\r\n### With Type Validation\r\n\r\n```python\r\nfrom agniapi import AgniAPI\r\nfrom pydantic import BaseModel\r\n\r\napp = AgniAPI()\r\n\r\nclass User(BaseModel):\r\n name: str\r\n email: str\r\n age: int\r\n\r\n@app.post(\"/users\")\r\nasync def create_user(user: User):\r\n return {\"message\": f\"Created user {user.name}\"}\r\n```\r\n\r\n### Flask-style Blueprints\r\n\r\n```python\r\nfrom agniapi import AgniAPI, Blueprint\r\n\r\napp = AgniAPI()\r\nusers_bp = Blueprint(\"users\", __name__, url_prefix=\"/users\")\r\n\r\n@users_bp.get(\"/\")\r\nasync def list_users():\r\n return {\"users\": []}\r\n\r\n@users_bp.post(\"/\")\r\nasync def create_user():\r\n return {\"message\": \"User created\"}\r\n\r\napp.register_blueprint(users_bp)\r\n```\r\n\r\n### MCP Integration\r\n\r\n```python\r\nfrom agniapi import AgniAPI, mcp_tool, mcp_resource\r\n\r\napp = AgniAPI(mcp_enabled=True)\r\n\r\n@mcp_tool(\"get_weather\", \"Get weather information\")\r\nasync def get_weather(location: str) -> dict:\r\n return {\"location\": location, \"temperature\": \"22\u00b0C\", \"condition\": \"sunny\"}\r\n\r\n@mcp_resource(\"database://users\", \"User Database\")\r\nasync def get_users_resource() -> list:\r\n return [{\"id\": 1, \"name\": \"Alice\"}, {\"id\": 2, \"name\": \"Bob\"}]\r\n\r\n@app.get(\"/\")\r\nasync def root():\r\n return {\"message\": \"API with MCP support\"}\r\n```\r\n\r\n### Dependency Injection\r\n\r\n```python\r\nfrom agniapi import AgniAPI, Depends\r\n\r\napp = AgniAPI()\r\n\r\nasync def get_database():\r\n # Database connection logic\r\n return {\"db\": \"connected\"}\r\n\r\nasync def get_current_user(db = Depends(get_database)):\r\n # User authentication logic\r\n return {\"user\": \"authenticated\"}\r\n\r\n@app.get(\"/protected\")\r\nasync def protected_route(user = Depends(get_current_user)):\r\n return {\"message\": f\"Hello {user['user']}\"}\r\n```\r\n\r\n### WebSocket Support\r\n\r\n```python\r\nfrom agniapi import AgniAPI\r\nfrom agniapi.websockets import WebSocket\r\n\r\napp = AgniAPI()\r\n\r\n@app.websocket(\"/ws\")\r\nasync def websocket_endpoint(websocket: WebSocket):\r\n await websocket.accept()\r\n \r\n try:\r\n while True:\r\n data = await websocket.receive_text()\r\n await websocket.send_text(f\"Echo: {data}\")\r\n except:\r\n pass\r\n```\r\n\r\n## CLI Usage\r\n\r\n### Create a new project\r\n\r\n```bash\r\nagniapi new my-project\r\ncd my-project\r\npip install -r requirements.txt\r\n```\r\n\r\n### Run development server\r\n\r\n```bash\r\nagniapi run --reload --debug\r\n```\r\n\r\n### Generate OpenAPI documentation\r\n\r\n```bash\r\nagniapi openapi --output api-spec.json\r\n```\r\n\r\n### List all routes\r\n\r\n```bash\r\nagniapi routes\r\n```\r\n\r\n### Run MCP server\r\n\r\n```bash\r\nagniapi mcp --transport stdio\r\nagniapi mcp --transport sse --host localhost --port 8080\r\nagniapi mcp --transport websocket --host localhost --port 8080\r\n```\r\n\r\n### Run tests\r\n\r\n```bash\r\nagniapi test --coverage\r\n```\r\n\r\n## Advanced Features\r\n\r\n### Middleware\r\n\r\n```python\r\nfrom agniapi import AgniAPI\r\nfrom agniapi.middleware import CORSMiddleware\r\n\r\napp = AgniAPI()\r\n\r\napp.add_middleware(\r\n CORSMiddleware,\r\n allow_origins=[\"*\"],\r\n allow_credentials=True,\r\n allow_methods=[\"*\"],\r\n allow_headers=[\"*\"],\r\n)\r\n```\r\n\r\n### Security\r\n\r\n```python\r\nfrom agniapi import AgniAPI, Depends\r\nfrom agniapi.security import HTTPBearer, JWTManager\r\n\r\napp = AgniAPI()\r\nsecurity = HTTPBearer()\r\njwt_manager = JWTManager(\"your-secret-key\")\r\n\r\nasync def get_current_user(token: str = Depends(security)):\r\n payload = jwt_manager.verify_token(token)\r\n return payload\r\n\r\n@app.get(\"/protected\")\r\nasync def protected(user = Depends(get_current_user)):\r\n return {\"user\": user}\r\n```\r\n\r\n### Testing\r\n\r\n```python\r\nfrom agniapi.testing import TestClient\r\nfrom main import app\r\n\r\ndef test_api():\r\n client = TestClient(app)\r\n \r\n response = client.get(\"/\")\r\n assert response.status_code == 200\r\n assert response.json() == {\"message\": \"Hello, World!\"}\r\n \r\n # Async testing\r\n async def test_async():\r\n response = await client.aget(\"/users/1\")\r\n assert response.status_code == 200\r\n```\r\n\r\n## Comparison with Flask and FastAPI\r\n\r\n| Feature | Flask | FastAPI | Agni API |\r\n|---------|-------|---------|----------|\r\n| Async Support | \u274c | \u2705 | \u2705 |\r\n| Type Hints | \u274c | \u2705 | \u2705 |\r\n| Auto Documentation | \u274c | \u2705 | \u2705 |\r\n| Blueprints | \u2705 | \u274c | \u2705 |\r\n| Dependency Injection | \u274c | \u2705 | \u2705 |\r\n| WebSocket Support | \u274c | \u2705 | \u2705 |\r\n| MCP Support | \u274c | \u274c | \u2705 |\r\n| WSGI Compatible | \u2705 | \u274c | \u2705 |\r\n| ASGI Compatible | \u274c | \u2705 | \u2705 |\r\n\r\n## Migration Guides\r\n\r\n### From Flask\r\n\r\n```python\r\n# Flask\r\nfrom flask import Flask, jsonify, request\r\n\r\napp = Flask(__name__)\r\n\r\n@app.route('/users/<int:user_id>')\r\ndef get_user(user_id):\r\n return jsonify({\"user_id\": user_id})\r\n\r\n# Agni API\r\nfrom agniapi import AgniAPI\r\n\r\napp = AgniAPI()\r\n\r\n@app.get('/users/{user_id}')\r\nasync def get_user(user_id: int):\r\n return {\"user_id\": user_id}\r\n```\r\n\r\n### From FastAPI\r\n\r\n```python\r\n# FastAPI\r\nfrom fastapi import FastAPI\r\n\r\napp = FastAPI()\r\n\r\n@app.get(\"/users/{user_id}\")\r\nasync def get_user(user_id: int):\r\n return {\"user_id\": user_id}\r\n\r\n# Agni API (same syntax!)\r\nfrom agniapi import AgniAPI\r\n\r\napp = AgniAPI()\r\n\r\n@app.get(\"/users/{user_id}\")\r\nasync def get_user(user_id: int):\r\n return {\"user_id\": user_id}\r\n```\r\n\r\n## Documentation\r\n\r\n- **API Reference**: [docs.agniapi.dev](https://docs.agniapi.dev)\r\n- **User Guide**: [docs.agniapi.dev/guide](https://docs.agniapi.dev/guide)\r\n- **MCP Integration**: [docs.agniapi.dev/mcp](https://docs.agniapi.dev/mcp)\r\n- **Examples**: [github.com/agniapi/examples](https://github.com/agniapi/examples)\r\n\r\n## Contributing\r\n\r\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\r\n\r\n## Acknowledgments\r\n\r\n- **Flask** - For the blueprint system and WSGI patterns\r\n- **FastAPI** - For async support and type validation patterns \r\n- **Starlette** - For ASGI implementation\r\n- **Pydantic** - For data validation\r\n- **MCP** - For the Model Context Protocol specification\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A unified REST API framework combining Flask and FastAPI features with built-in MCP support",
"version": "0.1.1",
"project_urls": {
"Bug Tracker": "https://github.com/AIMLDev726/agniapi/issues",
"Documentation": "https://github.com/AIMLDev726/agniapi/blob/main/README.md",
"Homepage": "https://github.com/AIMLDev726/agniapi",
"Repository": "https://github.com/AIMLDev726/agniapi"
},
"split_keywords": [
"api",
" rest",
" web",
" framework",
" async",
" flask",
" fastapi",
" mcp",
" model-context-protocol"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "496216d74d0bbd8ab09099418ec9b2c311f9c1031b52b57c09d9d0509ebb2ede",
"md5": "9070ddd8895f7decc55141e239d1c42e",
"sha256": "a395239abd05f33b6a28e25a8fd45d2349ef563865ebf90e33d5d2d744a223de"
},
"downloads": -1,
"filename": "agniapi-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9070ddd8895f7decc55141e239d1c42e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 94749,
"upload_time": "2025-08-30T07:20:47",
"upload_time_iso_8601": "2025-08-30T07:20:47.896691Z",
"url": "https://files.pythonhosted.org/packages/49/62/16d74d0bbd8ab09099418ec9b2c311f9c1031b52b57c09d9d0509ebb2ede/agniapi-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "65edf07ab32470faf905890ff5af96f2e70afd492956c15a88c1ec84c5c83831",
"md5": "ecdae15d0765ac08ece1eaeceb9da960",
"sha256": "054abef3284ca8fc4caf750bb2e1605fda5360e560c972e4b349e08b07bb8b7b"
},
"downloads": -1,
"filename": "agniapi-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "ecdae15d0765ac08ece1eaeceb9da960",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 84940,
"upload_time": "2025-08-30T07:20:50",
"upload_time_iso_8601": "2025-08-30T07:20:50.214035Z",
"url": "https://files.pythonhosted.org/packages/65/ed/f07ab32470faf905890ff5af96f2e70afd492956c15a88c1ec84c5c83831/agniapi-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-30 07:20:50",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AIMLDev726",
"github_project": "agniapi",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "starlette",
"specs": [
[
">=",
"0.27.0"
]
]
},
{
"name": "werkzeug",
"specs": [
[
">=",
"2.3.0"
]
]
},
{
"name": "pydantic",
"specs": [
[
">=",
"2.0.0"
]
]
},
{
"name": "click",
"specs": [
[
">=",
"8.0.0"
]
]
},
{
"name": "httpx",
"specs": [
[
">=",
"0.24.0"
]
]
},
{
"name": "typing-extensions",
"specs": [
[
">=",
"4.0.0"
]
]
},
{
"name": "uvicorn",
"specs": [
[
">=",
"0.18.0"
]
]
}
],
"lcname": "agniapi"
}