# Terminology and Glossary

This glossary defines terms used throughout the genro-asgi documentation. Understanding these terms is essential for contributors.

## Core Components

### AsgiServer

The ASGI entry point and orchestrator. Manages server lifecycle, configuration, and application mounting.

**Source**: `src/genro_asgi/server.py`

```python
class AsgiServer(RoutingClass):
    def __init__(self, server_dir=None, host=None, port=None, reload=None):
        self.config = ServerConfig(...)
        self.router = Router(self, name="root")
        self.apps: dict[str, AsgiApplication] = {}
        self.dispatcher = middleware_chain(...)
        self.lifespan = ServerLifespan(self)
```

**Key attributes**:

| Attribute | Type | Description |
| --------- | ---- | ----------- |
| `config` | `ServerConfig` | YAML + CLI configuration |
| `router` | `Router` | Root router (genro-routes) |
| `apps` | `dict[str, AsgiApplication]` | Mounted applications |
| `dispatcher` | `Middleware` | Middleware chain → Dispatcher |
| `lifespan` | `ServerLifespan` | Startup/shutdown handler |
| `storage` | `LocalStorage` | Filesystem access |
| `resource_loader` | `ResourceLoader` | Hierarchical resource loading |
| `request_registry` | `RequestRegistry` | In-flight request tracking |

### AsgiApplication

Base class for mountable applications. Each app is a self-contained unit with its own routes.

**Source**: `src/genro_asgi/application.py`

```python
class AsgiApplication(RoutingClass):
    openapi_info: ClassVar[dict] = {}

    def __init__(self, **kwargs):
        self.base_dir = kwargs.pop("base_dir", None)
        self.main = Router(self, name="main")
        self.on_init(**kwargs)
```

**Lifecycle hooks**:

| Hook | When Called | Signature |
| ---- | ----------- | --------- |
| `on_init()` | After `__init__` | `(**kwargs)` - receives config params |
| `on_startup()` | Server startup | `()` - sync or async |
| `on_shutdown()` | Server shutdown | `()` - sync or async |

### Dispatcher

Routes requests to the appropriate handler via the router tree.

**Source**: `src/genro_asgi/dispatcher.py`

```python
class Dispatcher:
    def __init__(self, server: AsgiServer):
        self.server = server

    async def __call__(self, scope, receive, send):
        # Create request, find handler, execute, send response
```

### Router

Instance-scoped routing engine from genro-routes. Maps paths to handlers.

```python
router = Router(self, name="root")
router.attach_instance(app, name="shop")  # /shop/* routes to app
node = router.node(path, method="GET", auth_tags=["user"])
```

## Request and Response

### BaseRequest

Abstract base for all request types. Provides uniform interface for HTTP and message-based requests.

**Source**: `src/genro_asgi/request.py`

```python
class BaseRequest:
    id: str                    # UUID generated by server
    scope: Scope               # ASGI scope
    server: AsgiServer         # Reference to server
    response: Response         # Response builder
```

### HttpRequest

HTTP request wrapper. Extends BaseRequest with HTTP-specific functionality.

```python
class HttpRequest(BaseRequest):
    method: str                # GET, POST, etc.
    path: str                  # /shop/products
    headers: Headers           # Request headers
    query_params: QueryParams  # URL query string
```

**Body access methods**:

| Method | Returns | Description |
| ------ | ------- | ----------- |
| `await body()` | `bytes` | Raw body |
| `await json()` | `dict` | JSON parsed body |
| `await form()` | `dict` | Form data |

### MsgRequest

Message-based request (e.g., from WebSocket WSX protocol).

```python
class MsgRequest(BaseRequest):
    data: dict                 # Message payload
    channel: str | None        # WSX channel
```

### Response

Response builder with auto content-type detection.

**Source**: `src/genro_asgi/response.py`

```python
response = Response(request)
response.set_result({"data": "value"})  # Auto JSON
response.set_result("<html>...")         # Auto HTML
response.set_cookie("session", "abc123")
```

### Handler

A method in an application class that processes a specific route.

```python
class MyApp(AsgiApplication):
    @route("main")
    def my_handler(self, name: str = "World"):
        return {"message": f"Hello, {name}!"}
```

### Endpoint

The combination of a path and its handler. Registered via `@route()` decorator.

```python
# Path: /shop/products
# Handler: ShopApp.products()
# Endpoint: route("main", name="products")
```

## Routing (genro-routes)

### RoutingClass

Mixin that tracks routers for an instance. Both AsgiServer and AsgiApplication extend this.

```python
from genro_routes import RoutingClass

class MyApp(RoutingClass):
    _routing_parent: RoutingClass | None  # Parent in routing tree
```

### @route Decorator

Registers methods as route handlers.

```python
@route("main")                    # Explicit router
@route()                          # Default router (if unambiguous)
@route("api", auth_tags="admin")  # With auth requirement
@route("api", name="list")        # Explicit handler name
```

### attach_instance

Connects a child RoutingClass to a parent router.

```python
self.router.attach_instance(app, name="shop")
# Now: /shop/* routes to app's handlers
```

## Infrastructure

### Middleware

ASGI middleware that wraps the request/response cycle.

**Available middleware**:

