neutronapi


Nameneutronapi JSON
Version 0.3.15 PyPI version JSON
download
home_pageNone
SummaryA modern, high-performance ASGI-based Python web framework.
upload_time2025-09-13 18:11:10
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords api framework async fastapi uvicorn orm migrations background-tasks dependency-injection typing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # NeutronAPI

**A modern, high-performance Python web framework built for async applications.**

NeutronAPI provides everything you need to build robust APIs quickly: universal dependency injection, comprehensive type support, database models with migrations, background tasks, and an intuitive command-line interface. Designed for performance, developer experience, and production readiness.

## Installation

```bash
pip install neutronapi
```

## Quick Start

```bash
# 1. Create project
neutronapi startproject blog
cd blog

# 2. Create an app
python manage.py startapp posts

# 3. Start server  
python manage.py start               # Dev mode (auto-reload)

# 4. Test
python manage.py test
```

## Key Features

✅ **Universal Registry System** - Clean dependency injection with `namespace:name` keys  
✅ **Comprehensive Type Support** - Full typing with IDE integration  
✅ **High Performance** - Built on uvicorn/ASGI for maximum speed  
✅ **Database ORM** - Models, migrations, and async queries  
✅ **Background Tasks** - Scheduled and async task execution  
✅ **Developer Experience** - Rich docstrings, validation, and error messages  

## Getting Started Tutorial

**1. Create Project**
```bash
neutronapi startproject blog
cd blog
```

**2. Create App Module**  
```bash
python manage.py startapp posts
```

**3. Configure in `apps/settings.py`**
```python
import os

# ASGI application entry point (required for server)
ENTRY = "apps.entry:app"  # module:variable format

# Database
DATABASES = {
    'default': {
        'ENGINE': 'aiosqlite',
        'NAME': 'db.sqlite3',
    }
}
```

**4. Create API in `apps/posts/api.py`**
```python
from neutronapi.base import API, endpoint

class PostAPI(API):
    resource = "/posts"
    name = "posts"
    
    @endpoint("/", methods=["GET"])
    async def list_posts(self, scope, receive, send, **kwargs):
        # Access registry dependencies
        logger = self.registry.get('utils:logger')
        cache = self.registry.get('services:cache')
        
        posts = [{"id": 1, "title": "Hello World"}]
        return await self.response(posts)
    
    @endpoint("/", methods=["POST"])
    async def create_post(self, scope, receive, send, **kwargs):
        # JSON parser is the default; access body via kwargs
        data = kwargs["body"]  # dict
        return await self.response({"id": 2, "title": data.get("title", "New Post")})
```

**5. Register API, Middlewares, Dependencies in `apps/entry.py`**
```python
from neutronapi.application import Application
from neutronapi.middleware.compression import CompressionMiddleware
from neutronapi.middleware.allowed_hosts import AllowedHostsMiddleware
from apps.posts.api import PostAPI

# Example dependencies
class Logger:
    def info(self, message: str) -> None:
        print(f"[INFO] {message}")

class CacheService:
    def __init__(self):
        self._cache = {}
    
    def get(self, key: str) -> any:
        return self._cache.get(key)
    
    def set(self, key: str, value: any) -> None:
        self._cache[key] = value

# Modern registry-based dependency injection
app = Application(
    apis=[PostAPI()],
    middlewares=[
        AllowedHostsMiddleware(allowed_hosts=["localhost", "127.0.0.1"]),
        CompressionMiddleware(minimum_size=512),
    ],
    registry={
        'utils:logger': Logger(),
        'services:cache': CacheService(),
        'services:email': EmailService(),
    }
)
```

**6. Start Server**
```bash
python manage.py start
# Visit: http://127.0.0.1:8000/posts
```

## Universal Registry System

The registry provides clean dependency injection with namespaced keys:

```python
from neutronapi.application import Application

# Register dependencies with namespace:name pattern
app = Application(
    registry={
        'utils:logger': Logger(),
        'utils:cache': RedisCache(),
        'services:email': EmailService(), 
        'services:database': DatabaseService(),
        'modules:auth': AuthModule(),
    }
)

# Access in APIs
class UserAPI(API):
    @API.endpoint("/register", methods=["POST"])
    async def register(self, scope, receive, send, **kwargs):
        # Type-safe access with IDE support
        logger = self.registry.get('utils:logger')
        email = self.registry.get('services:email')
        
        logger.info("User registration started")
        await email.send_welcome_email(user_data)
        
        return await self.response({"status": "registered"})

# Dynamic registration
app.register('utils:metrics', MetricsCollector())
app.register('services:payment', PaymentProcessor())

# Registry utilities
print(app.list_registry_keys())  # All keys
print(app.list_registry_keys('utils'))  # Just utils namespace
print(app.has_registry_item('services:email'))  # True
```

