> This page is for version v0.24.0.
> For other versions, use one of these documentation indexes:
> - Latest (default): https://docs.nvidia.com/nemo/guardrails/latest/llms.txt
> - v0.24.1: https://docs.nvidia.com/nemo/guardrails/v0.24.1/llms.txt
> - v0.24.0: https://docs.nvidia.com/nemo/guardrails/v0.24.0/llms.txt
> - v0.23.0: https://docs.nvidia.com/nemo/guardrails/v0.23.0/llms.txt
> - v0.22.0: https://docs.nvidia.com/nemo/guardrails/v0.22.0/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/guardrails/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/guardrails/_mcp/server.

# The Init Function for NeMo Guardrails

> Define the init() function to initialize resources and register action parameters at startup.

If `config.py` contains an `init` function, it is called during `LLMRails` initialization. Use it to set up shared resources and register action parameters.

> **Info**
>
> The `init` function **must be synchronous** (`def init`, not `async def init`). The framework calls it without `await`, so an async function would silently do nothing.

Any top-level code in `config.py` runs at import time, before `init()` is called. This can be used for provider registration that does not require the `LLMRails` instance.

## Basic Usage

```python
from nemoguardrails import LLMRails

def init(app: LLMRails):
    # Initialize database connection
    db = DatabaseConnection()

    # Register as action parameter (available to all actions)
    app.register_action_param("db", db)
```

## Registering Action Parameters

Action parameters registered in `config.py` are automatically injected into actions that declare them. The runtime matches parameters by name, i.e., the parameter name in the action must match the name used during registration.

**config.py:**

```python
import os

from nemoguardrails import LLMRails

def init(app: LLMRails):
    # Initialize shared resources
    db = DatabaseConnection(host="localhost", port=5432)
    api_client = ExternalAPIClient(api_key=os.environ.get("API_KEY"))

    # Register as action parameters
    app.register_action_param("db", db)
    app.register_action_param("api_client", api_client)
```

**actions.py:**

```python
from nemoguardrails.actions import action

@action()
async def fetch_user_data(user_id: str, db=None):
    """The 'db' parameter is injected from config.py."""
    return await db.get_user(user_id)

@action()
async def call_external_service(query: str, api_client=None):
    """The 'api_client' parameter is injected from config.py."""
    return await api_client.search(query)
```

## Built-in Action Parameters

In addition to parameters you register, the runtime automatically injects these built-in parameters into any action that declares them:

| Parameter          | Type             | Description                                          |
| ------------------ | ---------------- | ---------------------------------------------------- |
| `config`           | `RailsConfig`    | The full rails configuration object                  |
| `context`          | `dict`           | The current conversation context                     |
| `events`           | `list`           | The event history                                    |
| `llm`              | LLM instance     | The main LLM (auto-registered during initialization) |
| `llm_task_manager` | `LLMTaskManager` | Manages LLM task execution                           |

See [Custom Data](/configure-guardrails/custom-initialization/custom-data) for details on accessing `config.custom_data` inside actions.

## Accessing the Configuration

The `app` parameter provides access to the full configuration:

```python
def init(app: LLMRails):
    # Access the RailsConfig object
    config = app.config

    # Access custom data from config.yml
    custom_settings = config.custom_data

    # Access model configurations
    models = config.models
```

## Example: Database Connection

```python
import os
import psycopg2
from nemoguardrails import LLMRails

def init(app: LLMRails):
    # Create connection pool
    conn = psycopg2.connect(
        host=os.environ.get("DB_HOST", "localhost"),
        database=os.environ.get("DB_NAME", "mydb"),
        user=os.environ.get("DB_USER", "user"),
        password=os.environ.get("DB_PASSWORD"),
    )

    app.register_action_param("db_conn", conn)
```

## HTTP Client Lifecycle

The synchronous `init` function has no asynchronous teardown hook. Do not create a long-lived HTTP client in `init` unless another application component owns and closes it.

Create a shared canonical client at the surrounding application lifecycle boundary, register it as an action parameter, and close it at shutdown:

```python
from nemoguardrails import LLMRails, RailsConfig
from nemoguardrails.http import create_http_client


async def run():
    http_client = create_http_client(timeout=10.0)
    config = RailsConfig.from_path("config")
    app = LLMRails(config)
    app.register_action_param("http_client", http_client)

    try:
        return await app.generate_async(
            messages=[{"role": "user", "content": "Hello"}],
        )
    finally:
        await http_client.close()
```

Actions that accept `http_client: HTTPClient | None = None` can use a shared injected client or let `http_call` create and close a call-scoped fallback. For details, refer to [Outbound HTTP in Actions](/configure-guardrails/actions/outbound-http).