| Middleware | Purpose | Config key |
| ---------- | ------- | ---------- |
| `ErrorMiddleware` | Exception handling | `errors` |
| `CORSMiddleware` | Cross-origin headers | `cors` |
| `AuthMiddleware` | Authentication | `auth` |
| `CompressionMiddleware` | Gzip responses | `compression` |
| `LoggingMiddleware` | Request logging | `logging` |
| `CacheMiddleware` | Response caching | `cache` |

### Lifespan

ASGI protocol for server startup and shutdown events.

**Source**: `src/genro_asgi/lifespan.py`

```python
class ServerLifespan:
    async def startup(self):
        for app in self.server.apps.values():
            await smartasync(app.on_startup)()

    async def shutdown(self):
        for app in reversed(self.server.apps.values()):
            await smartasync(app.on_shutdown)()
```

### LocalStorage

Filesystem abstraction with mount points.

**Source**: `src/genro_asgi/storage.py`

```python
storage = LocalStorage(base_dir)
content = await storage.read("data/file.txt")
await storage.write("output/result.json", data)
```

### ResourceLoader

Hierarchical resource loading with fallback chain.

**Source**: `src/genro_asgi/resources.py`

```python
# Looks in: app resources → server resources → package resources
content, mime_type = resource_loader.load("shop", name="template.html")
```

### RequestRegistry

Tracks in-flight requests by UUID.

```python
registry = RequestRegistry()
request = registry.create(scope, receive, send)
current = registry.current  # ContextVar-based access
```

## WebSocket / WSX

### WebSocket

WebSocket connection wrapper.

**Source**: `src/genro_asgi/websocket.py`

```python
class WebSocket:
    async def accept(self):
        ...
    async def receive_json(self) -> dict:
        ...
    async def send_json(self, data: dict):
        ...
    async def close(self, code: int = 1000):
        ...
```

### WSX Protocol

RPC-over-WebSocket protocol for structured messaging.

**Source**: `src/genro_asgi/wsx/protocol.py`

```python
# Client sends:
{"method": "shop/products", "params": {"category": "books"}, "id": 1}

# Server responds:
{"result": [...], "id": 1}
```

### SubscriptionManager

Pub/sub for WebSocket channels (planned feature).

```python
manager.subscribe("user.updates", websocket.send_json)
await manager.publish("user.updates", {"status": "online"})
```

## Executors

### Executor

Runs blocking code without blocking the event loop.

**Source**: `src/genro_asgi/executors/`

| Executor | Use Case |
| -------- | -------- |
| `LocalExecutor` | ThreadPool for CPU-bound tasks |
| `ProcessExecutor` | ProcessPool for heavy computation |

```python
executor = LocalExecutor(max_workers=4)
result = await executor.run(blocking_function, arg1, arg2)
```

## Data Structures

### Headers

Immutable HTTP headers with case-insensitive access.

**Source**: `src/genro_asgi/datastructures/headers.py`

```python
headers = Headers(scope)
content_type = headers.get("content-type")
all_values = headers.getlist("accept")
```

### QueryParams

Parsed URL query string.

**Source**: `src/genro_asgi/datastructures/query_params.py`

```python
params = QueryParams(scope)
page = params.get("page", "1")
tags = params.getlist("tag")  # For repeated params
```

### URL

Parsed URL components.

**Source**: `src/genro_asgi/datastructures/url.py`

```python
url = URL(scope)
url.path      # /shop/products
url.query     # page=1&sort=name
url.hostname  # localhost
```

### State

Request-scoped key-value store for middleware communication.

**Source**: `src/genro_asgi/datastructures/state.py`

```python
scope["state"]["user_id"] = 123  # Set in AuthMiddleware
user_id = scope["state"]["user_id"]  # Read in handler
```

## Exceptions

### HTTPException

Base for HTTP error responses.

**Source**: `src/genro_asgi/exceptions.py`

```python
raise HTTPException(status_code=400, detail="Invalid input")
```

### Specialized Exceptions

| Exception | Status Code | Use Case |
| --------- | ----------- | -------- |
| `HTTPNotFound` | 404 | Resource not found |
| `HTTPUnauthorized` | 401 | Missing authentication |
| `HTTPForbidden` | 403 | Insufficient permissions |
| `Redirect` | 301/302/307 | URL redirection |

## Configuration

### ServerConfig

Parses and merges YAML config with CLI arguments.

**Source**: `src/genro_asgi/server_config.py`

```python
config = ServerConfig(server_dir=".", host="0.0.0.0", port=9000)
config.server["host"]        # "0.0.0.0" (CLI override)
config.middleware            # {"cors": "on", ...}
config.get_app_specs()       # {name: (cls, kwargs), ...}
```

### SmartOptions

genro-toolbox utility for YAML with merge semantics.

```yaml
# base.yaml
middleware:
  errors: on

# override.yaml
middleware:
  +cors: on  # Merge, don't replace
```

## ASGI Types

Standard ASGI protocol types:

| Type | Description |
| ---- | ----------- |
| `Scope` | `dict[str, Any]` - Connection metadata |
| `Receive` | `Callable[[], Awaitable[Message]]` - Receive messages |
| `Send` | `Callable[[Message], Awaitable[None]]` - Send messages |
| `Message` | `dict[str, Any]` - ASGI message |
| `ASGIApp` | `Callable[[Scope, Receive, Send], Awaitable[None]]` |

## Related Documents

- [Vision and Goals](01_vision_and_goals.md) - Project overview
- [Core Principles](02_core_principles.md) - Architectural principles
- [Quick Start for Contributors](04_quick_start.md) - Development setup