## Comprehensive Type Support

NeutronAPI includes full type hints with IDE integration:

```python
from typing import Dict, List, Optional
from neutronapi.base import API, Response, endpoint
from neutronapi.application import Application

class TypedAPI(API):
    resource = "/api"
    
    @endpoint("/users", methods=["GET"])
    async def get_users(self, scope: Dict[str, Any], receive, send) -> Response:
        # Full type support with autocomplete
        cache: CacheService = self.registry.get('services:cache')
        users: List[Dict[str, str]] = cache.get('users') or []
        
        return await self.response(users)

# Type-safe registry access
def get_typed_dependency[T](app: Application, key: str) -> Optional[T]:
    return app.get_registry_item(key)

logger = get_typed_dependency[Logger](app, 'utils:logger')
```

## Project Structure

```
myproject/
├── manage.py           # Management commands
├── apps/
│   ├── __init__.py
│   ├── settings.py     # Configuration 
│   └── entry.py        # ASGI application
└── db.sqlite3          # Database
```

## Background Tasks

```python
from neutronapi.background import Task, TaskFrequency
from neutronapi.base import API, endpoint
from neutronapi.application import Application

class CleanupTask(Task):
    name = "cleanup"
    frequency = TaskFrequency.MINUTELY
    
    async def run(self, **kwargs):
        print("Cleaning up logs...")

class PingAPI(API):
    resource = "/ping"
    
    @endpoint("/", methods=["GET"])
    async def ping(self, scope, receive, send, **kwargs):
        return await self.response({"status": "ok"})

# Add to application  
app = Application(
    apis=[PingAPI()],
    tasks={"cleanup": CleanupTask()}
)
```

## Database Models

```python
from neutronapi.db.models import Model
from neutronapi.db.fields import CharField, IntegerField, DateTimeField

class User(Model):
    name = CharField(max_length=100)
    age = IntegerField()
    created_at = DateTimeField(auto_now_add=True)
```

## Server Commands

```bash
# Development (auto-reload, localhost)
python manage.py start

# Production (multi-worker, optimized)  
python manage.py start --production

# Custom configuration
python manage.py start --host 0.0.0.0 --port 8080 --workers 4
```

## Testing

```bash
# SQLite (default)
python manage.py test

# Specific tests
python manage.py test app.tests.test_models.TestUser.test_creation

# Dev tooling (only neutronapi/ is targeted)
black neutronapi
flake8 neutronapi
```

## Database Features

### Models & ORM
```python
from neutronapi.db.models import Model
from neutronapi.db.fields import CharField, IntegerField, DateTimeField

class Post(Model):
    title = CharField(max_length=200)
    content = TextField()
    created_at = DateTimeField(auto_now_add=True)

# Basic queries
await Post.objects.all()
await Post.objects.filter(title="My Post")
await Post.objects.create(title="New Post", content="...")
```

### Full-Text Search
```python
# Search across text fields
await Post.objects.search("python framework")

# Field-specific search
await Post.objects.filter(content__search="database")

# Ranked results (PostgreSQL/SQLite FTS5)
await Post.objects.search("api").order_by_rank()
```

Supports PostgreSQL native FTS and SQLite FTS5 with automatic fallback to LIKE queries.


## Commands

```bash
python manage.py start              # Start server
python manage.py test               # Run tests  
python manage.py migrate            # Run migrations
python manage.py startapp posts     # Create new app
```

### Custom Commands

Create custom management commands like Django by adding them to your app's `commands` directory:

```python
# apps/blog/commands/greet.py
from neutronapi.commands.base import BaseCommand

class Command(BaseCommand):
    help = "Greet a user"
    
    def handle(self, *args, **options):
        name = args[0] if args else "World"
        self.success(f"Hello, {name}!")
        return 0
```

Run with:
```bash
python manage.py greet Alice    # Hello, Alice!
```

Commands are automatically discovered from any `apps/*/commands/*.py` files that contain a `Command` class.

## Middlewares

