{"id":35313833,"url":"https://github.com/pavalso/awioc","last_synced_at":"2026-01-13T21:49:24.388Z","repository":{"id":329320825,"uuid":"1117566094","full_name":"pavalso/awioc","owner":"pavalso","description":null,"archived":false,"fork":false,"pushed_at":"2025-12-30T16:56:21.000Z","size":586,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-03T09:42:00.723Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pavalso.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-16T13:49:10.000Z","updated_at":"2025-12-20T14:20:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pavalso/awioc","commit_stats":null,"previous_names":["pavalso/awioc"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pavalso/awioc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavalso%2Fawioc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavalso%2Fawioc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavalso%2Fawioc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavalso%2Fawioc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pavalso","download_url":"https://codeload.github.com/pavalso/awioc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavalso%2Fawioc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28401113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-30T18:14:22.647Z","updated_at":"2026-01-13T21:49:24.381Z","avatar_url":"https://github.com/pavalso.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# awioc\n\nA modern, async-first Inversion of Control (IoC) and Dependency Injection (DI) framework for Python applications.\n\n[![Python Version](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/)\n[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Core Concepts](#core-concepts)\n    - [Components](#components)\n    - [Dependency Injection](#dependency-injection)\n    - [Configuration](#configuration)\n    - [Lifecycle Management](#lifecycle-management)\n- [Architecture](#architecture)\n- [API Reference](#api-reference)\n- [Configuration Files](#configuration-files)\n- [CLI Usage](#cli-usage)\n- [Testing](#testing)\n- [Examples](#examples)\n\n## Overview\n\n**awioc** is a comprehensive IoC/DI framework designed for building modular, testable, and maintainable Python\napplications. It provides a protocol-based component system with full async/await support, automatic dependency\nresolution, and flexible configuration management.\n\nThe framework follows the Inversion of Control principle, allowing you to define components with their dependencies\ndeclaratively and letting the framework handle instantiation, initialization, and lifecycle management.\n\n## Features\n\n- **Protocol-Based Components**: Define components using Python protocols without inheritance constraints\n- **Async-First Lifecycle**: Full async/await support for component initialization, execution, and shutdown\n- **Automatic Dependency Resolution**: Components declare dependencies; the framework handles initialization order\n- **Flexible Configuration**: Support for YAML/JSON files, environment variables, and Pydantic models\n- **Dynamic Module Loading**: Load components from arbitrary file paths at runtime\n- **Plugin Architecture**: Runtime registration and unregistration of plugin components\n- **Comprehensive DI Providers**: Easy-to-use injection functions for libraries, configuration, and logging\n- **CLI Interface**: Run applications directly with the `awioc` command\n\n## Installation\n\n```bash\npip install awioc\n```\n\nOr install from source:\n\n```bash\ngit clone https://github.com/pavalso/awioc.git\ncd awioc\npip install -e .\n```\n\n### Dependencies\n\n- Python 3.11+\n- pydantic ~= 2.12.4\n- PyYAML ~= 6.0.3\n- pydantic-settings ~= 2.12.0\n- dependency-injector\n- cachetools ~= 6.2.3\n\n## Quick Start\n\n### 1. Define a Component\n\nCreate a file `my_app.py`:\n\n```python\nimport asyncio\nfrom ioc import get_config, get_logger, inject\nimport pydantic\n\n\n# Define configuration model\nclass AppConfig(pydantic.BaseModel):\n    __prefix__ = \"my_app_config\"\n    name: str = \"MyApp\"\n    debug: bool = False\n\n\n# Module-level metadata (required for component registration)\n__metadata__ = {\n    \"name\": \"my_app\",\n    \"version\": \"1.0.0\",\n    \"description\": \"My Application\",\n    \"wire\": True,\n    \"config\": AppConfig\n}\n\n\n# Define the application component\nclass MyApp:\n\n    @inject\n    async def initialize(\n            self,\n            logger=get_logger(),\n            config=get_config(AppConfig)\n    ) -\u003e None:\n        self.logger = logger\n        self.config = config\n        self.logger.info(f\"Starting {config.name}...\")\n\n    async def wait(self) -\u003e None:\n        \"\"\"Keep the application running.\"\"\"\n        while True:\n            await asyncio.sleep(1)\n\n    async def shutdown(self) -\u003e None:\n        self.logger.info(\"Shutting down...\")\n\n\n# Create instance and export lifecycle methods\nmy_app = MyApp()\ninitialize = my_app.initialize\nshutdown = my_app.shutdown\nwait = my_app.wait\n```\n\n### 2. Create Configuration\n\nCreate `ioc.yaml`:\n\n```yaml\napp: my_app\n\nmy_app_config:\n  name: \"My Awesome App\"\n  debug: true\n```\n\n### 3. Run the Application\n\n```bash\nawioc\n```\n\nOr with verbose logging:\n\n```bash\nawioc -vv\n```\n\n## Core Concepts\n\n### Components\n\nComponents are the building blocks of an awioc application. The framework defines three component types:\n\n#### AppComponent\n\nThe main application entry point. Requires `initialize` and `shutdown` methods.\n\n```python\n# my_app.py\n\n# Module-level metadata (required)\n__metadata__ = {\n    \"name\": \"my_app\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Main application\"\n}\n\n\nclass MyApp:\n\n    async def initialize(self) -\u003e None:\n        \"\"\"Called when application starts.\"\"\"\n        pass\n\n    async def shutdown(self) -\u003e None:\n        \"\"\"Called when application stops.\"\"\"\n        pass\n\n    async def wait(self) -\u003e None:\n        \"\"\"Optional: keeps the application running.\"\"\"\n        pass\n\n\n# Export lifecycle methods at module level\nmy_app = MyApp()\ninitialize = my_app.initialize\nshutdown = my_app.shutdown\nwait = my_app.wait\n```\n\n#### PluginComponent\n\nOptional extensions that can be registered/unregistered at runtime.\n\n```python\n# my_plugin.py\n\n# Module-level metadata (required)\n__metadata__ = {\n    \"name\": \"my_plugin\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Optional plugin\"\n}\n\n\nclass MyPlugin:\n\n    async def initialize(self) -\u003e None:\n        pass\n\n    async def shutdown(self) -\u003e None:\n        pass\n\n\n# Export lifecycle methods at module level\nmy_plugin = MyPlugin()\ninitialize = my_plugin.initialize\nshutdown = my_plugin.shutdown\n```\n\n#### LibraryComponent\n\nReusable libraries that provide shared functionality.\n\n```python\n# database_lib.py\n\n# Module-level metadata (required)\n__metadata__ = {\n    \"name\": \"database\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Database connection library\"\n}\n\n\nclass DatabaseLibrary:\n\n    async def initialize(self) -\u003e None:\n        self.connection = await create_connection()\n\n    async def shutdown(self) -\u003e None:\n        await self.connection.close()\n\n    async def query(self, sql: str):\n        return await self.connection.execute(sql)\n\n\n# Export lifecycle methods at module level\ndatabase = DatabaseLibrary()\ninitialize = database.initialize\nshutdown = database.shutdown\n```\n\n#### Component Metadata\n\nEvery component module must have a `__metadata__` attribute defined at the **module level** (not inside a class). The\nframework loads modules as components, so the metadata must be accessible directly on the module object.\n\n| Field         | Type             | Required | Description                           |\n|---------------|------------------|----------|---------------------------------------|\n| `name`        | `str`            | Yes      | Unique component identifier           |\n| `version`     | `str`            | Yes      | Semantic version string               |\n| `description` | `str`            | Yes      | Human-readable description            |\n| `wire`        | `bool`           | No       | Enable auto-wiring for this component |\n| `wirings`     | `set[str]`       | No       | Additional modules to wire            |\n| `requires`    | `set[Component]` | No       | Component dependencies                |\n| `config`      | `BaseModel`      | No       | Configuration model class             |\n\n### Dependency Injection\n\nawioc provides several provider functions for dependency injection:\n\n#### Injecting Libraries\n\n```python\nfrom ioc import get_library, inject\n\n\n@inject\nasync def my_function(db=get_library(\"database\")):\n    result = await db.query(\"SELECT * FROM users\")\n```\n\n#### Injecting Configuration\n\n```python\nfrom ioc import get_config, inject\nimport pydantic\n\n\nclass ServerConfig(pydantic.BaseModel):\n    __prefix__ = \"server\"\n    host: str = \"localhost\"\n    port: int = 8080\n\n\n@inject\nasync def start_server(config=get_config(ServerConfig)):\n    print(f\"Starting on {config.host}:{config.port}\")\n```\n\n#### Injecting Logger\n\n```python\nfrom ioc import get_logger, inject\n\n\n@inject\ndef process_data(logger=get_logger()):\n    # Logger automatically uses caller's module name\n    logger.info(\"Processing data...\")\n```\n\n#### Available Providers\n\n| Function              | Description                                          |\n|-----------------------|------------------------------------------------------|\n| `get_library(type_)`  | Get a registered library by type or name             |\n| `get_config(model)`   | Get configuration for a Pydantic model               |\n| `get_logger(*name)`   | Get a logger (auto-detects caller module if no name) |\n| `get_app()`           | Get the main application component                   |\n| `get_container_api()` | Get the container interface                          |\n| `get_raw_container()` | Get the underlying DI container                      |\n\n### Configuration\n\nConfiguration in awioc follows a layered approach:\n\n#### 1. Pydantic Models\n\nDefine configuration schemas using Pydantic:\n\n```python\nimport pydantic\n\n\nclass DatabaseConfig(pydantic.BaseModel):\n    __prefix__ = \"database\"  # Environment variable prefix\n\n    host: str = \"localhost\"\n    port: int = 5432\n    name: str = \"mydb\"\n    user: str = \"admin\"\n    password: str = \"\"\n```\n\n#### 2. Configuration Registration\n\nRegister configuration models via component metadata:\n\n```python\nfrom ioc import register_configuration\n\n\n@register_configuration\nclass MyConfig(pydantic.BaseModel):\n    __prefix__ = \"myapp\"\n    setting: str = \"default\"\n\n\nclass MyComponent:\n    __metadata__ = {\n        \"name\": \"my_component\",\n        \"config\": MyConfig  # Auto-registered\n    }\n```\n\n#### 3. Configuration Sources\n\nConfiguration values are loaded from (in order of precedence):\n\n1. **Environment Variables**: `DATABASE_HOST=localhost`\n2. **Context-specific .env files**: `.production.env`, `.development.env`\n3. **YAML/JSON configuration files**: `ioc.yaml` or `ioc.json`\n\n#### 4. IOC Base Configuration\n\nThe framework itself is configured via `IOCBaseConfig`:\n\n| Variable             | Description                       | Default    |\n|----------------------|-----------------------------------|------------|\n| `IOC_CONFIG_PATH`    | Path to component definition file | `ioc.yaml` |\n| `IOC_CONTEXT`        | Environment context               | None       |\n| `IOC_LOGGING_CONFIG` | Path to logging INI file          | None       |\n| `IOC_VERBOSE`        | Verbosity level (0-3)             | 0          |\n\n### Lifecycle Management\n\nComponents follow a three-phase lifecycle:\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                     APPLICATION LIFECYCLE                    │\n├─────────────────────────────────────────────────────────────┤\n│                                                             │\n│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐  │\n│  │ INITIALIZE   │───▶│    WAIT      │───▶│  SHUTDOWN    │  │\n│  │              │    │              │    │              │  │\n│  │ • Libraries  │    │ • App runs   │    │ • Plugins    │  │\n│  │ • Plugins    │    │ • Handle     │    │ • Libraries  │  │\n│  │ • App        │    │   requests   │    │ • App        │  │\n│  └──────────────┘    └──────────────┘    └──────────────┘  │\n│                                                             │\n└─────────────────────────────────────────────────────────────┘\n```\n\n#### Initialization Order\n\n1. Libraries (in dependency order)\n2. Plugins (parallel)\n3. Application\n\n#### Shutdown Order\n\n1. Application\n2. Plugins (parallel)\n3. Libraries (reverse dependency order)\n\n#### Programmatic Lifecycle Control\n\n```python\nfrom ioc import (\n    initialize_ioc_app,\n    compile_ioc_app,\n    initialize_components,\n    wait_for_components,\n    shutdown_components\n)\n\n\nasync def main():\n    # Initialize framework\n    api = initialize_ioc_app()\n    compile_ioc_app(api)\n\n    app = api.provided_app()\n    libs = api.provided_libs()\n    plugins = api.provided_plugins()\n\n    try:\n        # Start components\n        await initialize_components(app)\n        await initialize_components(*libs)\n        await initialize_components(*plugins)\n\n        # Run\n        await wait_for_components(app)\n    finally:\n        # Cleanup\n        await shutdown_components(*plugins)\n        await shutdown_components(*libs)\n        await shutdown_components(app)\n```\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                         awioc Framework                          │\n├─────────────────────────────────────────────────────────────────┤\n│                                                                  │\n│  ┌──────────────────────────────────────────────────────────┐   │\n│  │                      Public API (api.py)                  │   │\n│  │  • Bootstrap functions    • Lifecycle functions          │   │\n│  │  • DI providers           • Configuration utilities      │   │\n│  └──────────────────────────────────────────────────────────┘   │\n│                              │                                   │\n│         ┌────────────────────┼────────────────────┐             │\n│         │                    │                    │             │\n│         ▼                    ▼                    ▼             │\n│  ┌─────────────┐     ┌─────────────┐     ┌─────────────┐       │\n│  │ Components  │     │  Container  │     │   Config    │       │\n│  │             │     │             │     │             │       │\n│  │ • Protocols │     │ • AppCont.  │     │ • Settings  │       │\n│  │ • Metadata  │     │ • Interface │     │ • Loaders   │       │\n│  │ • Registry  │     │ • Providers │     │ • Registry  │       │\n│  │ • Lifecycle │     │             │     │ • Models    │       │\n│  └─────────────┘     └─────────────┘     └─────────────┘       │\n│         │                    │                    │             │\n│         └────────────────────┼────────────────────┘             │\n│                              │                                   │\n│                              ▼                                   │\n│  ┌──────────────────────────────────────────────────────────┐   │\n│  │                    Bootstrap (bootstrap.py)               │   │\n│  │  • Container creation     • IOC initialization           │   │\n│  │  • Component compilation  • Configuration loading        │   │\n│  └──────────────────────────────────────────────────────────┘   │\n│                              │                                   │\n│         ┌────────────────────┼────────────────────┐             │\n│         ▼                    ▼                    ▼             │\n│  ┌─────────────┐     ┌─────────────┐     ┌─────────────┐       │\n│  │     DI      │     │   Loader    │     │    Utils    │       │\n│  │             │     │             │     │             │       │\n│  │ • Providers │     │ • Dynamic   │     │ • Paths     │       │\n│  │ • Wiring    │     │   loading   │     │ • Merging   │       │\n│  └─────────────┘     └─────────────┘     └─────────────┘       │\n│                                                                  │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### Module Structure\n\n```\nsrc/ioc/\n├── __init__.py          # Public exports\n├── __main__.py          # CLI entry point\n├── api.py               # Public API surface\n├── bootstrap.py         # Application initialization\n├── container.py         # DI container implementation\n├── utils.py             # Utility functions\n│\n├── components/          # Component system\n│   ├── protocols.py     # Component protocols (Component, App, Plugin, Library)\n│   ├── metadata.py      # Metadata structures and types\n│   ├── registry.py      # Component registration utilities\n│   └── lifecycle.py     # Initialization/shutdown management\n│\n├── config/              # Configuration management\n│   ├── base.py          # Settings base class\n│   ├── models.py        # IOC configuration models\n│   ├── loaders.py       # YAML/JSON file loaders\n│   ├── registry.py      # Configuration registration\n│   └── setup.py         # Logging setup\n│\n├── di/                  # Dependency Injection\n│   ├── providers.py     # DI provider functions\n│   └── wiring.py        # Module wiring utilities\n│\n└── loader/              # Dynamic loading\n    └── module_loader.py # Component compilation\n```\n\n## API Reference\n\n### Bootstrap Functions\n\n```python\nfrom ioc import (\n    initialize_ioc_app,\n    create_container,\n    compile_ioc_app,\n    reconfigure_ioc_app,\n    reload_configuration\n)\n\n# Initialize full IOC application\napi = initialize_ioc_app()\n\n# Create empty container\ncontainer = create_container()\n\n# Compile components into container\ncompile_ioc_app(api)\n\n# Reconfigure with current components\nreconfigure_ioc_app(api)\n\n# Reload configuration at runtime\nreload_configuration(api)\n```\n\n### Lifecycle Functions\n\n```python\nfrom ioc import (\n    initialize_components,\n    shutdown_components,\n    wait_for_components,\n    register_plugin,\n    unregister_plugin\n)\n\n# Initialize one or more components\nawait initialize_components(component1, component2)\n\n# Shutdown components\nawait shutdown_components(component1, component2)\n\n# Wait for component completion\nawait wait_for_components(app)\n\n# Runtime plugin management\nregister_plugin(api, plugin)\nunregister_plugin(api, plugin)\n```\n\n### Container Interface\n\n```python\nfrom ioc import ContainerInterface\n\napi: ContainerInterface\n\n# Access components\napp = api.provided_app()\nlibs = api.provided_libs()\nplugins = api.provided_plugins()\n\n# Access configuration\nconfig = api.provided_config(MyConfigModel)\n\n# Access logger\nlogger = api.provided_logger()\n```\n\n### Component Utilities\n\n```python\nfrom ioc import (\n    as_component,\n    component_requires,\n    component_internals,\n    component_str,\n    compile_component\n)\n\n# Convert object to component\ncomponent = as_component(my_object)\n\n# Get component dependencies\ndeps = component_requires(component, recursive=True)\n\n# Access internal state\ninternals = component_internals(component)\n\n# Load component from path\ncomponent = compile_component(Path(\"./my_component.py\"))\n```\n\n## Configuration Files\n\n### ioc.yaml\n\nThe main configuration file defines components and their settings:\n\n```yaml\n# Component definitions\napp: path/to/app_module\n\nlibraries:\n  database: path/to/database_lib\n  cache: path/to/cache_lib\n\nplugins:\n  - path/to/plugin_a\n  - path/to/plugin_b\n\n# Component configuration (matches __prefix__ in config models)\ndatabase:\n  host: localhost\n  port: 5432\n  name: production_db\n\ncache:\n  backend: redis\n  ttl: 3600\n\napp:\n  debug: false\n  workers: 4\n```\n\n### Environment Variables\n\nEnvironment variables override file configuration:\n\n```bash\n# Set via environment\nexport DATABASE_HOST=production-db.example.com\nexport DATABASE_PORT=5432\nexport APP_DEBUG=false\n\n# Or use context-specific .env files\n# .production.env\nDATABASE_HOST=production-db.example.com\nAPP_DEBUG=false\n```\n\n### Logging Configuration\n\nCreate a logging INI file for advanced logging:\n\n```ini\n[loggers]\nkeys = root,ioc,myapp\n\n[handlers]\nkeys = console,file\n\n[formatters]\nkeys = detailed\n\n[logger_root]\nlevel = INFO\nhandlers = console\n\n[logger_ioc]\nlevel = DEBUG\nhandlers = console,file\nqualname = ioc\n\n[logger_myapp]\nlevel = DEBUG\nhandlers = console\nqualname = myapp\n\n[handler_console]\nclass = StreamHandler\nlevel = DEBUG\nformatter = detailed\nargs = (sys.stdout,)\n\n[handler_file]\nclass = FileHandler\nlevel = DEBUG\nformatter = detailed\nargs = ('app.log', 'a')\n\n[formatter_detailed]\nformat = %(asctime)s - %(name)s - %(levelname)s - %(message)s\n```\n\n## CLI Usage\n\nThe `awioc` command runs your application:\n\n```bash\n# Run with default settings\nawioc\n\n# Verbose output (INFO level)\nawioc -v\n\n# Debug output (DEBUG level)\nawioc -vv\n\n# Full debug including library logs\nawioc -vvv\n\n# Specify configuration file\nIOC_CONFIG_PATH=./config/app.yaml\n\n# Use environment context\nIOC_CONTEXT=production\n\n# Custom logging configuration\nIOC_LOGGING_CONFIG=./logging.ini\n```\n\n## Testing\n\nRun the test suite:\n\n```bash\n# Install test dependencies\npip install -r requirements-test.txt\n\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=ioc --cov-report=html\n\n# Run specific test module\npytest tests/ioc/test_container.py\n\n# Run with verbose output\npytest -v\n```\n\n### Writing Tests\n\n```python\nimport pytest\nfrom ioc import create_container, as_component\n\n\n@pytest.fixture\ndef container():\n    return create_container()\n\n\n@pytest.fixture\ndef sample_component():\n    class TestComponent:\n        __metadata__ = {\n            \"name\": \"test\",\n            \"version\": \"1.0.0\",\n            \"description\": \"Test component\"\n        }\n\n        async def initialize(self):\n            pass\n\n        async def shutdown(self):\n            pass\n\n    return as_component(TestComponent())\n\n\nasync def test_component_initialization(container, sample_component):\n    from ioc import initialize_components\n    result = await initialize_components(sample_component)\n    assert result is True\n```\n\n## Examples\n\n### HTTP Server\n\nSee the complete example in `samples/http_server/`:\n\n```python\n# samples/http_server/http_server.py\nimport asyncio\nfrom ioc import get_config, get_logger, inject\nimport pydantic\n\n\nclass ServerConfig(pydantic.BaseModel):\n    __prefix__ = \"server\"\n    host: str = \"127.0.0.1\"\n    port: int = 8080\n\n\n# Module-level metadata (required)\n__metadata__ = {\n    \"name\": \"http_server_app\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Simple HTTP Server\",\n    \"wire\": True,\n    \"config\": ServerConfig\n}\n\n\nclass HttpServerApp:\n\n    @inject\n    async def initialize(\n            self,\n            logger=get_logger(),\n            config=get_config(ServerConfig)\n    ) -\u003e None:\n        self.logger = logger\n        self.config = config\n        self.logger.info(f\"Starting server on {config.host}:{config.port}\")\n\n    async def wait(self) -\u003e None:\n        while True:\n            await asyncio.sleep(1)\n\n    async def shutdown(self) -\u003e None:\n        self.logger.info(\"Server stopped\")\n\n\n# Export lifecycle methods at module level\nhttp_server_app = HttpServerApp()\ninitialize = http_server_app.initialize\nshutdown = http_server_app.shutdown\nwait = http_server_app.wait\n```\n\n### Multi-Component Application\n\n```python\n# database_lib.py\n\n# Module-level metadata (required)\n__metadata__ = {\n    \"name\": \"database\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Database connection library\"\n}\n\nclass DatabaseLibrary:\n\n    async def initialize(self):\n        self.pool = await create_pool()\n\n    async def shutdown(self):\n        await self.pool.close()\n\n    async def query(self, sql):\n        async with self.pool.acquire() as conn:\n            return await conn.fetch(sql)\n\n# Export lifecycle methods at module level\ndatabase = DatabaseLibrary()\ninitialize = database.initialize\nshutdown = database.shutdown\n```\n\n```python\n# app.py\nfrom ioc import get_library, inject\n\n# Module-level metadata (required)\n__metadata__ = {\n    \"name\": \"my_app\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Application with database\",\n    \"requires\": {database}\n}\n\nclass MyApp:\n\n    @inject\n    async def initialize(self, db=get_library(\"database\")):\n        self.db = db\n        users = await self.db.query(\"SELECT * FROM users\")\n\n# Export lifecycle methods at module level\nmy_app = MyApp()\ninitialize = my_app.initialize\n```\n\n## License\n\nMIT License - see [LICENSE](LICENSE) for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit issues and pull requests.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## Links\n\n- [GitHub Repository](https://github.com/pavalso/awioc)\n- [Issue Tracker](https://github.com/pavalso/awioc/issues)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavalso%2Fawioc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpavalso%2Fawioc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavalso%2Fawioc/lists"}