{"id":29861057,"url":"https://github.com/astralmortem/aiogram-dependency","last_synced_at":"2026-04-18T11:03:31.131Z","repository":{"id":305718940,"uuid":"1023785393","full_name":"AstralMortem/aiogram-dependency","owner":"AstralMortem","description":"A FastAPI-style dependency injection system for aiogram Telegram bots. This library brings clean, type-safe dependency injection to your aiogram handlers, making your code more modular, testable, and maintainable.","archived":false,"fork":false,"pushed_at":"2025-07-21T17:38:22.000Z","size":0,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-21T18:13:15.293Z","etag":null,"topics":["aiogram","dependency-injection","fastapi","telegram","telegrambot"],"latest_commit_sha":null,"homepage":"","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/AstralMortem.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}},"created_at":"2025-07-21T17:31:40.000Z","updated_at":"2025-07-21T17:41:49.000Z","dependencies_parsed_at":"2025-07-21T18:13:50.719Z","dependency_job_id":"c674afe4-9d1e-4861-9fac-89d7bc55c2fb","html_url":"https://github.com/AstralMortem/aiogram-dependency","commit_stats":null,"previous_names":["astralmortem/aiogram-dependency"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/AstralMortem/aiogram-dependency","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AstralMortem%2Faiogram-dependency","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AstralMortem%2Faiogram-dependency/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AstralMortem%2Faiogram-dependency/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AstralMortem%2Faiogram-dependency/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AstralMortem","download_url":"https://codeload.github.com/AstralMortem/aiogram-dependency/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AstralMortem%2Faiogram-dependency/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267808280,"owners_count":24147391,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["aiogram","dependency-injection","fastapi","telegram","telegrambot"],"created_at":"2025-07-30T04:11:51.578Z","updated_at":"2026-04-18T11:03:31.122Z","avatar_url":"https://github.com/AstralMortem.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Aiogram Dependency Injection\n\nA FastAPI-style dependency injection system for aiogram Telegram bots. This library brings clean, type-safe dependency injection to your aiogram handlers, making your code more modular, testable, and maintainable.\n\n[![PyPI Downloads](https://static.pepy.tech/badge/aiogram-dependency)](https://pepy.tech/projects/aiogram-dependency)\n## Features\n\n- **FastAPI-style syntax** - Familiar `Depends()` decorator\n- **Multiple dependency scopes** - Singleton, Request, and Transient\n- **Nested dependencies** - Dependencies can depend on other dependencies\n- **Async support** - Both sync and async dependency functions\n- **Circular dependency detection** - Prevents infinite loops\n- **Type-safe** - Full type hints support\n- **Smart caching** - Efficient resource management\n- **FastAPI Support** - Can use fastapi Depends instead default one\n## Installation\n\n```bash\npip install aiogram-dependency\n```\n\nOr install from source:\n\n```bash\ngit clone https://github.com/AstralMortem/aiogram-dependency\ncd aiogram-dependency\npip install -e .\n```\n\n## Quick Start\n\n```python\nimport asyncio\nfrom aiogram import Bot, Dispatcher, F\nfrom aiogram.types import Message\n\nfrom aiogram_dependency import Depends, setup_dependency, Scope\n\n# Define your dependencies\nclass DatabaseConnection:\n    def __init__(self, connection_string: str):\n        self.connection_string = connection_string\n    \n    async def query(self, sql: str):\n        # Your database logic here\n        return f\"Result for: {sql}\"\n\nclass UserService:\n    def __init__(self, db: DatabaseConnection):\n        self.db = db\n    \n    async def get_user_profile(self, user_id: int):\n        return await self.db.query(f\"SELECT * FROM users WHERE id = {user_id}\")\n\n# Dependency factories\nasync def get_database() -\u003e DatabaseConnection:\n    return DatabaseConnection(\"postgresql://localhost/mydb\")\n\nasync def get_user_service(\n    db: DatabaseConnection = Depends(get_database, scope=Scope.SINGLETON)\n) -\u003e UserService:\n    return UserService(db)\n\n# Handler with dependency injection\nasync def profile_handler(\n    message: Message,\n    user_service: UserService = Depends(get_user_service)\n):\n    if not message.from_user:\n        await message.answer(\"User not found\")\n        return\n    \n    profile = await user_service.get_user_profile(message.from_user.id)\n    await message.answer(f\"Your profile: {profile}\")\n\n# Setup bot (ORDER MATER!)\nasync def main():\n    bot = Bot(token=\"YOUR_BOT_TOKEN\")\n    dp = Dispatcher()\n    \n    # Register handlers\n    dp.message.register(profile_handler, F.text == \"/profile\")\n\n    # Register dependency injection \n    setup_dependency(dp)\n    \n    await dp.start_polling(bot)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## Dependency Scopes\n\n### Singleton\nCreated once and shared across all requests globally.\n\n```python\nasync def get_database() -\u003e DatabaseConnection:\n    return DatabaseConnection(\"connection_string\")\n\nasync def handler(\n    message: Message,\n    db: DatabaseConnection = Depends(get_database, scope=Scope.SINGLETON)\n):\n    # Same database instance for all users\n    pass\n```\n\n### Request (Default)\nCreated once per user/chat and cached for subsequent calls in the same context.\n\n```python\nasync def get_user_service() -\u003e UserService:\n    return UserService()\n\nasync def handler(\n    message: Message,\n    service: UserService = Depends(get_user_service, scope=Scope.REQUEST)\n):\n    # Same service instance for this user, different for other users\n    pass\n```\n\n### Transient\nCreated fresh every time it's requested.\n\n```python\nasync def get_timestamp() -\u003e float:\n    return time.time()\n\nasync def handler(\n    message: Message,\n    timestamp: float = Depends(get_timestamp, scope=Scope.TRANSIENT)\n):\n    # New timestamp every time\n    pass\n```\n\n## Advanced Usage\n\n### FastAPI\nYou can use FastAPI Depends to remove dupplication if you use fastapi as backend server\n\n### Annotated\n\nYou can use Annotated type to make it more readable.\n```python\nfrom typing import Annotated\nfrom aiogram_dependency import Depends\nfrom aiogram import Dispatcher,filters,types\n\nasync def get_database() -\u003e DatabaseConnection:\n    return DatabaseConnection(\"postgresql://localhost/db\")\n\nDatabaseDep = Annotated[DatabaseConnection, Depends(get_database)]\n\nasync def get_user(db: DatabaseDep):\n    return db.execute('SQL')\n\nUserDep = Annotated[dict, Depends(get_user)]\n\ndp = Dispatcher()\n\n@dp.message(filters.CommandStart())\nasync def start(message:types.Message, user: UserDep):\n    return await message.answer(user['username'])\n\n\n```\n\n\n### Nested Dependencies\n\nDependencies can depend on other dependencies:\n\n```python\nasync def get_database() -\u003e DatabaseConnection:\n    return DatabaseConnection(\"postgresql://localhost/db\")\n\nasync def get_user_repository(\n    db: DatabaseConnection = Depends(get_database)\n) -\u003e UserRepository:\n    return UserRepository(db)\n\nasync def get_user_service(\n    user_repo: UserRepository = Depends(get_user_repository),\n    notification_service: NotificationService = Depends(get_notification_service)\n) -\u003e UserService:\n    return UserService(user_repo, notification_service)\n```\n\n### Using Event Data in Dependencies\n\nDependencies can access the current event and handler data:\n\n```python\nasync def get_current_user(event: Message) -\u003e Optional[User]:\n    return event.from_user\n\nasync def get_user_permissions(\n    event: Message,\n    data: dict,\n    current_user: User = Depends(get_current_user)\n) -\u003e List[str]:\n    # Access event, data, and other dependencies\n    if current_user and current_user.id in data.get('admins', []):\n        return ['admin', 'user']\n    return ['user']\n\nasync def admin_handler(\n    message: Message,\n    permissions: List[str] = Depends(get_user_permissions)\n):\n    if 'admin' not in permissions:\n        await message.answer(\"Access denied\")\n        return\n    \n    await message.answer(\"Welcome, admin!\")\n```\n\n### Custom Registry and Resolver\n\nFor advanced use cases, you can customize the dependency system:\n\n```python\nfrom aiogram_dependency.registry import DependencyRegistry\nfrom aiogram_dependency.resolver import DependencyResolver\nfrom aiogram_dependency.middleware import DependencyMiddleware\nfrom aiogram_dependency import Scope\n\n# Create custom registry\nregistry = DependencyRegistry()\n\ndb_dep = Depends(get_database, scope=Scope.SINGLETON)\n\n# Pre-populate with some dependencies\nregistry.set_dependency(\n    db_dep,\n    DatabaseConnection(\"custom://connection\"),\n    \"global\"\n)\n\n# Use custom middleware\nmiddleware = DependencyMiddleware(registry)\ndp.message.middleware(middleware)\n```\n\n## Testing\n\nThe library is fully testable. Here's an example:\n\n\nRun the full test suite:\n\n```bash\n# Install test dependencies\npip install pytest pytest-asyncio\n\n# Run tests\npytest tests/ -v\n\n# Run with coverage\npytest tests/ --cov=aiogram_dependency --cov-report=html\n```\n\n\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n\n## Related Projects\n\n- [aiogram](https://github.com/aiogram/aiogram) - Modern and fully asynchronous framework for Telegram Bot API\n- [FastAPI](https://github.com/tiangolo/fastapi) - Modern, fast web framework for building APIs with Python\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastralmortem%2Faiogram-dependency","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fastralmortem%2Faiogram-dependency","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastralmortem%2Faiogram-dependency/lists"}