```python
from neutronapi.middleware.compression import CompressionMiddleware
from neutronapi.middleware.allowed_hosts import AllowedHostsMiddleware

app = Application(
    apis=[PostAPI()],
    middlewares=[
        AllowedHostsMiddleware(allowed_hosts=["localhost", "yourdomain.com"]),
        CompressionMiddleware(minimum_size=512),  # Compress responses > 512 bytes
    ]
)

# Endpoint-level middleware
@endpoint("/upload", methods=["POST"], middlewares=[AuthMiddleware()])
async def upload_file(self, scope, receive, send, **kwargs):
    # This endpoint has auth middleware
    pass
```

## Parsers

```python
from neutronapi.parsers import FormParser, MultiPartParser, BinaryParser

# Default: JSON parser
@endpoint("/api/data", methods=["POST"])
async def json_data(self, scope, receive, send, **kwargs):
    data = kwargs["body"]  # Parsed JSON dict
    return await self.response({"received": data})

# Custom parsers
@endpoint("/upload", methods=["POST"], parsers=[MultiPartParser(), FormParser()])
async def upload_file(self, scope, receive, send, **kwargs):
    files = kwargs["files"]  # Uploaded files
    form_data = kwargs["form"]  # Form fields
    return await self.response({"status": "uploaded"})
```

## Advanced Registry Usage

```python
from neutronapi.application import Application
from typing import Protocol

# Define interfaces for better type safety
class EmailServiceProtocol(Protocol):
    async def send(self, to: str, subject: str, body: str) -> None: ...

class MetricsProtocol(Protocol):
    def increment(self, metric: str) -> None: ...

# Implementation
class SMTPEmailService:
    async def send(self, to: str, subject: str, body: str) -> None:
        # SMTP implementation
        pass

class PrometheusMetrics:
    def increment(self, metric: str) -> None:
        # Prometheus implementation
        pass

# Register with clear namespacing
app = Application(
    registry={
        'services:email': SMTPEmailService(),
        'services:metrics': PrometheusMetrics(),
        'utils:logger': StructuredLogger(),
        'modules:auth': JWTAuthModule(),
    }
)

# Usage with type safety
class OrderAPI(API):
    @endpoint("/orders", methods=["POST"])
    async def create_order(self, scope, receive, send, **kwargs):
        email: EmailServiceProtocol = self.registry.get('services:email')
        metrics: MetricsProtocol = self.registry.get('services:metrics')
        
        # Your business logic here
        metrics.increment('orders.created')
        await email.send('user@example.com', 'Order Confirmed', 'Thanks!')
        
        return await self.response({"status": "created"})
```

## Error Handling

```python
from neutronapi.api.exceptions import ValidationError, NotFound, APIException

@endpoint("/users/<int:user_id>", methods=["GET"])
async def get_user(self, scope, receive, send, **kwargs):
    user_id = kwargs["user_id"]
    
    if not user_id:
        raise ValidationError("User ID is required")
    
    user = await get_user_from_db(user_id)
    if not user:
        raise NotFound("User not found")
    
    return await self.response(user)

# Custom exceptions
class BusinessLogicError(APIException):
    status_code = 422
    
    def __init__(self, message: str = "Business logic error"):
        super().__init__(message, type="business_error")
```

### Exception Organization

Exceptions are organized by module:

```python
# Module-specific exceptions
from neutronapi.api.exceptions import APIException, ValidationError, NotFound
from neutronapi.db.exceptions import DoesNotExist, MigrationError, IntegrityError
from neutronapi.authentication.exceptions import AuthenticationFailed
from neutronapi.middleware.exceptions import RouteNotFound, MethodNotAllowed
from neutronapi.openapi.exceptions import InvalidSchemaError

# Generic framework exceptions
from neutronapi.exceptions import ImproperlyConfigured, ValidationError, ObjectDoesNotExist
```

## OpenAPI Documentation

Automatically generate OpenAPI 3.0 specifications from your APIs:

