agniapi


Nameagniapi JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryA unified REST API framework combining Flask and FastAPI features with built-in MCP support
upload_time2025-08-30 07:20:50
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords api rest web framework async flask fastapi mcp model-context-protocol
VCS
bugtrack_url
requirements starlette werkzeug pydantic click httpx typing-extensions uvicorn
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 0.95149s