```python
from neutronapi.openapi.openapi import OpenAPIGenerator

# Basic API - automatically discovered
class UserAPI(API):
    resource = "/v1/users"
    name = "users"
    
    @API.endpoint("/", methods=["GET"], name="list")
    async def list_users(self, scope, receive, send, **kwargs):
        return await self.response({"users": []})

# Internal/debug API - hidden by default
class DebugAPI(API):
    resource = "/debug"
    name = "debug" 
    hidden = True  # Excluded from docs by default
    
    @API.endpoint("/status", methods=["GET"], name="status")
    async def debug_status(self, scope, receive, send, **kwargs):
        return await self.response({"debug": True})

# Generate public API docs (excludes hidden APIs)
async def generate_public_docs():
    apis = {"users": UserAPI(), "debug": DebugAPI()}
    
    generator = OpenAPIGenerator(title="My API", version="1.0.0")
    spec = await generator.generate(source=apis)
    # Result: Only includes /v1/users endpoints
    
# Generate complete docs (includes everything)
async def generate_complete_docs():
    apis = {"users": UserAPI(), "debug": DebugAPI()}
    
    generator = OpenAPIGenerator(
        title="Complete API",
        include_all=True  # Include hidden APIs and private endpoints
    )
    spec = await generator.generate(source=apis)
    # Result: Includes both /v1/users and /debug endpoints

# Exclude specific patterns
async def generate_filtered_docs():
    apis = {"users": UserAPI(), "debug": DebugAPI()}
    
    generator = OpenAPIGenerator(
        title="Filtered API",
        exclude_patterns=["/debug/*", "/internal/*"]
    )
    spec = await generator.generate(source=apis)

# Convenience function for all endpoints
from neutronapi.openapi.openapi import generate_all_endpoints_openapi
spec = await generate_all_endpoints_openapi(apis, title="All Endpoints")
```

**Why use `hidden=True`?**
- Mark internal APIs (debugging, health checks, admin endpoints)
- Keep them accessible but exclude from public documentation
- Use `include_all=True` to generate complete internal docs

## Why NeutronAPI?

- **🚀 Performance**: Built on ASGI/uvicorn for maximum throughput
- **🏗️ Architecture**: Clean separation with universal dependency injection  
- **🔒 Type Safety**: Comprehensive typing with IDE support
- **📚 Auto Documentation**: OpenAPI 3.0 & Swagger 2.0 generation
- **🎯 Developer Experience**: Rich error messages, validation, and documentation
- **📦 Batteries Included**: ORM, migrations, background tasks, middleware
- **🔧 Production Ready**: Multi-worker support, monitoring, and deployment tools

Perfect for building modern APIs, microservices, and high-performance web applications with automatic documentation.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "neutronapi",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "api, framework, async, fastapi, uvicorn, orm, migrations, background-tasks, dependency-injection, typing",
    "author": null,
    "author_email": "Aaron Kazah <aaron@neutronapi.com>",
    "download_url": "https://files.pythonhosted.org/packages/99/e9/3e1dc3204e3fc23cde1fed6313b2ac81881bee1822e8a13f3124f1d410ba/neutronapi-0.3.15.tar.gz",
    "platform": null,
    "description": "# NeutronAPI\n\n**A modern, high-performance Python web framework built for async applications.**\n\nNeutronAPI provides everything you need to build robust APIs quickly: universal dependency injection, comprehensive type support, database models with migrations, background tasks, and an intuitive command-line interface. Designed for performance, developer experience, and production readiness.\n\n## Installation\n\n```bash\npip install neutronapi\n```\n\n## Quick Start\n\n```bash\n# 1. Create project\nneutronapi startproject blog\ncd blog\n\n# 2. Create an app\npython manage.py startapp posts\n\n# 3. Start server  \npython manage.py start               # Dev mode (auto-reload)\n\n# 4. Test\npython manage.py test\n```\n\n## Key Features\n\n\u2705 **Universal Registry System** - Clean dependency injection with `namespace:name` keys  \n\u2705 **Comprehensive Type Support** - Full typing with IDE integration  \n\u2705 **High Performance** - Built on uvicorn/ASGI for maximum speed  \n\u2705 **Database ORM** - Models, migrations, and async queries  \n\u2705 **Background Tasks** - Scheduled and async task execution  \n\u2705 **Developer Experience** - Rich docstrings, validation, and error messages  \n\n## Getting Started Tutorial\n\n**1. Create Project**\n```bash\nneutronapi startproject blog\ncd blog\n```\n\n**2. Create App Module**  \n```bash\npython manage.py startapp posts\n```\n\n**3. Configure in `apps/settings.py`**\n```python\nimport os\n\n# ASGI application entry point (required for server)\nENTRY = \"apps.entry:app\"  # module:variable format\n\n# Database\nDATABASES = {\n    'default': {\n        'ENGINE': 'aiosqlite',\n        'NAME': 'db.sqlite3',\n    }\n}\n```\n\n**4. Create API in `apps/posts/api.py`**\n```python\nfrom neutronapi.base import API, endpoint\n\nclass PostAPI(API):\n    resource = \"/posts\"\n    name = \"posts\"\n    \n    @endpoint(\"/\", methods=[\"GET\"])\n    async def list_posts(self, scope, receive, send, **kwargs):\n        # Access registry dependencies\n        logger = self.registry.get('utils:logger')\n        cache = self.registry.get('services:cache')\n        \n        posts = [{\"id\": 1, \"title\": \"Hello World\"}]\n        return await self.response(posts)\n    \n    @endpoint(\"/\", methods=[\"POST\"])\n    async def create_post(self, scope, receive, send, **kwargs):\n        # JSON parser is the default; access body via kwargs\n        data = kwargs[\"body\"]  # dict\n        return await self.response({\"id\": 2, \"title\": data.get(\"title\", \"New Post\")})\n```\n\n**5. Register API, Middlewares, Dependencies in `apps/entry.py`**\n```python\nfrom neutronapi.application import Application\nfrom neutronapi.middleware.compression import CompressionMiddleware\nfrom neutronapi.middleware.allowed_hosts import AllowedHostsMiddleware\nfrom apps.posts.api import PostAPI\n\n# Example dependencies\nclass Logger:\n    def info(self, message: str) -> None:\n        print(f\"[INFO] {message}\")\n\nclass CacheService:\n    def __init__(self):\n        self._cache = {}\n    \n    def get(self, key: str) -> any:\n        return self._cache.get(key)\n    \n    def set(self, key: str, value: any) -> None:\n        self._cache[key] = value\n\n# Modern registry-based dependency injection\napp = Application(\n    apis=[PostAPI()],\n    middlewares=[\n        AllowedHostsMiddleware(allowed_hosts=[\"localhost\", \"127.0.0.1\"]),\n        CompressionMiddleware(minimum_size=512),\n    ],\n    registry={\n        'utils:logger': Logger(),\n        'services:cache': CacheService(),\n        'services:email': EmailService(),\n    }\n)\n```\n\n**6. Start Server**\n```bash\npython manage.py start\n# Visit: http://127.0.0.1:8000/posts\n```\n\n## Universal Registry System\n\nThe registry provides clean dependency injection with namespaced keys:\n\n```python\nfrom neutronapi.application import Application\n\n# Register dependencies with namespace:name pattern\napp = Application(\n    registry={\n        'utils:logger': Logger(),\n        'utils:cache': RedisCache(),\n        'services:email': EmailService(), \n        'services:database': DatabaseService(),\n        'modules:auth': AuthModule(),\n    }\n)\n\n# Access in APIs\nclass UserAPI(API):\n    @API.endpoint(\"/register\", methods=[\"POST\"])\n    async def register(self, scope, receive, send, **kwargs):\n        # Type-safe access with IDE support\n        logger = self.registry.get('utils:logger')\n        email = self.registry.get('services:email')\n        \n        logger.info(\"User registration started\")\n        await email.send_welcome_email(user_data)\n        \n        return await self.response({\"status\": \"registered\"})\n\n# Dynamic registration\napp.register('utils:metrics', MetricsCollector())\napp.register('services:payment', PaymentProcessor())\n\n# Registry utilities\nprint(app.list_registry_keys())  # All keys\nprint(app.list_registry_keys('utils'))  # Just utils namespace\nprint(app.has_registry_item('services:email'))  # True\n```\n\n## Comprehensive Type Support\n\nNeutronAPI includes full type hints with IDE integration:\n\n```python\nfrom typing import Dict, List, Optional\nfrom neutronapi.base import API, Response, endpoint\nfrom neutronapi.application import Application\n\nclass TypedAPI(API):\n    resource = \"/api\"\n    \n    @endpoint(\"/users\", methods=[\"GET\"])\n    async def get_users(self, scope: Dict[str, Any], receive, send) -> Response:\n        # Full type support with autocomplete\n        cache: CacheService = self.registry.get('services:cache')\n        users: List[Dict[str, str]] = cache.get('users') or []\n        \n        return await self.response(users)\n\n# Type-safe registry access\ndef get_typed_dependency[T](app: Application, key: str) -> Optional[T]:\n    return app.get_registry_item(key)\n\nlogger = get_typed_dependency[Logger](app, 'utils:logger')\n```\n\n## Project Structure\n\n```\nmyproject/\n\u251c\u2500\u2500 manage.py           # Management commands\n\u251c\u2500\u2500 apps/\n\u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u251c\u2500\u2500 settings.py     # Configuration \n\u2502   \u2514\u2500\u2500 entry.py        # ASGI application\n\u2514\u2500\u2500 db.sqlite3          # Database\n```\n\n## Background Tasks\n\n```python\nfrom neutronapi.background import Task, TaskFrequency\nfrom neutronapi.base import API, endpoint\nfrom neutronapi.application import Application\n\nclass CleanupTask(Task):\n    name = \"cleanup\"\n    frequency = TaskFrequency.MINUTELY\n    \n    async def run(self, **kwargs):\n        print(\"Cleaning up logs...\")\n\nclass PingAPI(API):\n    resource = \"/ping\"\n    \n    @endpoint(\"/\", methods=[\"GET\"])\n    async def ping(self, scope, receive, send, **kwargs):\n        return await self.response({\"status\": \"ok\"})\n\n# Add to application  \napp = Application(\n    apis=[PingAPI()],\n    tasks={\"cleanup\": CleanupTask()}\n)\n```\n\n## Database Models\n\n```python\nfrom neutronapi.db.models import Model\nfrom neutronapi.db.fields import CharField, IntegerField, DateTimeField\n\nclass User(Model):\n    name = CharField(max_length=100)\n    age = IntegerField()\n    created_at = DateTimeField(auto_now_add=True)\n```\n\n## Server Commands\n\n```bash\n# Development (auto-reload, localhost)\npython manage.py start\n\n# Production (multi-worker, optimized)  \npython manage.py start --production\n\n# Custom configuration\npython manage.py start --host 0.0.0.0 --port 8080 --workers 4\n```\n\n## Testing\n\n```bash\n# SQLite (default)\npython manage.py test\n\n# Specific tests\npython manage.py test app.tests.test_models.TestUser.test_creation\n\n# Dev tooling (only neutronapi/ is targeted)\nblack neutronapi\nflake8 neutronapi\n```\n\n## Database Features\n\n### Models & ORM\n```python\nfrom neutronapi.db.models import Model\nfrom neutronapi.db.fields import CharField, IntegerField, DateTimeField\n\nclass Post(Model):\n    title = CharField(max_length=200)\n    content = TextField()\n    created_at = DateTimeField(auto_now_add=True)\n\n# Basic queries\nawait Post.objects.all()\nawait Post.objects.filter(title=\"My Post\")\nawait Post.objects.create(title=\"New Post\", content=\"...\")\n```\n\n### Full-Text Search\n```python\n# Search across text fields\nawait Post.objects.search(\"python framework\")\n\n# Field-specific search\nawait Post.objects.filter(content__search=\"database\")\n\n# Ranked results (PostgreSQL/SQLite FTS5)\nawait Post.objects.search(\"api\").order_by_rank()\n```\n\nSupports PostgreSQL native FTS and SQLite FTS5 with automatic fallback to LIKE queries.\n\n\n## Commands\n\n```bash\npython manage.py start              # Start server\npython manage.py test               # Run tests  \npython manage.py migrate            # Run migrations\npython manage.py startapp posts     # Create new app\n```\n\n### Custom Commands\n\nCreate custom management commands like Django by adding them to your app's `commands` directory:\n\n```python\n# apps/blog/commands/greet.py\nfrom neutronapi.commands.base import BaseCommand\n\nclass Command(BaseCommand):\n    help = \"Greet a user\"\n    \n    def handle(self, *args, **options):\n        name = args[0] if args else \"World\"\n        self.success(f\"Hello, {name}!\")\n        return 0\n```\n\nRun with:\n```bash\npython manage.py greet Alice    # Hello, Alice!\n```\n\nCommands are automatically discovered from any `apps/*/commands/*.py` files that contain a `Command` class.\n\n## Middlewares\n\n```python\nfrom neutronapi.middleware.compression import CompressionMiddleware\nfrom neutronapi.middleware.allowed_hosts import AllowedHostsMiddleware\n\napp = Application(\n    apis=[PostAPI()],\n    middlewares=[\n        AllowedHostsMiddleware(allowed_hosts=[\"localhost\", \"yourdomain.com\"]),\n        CompressionMiddleware(minimum_size=512),  # Compress responses > 512 bytes\n    ]\n)\n\n# Endpoint-level middleware\n@endpoint(\"/upload\", methods=[\"POST\"], middlewares=[AuthMiddleware()])\nasync def upload_file(self, scope, receive, send, **kwargs):\n    # This endpoint has auth middleware\n    pass\n```\n\n## Parsers\n\n```python\nfrom neutronapi.parsers import FormParser, MultiPartParser, BinaryParser\n\n# Default: JSON parser\n@endpoint(\"/api/data\", methods=[\"POST\"])\nasync def json_data(self, scope, receive, send, **kwargs):\n    data = kwargs[\"body\"]  # Parsed JSON dict\n    return await self.response({\"received\": data})\n\n# Custom parsers\n@endpoint(\"/upload\", methods=[\"POST\"], parsers=[MultiPartParser(), FormParser()])\nasync def upload_file(self, scope, receive, send, **kwargs):\n    files = kwargs[\"files\"]  # Uploaded files\n    form_data = kwargs[\"form\"]  # Form fields\n    return await self.response({\"status\": \"uploaded\"})\n```\n\n## Advanced Registry Usage\n\n```python\nfrom neutronapi.application import Application\nfrom typing import Protocol\n\n# Define interfaces for better type safety\nclass EmailServiceProtocol(Protocol):\n    async def send(self, to: str, subject: str, body: str) -> None: ...\n\nclass MetricsProtocol(Protocol):\n    def increment(self, metric: str) -> None: ...\n\n# Implementation\nclass SMTPEmailService:\n    async def send(self, to: str, subject: str, body: str) -> None:\n        # SMTP implementation\n        pass\n\nclass PrometheusMetrics:\n    def increment(self, metric: str) -> None:\n        # Prometheus implementation\n        pass\n\n# Register with clear namespacing\napp = Application(\n    registry={\n        'services:email': SMTPEmailService(),\n        'services:metrics': PrometheusMetrics(),\n        'utils:logger': StructuredLogger(),\n        'modules:auth': JWTAuthModule(),\n    }\n)\n\n# Usage with type safety\nclass OrderAPI(API):\n    @endpoint(\"/orders\", methods=[\"POST\"])\n    async def create_order(self, scope, receive, send, **kwargs):\n        email: EmailServiceProtocol = self.registry.get('services:email')\n        metrics: MetricsProtocol = self.registry.get('services:metrics')\n        \n        # Your business logic here\n        metrics.increment('orders.created')\n        await email.send('user@example.com', 'Order Confirmed', 'Thanks!')\n        \n        return await self.response({\"status\": \"created\"})\n```\n\n## Error Handling\n\n```python\nfrom neutronapi.api.exceptions import ValidationError, NotFound, APIException\n\n@endpoint(\"/users/<int:user_id>\", methods=[\"GET\"])\nasync def get_user(self, scope, receive, send, **kwargs):\n    user_id = kwargs[\"user_id\"]\n    \n    if not user_id:\n        raise ValidationError(\"User ID is required\")\n    \n    user = await get_user_from_db(user_id)\n    if not user:\n        raise NotFound(\"User not found\")\n    \n    return await self.response(user)\n\n# Custom exceptions\nclass BusinessLogicError(APIException):\n    status_code = 422\n    \n    def __init__(self, message: str = \"Business logic error\"):\n        super().__init__(message, type=\"business_error\")\n```\n\n### Exception Organization\n\nExceptions are organized by module:\n\n```python\n# Module-specific exceptions\nfrom neutronapi.api.exceptions import APIException, ValidationError, NotFound\nfrom neutronapi.db.exceptions import DoesNotExist, MigrationError, IntegrityError\nfrom neutronapi.authentication.exceptions import AuthenticationFailed\nfrom neutronapi.middleware.exceptions import RouteNotFound, MethodNotAllowed\nfrom neutronapi.openapi.exceptions import InvalidSchemaError\n\n# Generic framework exceptions\nfrom neutronapi.exceptions import ImproperlyConfigured, ValidationError, ObjectDoesNotExist\n```\n\n## OpenAPI Documentation\n\nAutomatically generate OpenAPI 3.0 specifications from your APIs:\n\n```python\nfrom neutronapi.openapi.openapi import OpenAPIGenerator\n\n# Basic API - automatically discovered\nclass UserAPI(API):\n    resource = \"/v1/users\"\n    name = \"users\"\n    \n    @API.endpoint(\"/\", methods=[\"GET\"], name=\"list\")\n    async def list_users(self, scope, receive, send, **kwargs):\n        return await self.response({\"users\": []})\n\n# Internal/debug API - hidden by default\nclass DebugAPI(API):\n    resource = \"/debug\"\n    name = \"debug\" \n    hidden = True  # Excluded from docs by default\n    \n    @API.endpoint(\"/status\", methods=[\"GET\"], name=\"status\")\n    async def debug_status(self, scope, receive, send, **kwargs):\n        return await self.response({\"debug\": True})\n\n# Generate public API docs (excludes hidden APIs)\nasync def generate_public_docs():\n    apis = {\"users\": UserAPI(), \"debug\": DebugAPI()}\n    \n    generator = OpenAPIGenerator(title=\"My API\", version=\"1.0.0\")\n    spec = await generator.generate(source=apis)\n    # Result: Only includes /v1/users endpoints\n    \n# Generate complete docs (includes everything)\nasync def generate_complete_docs():\n    apis = {\"users\": UserAPI(), \"debug\": DebugAPI()}\n    \n    generator = OpenAPIGenerator(\n        title=\"Complete API\",\n        include_all=True  # Include hidden APIs and private endpoints\n    )\n    spec = await generator.generate(source=apis)\n    # Result: Includes both /v1/users and /debug endpoints\n\n# Exclude specific patterns\nasync def generate_filtered_docs():\n    apis = {\"users\": UserAPI(), \"debug\": DebugAPI()}\n    \n    generator = OpenAPIGenerator(\n        title=\"Filtered API\",\n        exclude_patterns=[\"/debug/*\", \"/internal/*\"]\n    )\n    spec = await generator.generate(source=apis)\n\n# Convenience function for all endpoints\nfrom neutronapi.openapi.openapi import generate_all_endpoints_openapi\nspec = await generate_all_endpoints_openapi(apis, title=\"All Endpoints\")\n```\n\n**Why use `hidden=True`?**\n- Mark internal APIs (debugging, health checks, admin endpoints)\n- Keep them accessible but exclude from public documentation\n- Use `include_all=True` to generate complete internal docs\n\n## Why NeutronAPI?\n\n- **\ud83d\ude80 Performance**: Built on ASGI/uvicorn for maximum throughput\n- **\ud83c\udfd7\ufe0f Architecture**: Clean separation with universal dependency injection  \n- **\ud83d\udd12 Type Safety**: Comprehensive typing with IDE support\n- **\ud83d\udcda Auto Documentation**: OpenAPI 3.0 & Swagger 2.0 generation\n- **\ud83c\udfaf Developer Experience**: Rich error messages, validation, and documentation\n- **\ud83d\udce6 Batteries Included**: ORM, migrations, background tasks, middleware\n- **\ud83d\udd27 Production Ready**: Multi-worker support, monitoring, and deployment tools\n\nPerfect for building modern APIs, microservices, and high-performance web applications with automatic documentation.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A modern, high-performance ASGI-based Python web framework.",
    "version": "0.3.15",
    "project_urls": null,
    "split_keywords": [
        "api",
        " framework",
        " async",
        " fastapi",
        " uvicorn",
        " orm",
        " migrations",
        " background-tasks",
        " dependency-injection",
        " typing"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b8d5ecc6d3fa8c78968e4406434ba863ce76bdb994c91c1fdd77eec84050caf6",
                "md5": "1e77551bb9e77d7a711e1b96b054d964",
                "sha256": "3e8bf9fbd529788470c061aba8bfdf003b760eceb0520ad8da8b232138b8ed6c"
            },
            "downloads": -1,
            "filename": "neutronapi-0.3.15-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1e77551bb9e77d7a711e1b96b054d964",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 123727,
            "upload_time": "2025-09-13T18:11:09",
            "upload_time_iso_8601": "2025-09-13T18:11:09.096507Z",
            "url": "https://files.pythonhosted.org/packages/b8/d5/ecc6d3fa8c78968e4406434ba863ce76bdb994c91c1fdd77eec84050caf6/neutronapi-0.3.15-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "99e93e1dc3204e3fc23cde1fed6313b2ac81881bee1822e8a13f3124f1d410ba",
                "md5": "56559c100d709573364e358af9ffa0f1",
                "sha256": "dd56820d89213520676c95db23e954e56d3343a7ef4c0eec87b720898b51be6c"
            },
            "downloads": -1,
            "filename": "neutronapi-0.3.15.tar.gz",
            "has_sig": false,
            "md5_digest": "56559c100d709573364e358af9ffa0f1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 110322,
            "upload_time": "2025-09-13T18:11:10",
            "upload_time_iso_8601": "2025-09-13T18:11:10.663137Z",
            "url": "https://files.pythonhosted.org/packages/99/e9/3e1dc3204e3fc23cde1fed6313b2ac81881bee1822e8a13f3124f1d410ba/neutronapi-0.3.15.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-13 18:11:10",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "neutronapi"
}
        
Elapsed time: 1.64138s