- Add selectinload for episode relationship in get_all() - Prevents MissingGreenlet error during queue initialization - Both series and episode are now eagerly loaded
60 KiB
Aniworld Web Application Development Instructions
This document provides detailed tasks for AI agents to implement a modern web application for the Aniworld anime download manager. All tasks should follow the coding guidelines specified in the project's copilot instructions.
Project Overview
The goal is to create a FastAPI-based web application that provides a modern interface for the existing Aniworld anime download functionality. The core anime logic should remain in SeriesApp.py while the web layer provides REST API endpoints and a responsive UI.
Architecture Principles
- Single Responsibility: Each file/class has one clear purpose
- Dependency Injection: Use FastAPI's dependency system
- Clean Separation: Web layer calls core logic, never the reverse
- File Size Limit: Maximum 500 lines per file
- Type Hints: Use comprehensive type annotations
- Error Handling: Proper exception handling and logging
Additional Implementation Guidelines
Code Style and Standards
- Type Hints: Use comprehensive type annotations throughout all modules
- Docstrings: Follow PEP 257 for function and class documentation
- Error Handling: Implement custom exception classes with meaningful messages
- Logging: Use structured logging with appropriate log levels
- Security: Validate all inputs and sanitize outputs
- Performance: Use async/await patterns for I/O operations
📞 Escalation
If you encounter:
- Architecture issues requiring design decisions
- Tests that conflict with documented requirements
- Breaking changes needed
- Unclear requirements or expectations
Document the issue and escalate rather than guessing.
<EFBFBD> Credentials
Admin Login:
- Username:
admin - Password:
Hallo123!
<EFBFBD>📚 Helpful Commands
# Run all tests
conda run -n AniWorld python -m pytest tests/ -v --tb=short
# Run specific test file
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py -v
# Run specific test class
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py::TestWebSocketService -v
# Run specific test
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py::TestWebSocketService::test_broadcast_download_progress -v
# Run with extra verbosity
conda run -n AniWorld python -m pytest tests/ -vv
# Run with full traceback
conda run -n AniWorld python -m pytest tests/ -v --tb=long
# Run and stop at first failure
conda run -n AniWorld python -m pytest tests/ -v -x
# Run tests matching pattern
conda run -n AniWorld python -m pytest tests/ -v -k "auth"
# Show all print statements
conda run -n AniWorld python -m pytest tests/ -v -s
#Run app
conda run -n AniWorld python -m uvicorn src.server.fastapi_app:app --host 127.0.0.1 --port 8000 --reload
Implementation Notes
- Incremental Development: Implement features incrementally, testing each component thoroughly before moving to the next
- Code Review: Review all generated code for adherence to project standards
- Documentation: Document all public APIs and complex logic
- Testing: Maintain test coverage above 80% for all new code
- Performance: Profile and optimize critical paths, especially download and streaming operations
- Security: Regular security audits and dependency updates
- Monitoring: Implement comprehensive monitoring and alerting
- Maintenance: Plan for regular maintenance and updates
Task Completion Checklist
For each task completed:
- Implementation follows coding standards
- Unit tests written and passing
- Integration tests passing
- Documentation updated
- Error handling implemented
- Logging added
- Security considerations addressed
- Performance validated
- Code reviewed
- Task marked as complete in instructions.md
- Infrastructure.md updated and other docs
- Changes committed to git; keep your messages in git short and clear
- Take the next task
TODO List:
- fix issue: 2026-01-23 18:28:39 [info ] DownloadService initialized maxretries=3 INFO: QueueRepository initialized ERROR: Failed to get all items: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s) 2026-01-23 18:28:39 [error ] Failed to load queue from database: Failed to get all items: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s) ╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮ │ /home/lukas/Volume/repo/Aniworld/src/server/services/queue_repository.py:292 in get_all_items │ │ │ │ 289 │ │ │ db_items = await DownloadQueueService.get_all( │ │ 290 │ │ │ │ session, with_series=True │ │ 291 │ │ │ ) │ │ ❱ 292 │ │ │ return [self._from_db_model(item) for item in db_items] │ │ 293 │ │ │ │ 294 │ │ except Exception as e: │ │ 295 │ │ │ logger.error("Failed to get all items: %s", e) │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ db = None │ │ │ │ db_items = [ │ │ │ │ │ <DownloadQueueItem(id=8, series_id=146, episode_id=26)>, │ │ │ │ │ <DownloadQueueItem(id=9, series_id=146, episode_id=27)>, │ │ │ │ │ <DownloadQueueItem(id=10, series_id=146, episode_id=28)>, │ │ │ │ │ <DownloadQueueItem(id=11, series_id=146, episode_id=29)>, │ │ │ │ │ <DownloadQueueItem(id=12, series_id=146, episode_id=30)>, │ │ │ │ │ <DownloadQueueItem(id=13, series_id=146, episode_id=31)>, │ │ │ │ │ <DownloadQueueItem(id=14, series_id=146, episode_id=32)>, │ │ │ │ │ <DownloadQueueItem(id=15, series_id=146, episode_id=33)>, │ │ │ │ │ <DownloadQueueItem(id=16, series_id=83, episode_id=1)>, │ │ │ │ │ <DownloadQueueItem(id=17, series_id=83, episode_id=2)>, │ │ │ │ │ ... +21 │ │ │ │ ] │ │ │ │ manage_session = True │ │ │ │ self = <src.server.services.queue_repository.QueueRepository object at │ │ │ │ 0x7ed67ca6b770> │ │ │ │ session = <sqlalchemy.ext.asyncio.session.AsyncSession object at 0x7ed67caf4e90> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/Volume/repo/Aniworld/src/server/services/queue_repository.py:97 in _from_db_model │ │ │ │ 94 │ │ │ Pydantic download item with default status/priority │ │ 95 │ │ """ │ │ 96 │ │ # Get episode info from the related Episode object │ │ ❱ 97 │ │ episode = db_item.episode │ │ 98 │ │ series = db_item.series │ │ 99 │ │ │ │ 100 │ │ episode_identifier = EpisodeIdentifier( │ │ │ │ ╭───────────────────────────────────────── locals ──────────────────────────────────────────╮ │ │ │ db_item = <DownloadQueueItem(id=8, series_id=146, episode_id=26)> │ │ │ │ item_id = None │ │ │ │ self = <src.server.services.queue_repository.QueueRepository object at 0x7ed67ca6b770> │ │ │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/attributes.py:5 │ │ 69 in get │ │ │ │ 566 │ │ │ │ state = instance_state(instance) │ │ 567 │ │ │ except AttributeError as err: │ │ 568 │ │ │ │ raise orm_exc.UnmappedInstanceError(instance) from err │ │ ❱ 569 │ │ │ return self.impl.get(state, dict) # type: ignore[no-any-return] │ │ 570 │ │ 571 │ │ 572 @dataclasses.dataclass(frozen=True) │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ dict* = { │ │ │ │ │ '_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>, │ │ │ │ │ 'id': 8, │ │ │ │ │ 'error_message': None, │ │ │ │ │ 'file_destination': None, │ │ │ │ │ 'completed_at': None, │ │ │ │ │ 'updated_at': datetime.datetime(2026, 1, 23, 17, 10, 47), │ │ │ │ │ 'series_id': 146, │ │ │ │ │ 'episode_id': 26, │ │ │ │ │ 'download_url': None, │ │ │ │ │ 'started_at': None, │ │ │ │ │ ... +2 │ │ │ │ } │ │ │ │ instance = <DownloadQueueItem(id=8, series_id=146, episode_id=26)> │ │ │ │ self = <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7ed681867b00> │ │ │ │ state = <sqlalchemy.orm.state.InstanceState object at 0x7ed67b61e330> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/attributes.py:1 │ │ 096 in get │ │ │ │ 1093 │ │ │ │ if not passive & CALLABLES_OK: │ │ 1094 │ │ │ │ │ return PASSIVE_NO_RESULT │ │ 1095 │ │ │ │ │ │ ❱ 1096 │ │ │ │ value = self._fire_loader_callables(state, key, passive) │ │ 1097 │ │ │ │ │ │ 1098 │ │ │ │ if value is PASSIVE_NO_RESULT or value is NO_VALUE: │ │ 1099 │ │ │ │ │ return value │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ dict* = { │ │ │ │ │ 'sa_instance_state': <sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>, │ │ │ │ │ 'id': 8, │ │ │ │ │ 'error_message': None, │ │ │ │ │ 'file_destination': None, │ │ │ │ │ 'completed_at': None, │ │ │ │ │ 'updated_at': datetime.datetime(2026, 1, 23, 17, 10, 47), │ │ │ │ │ 'series_id': 146, │ │ │ │ │ 'episode_id': 26, │ │ │ │ │ 'download_url': None, │ │ │ │ │ 'started_at': None, │ │ │ │ │ ... +2 │ │ │ │ } │ │ │ │ key = 'episode' │ │ │ │ passive = symbol('PASSIVE_OFF') │ │ │ │ self = <sqlalchemy.orm.attributes.ScalarObjectAttributeImpl object at 0x7ed67cab6700> │ │ │ │ state = <sqlalchemy.orm.state.InstanceState object at 0x7ed67b61e330> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/attributes.py:1 │ │ 131 in _fire_loader_callables │ │ │ │ 1128 │ │ │ callable = state.callables[key] │ │ 1129 │ │ │ return callable*(state, passive) │ │ 1130 │ │ elif self.callable*: │ │ ❱ 1131 │ │ │ return self.callable*(state, passive) │ │ 1132 │ │ else: │ │ 1133 │ │ │ return ATTR_EMPTY │ │ 1134 │ │ │ │ ╭───────────────────────────────────────── locals ─────────────────────────────────────────╮ │ │ │ key = 'episode' │ │ │ │ passive = symbol('PASSIVE_OFF') │ │ │ │ self = <sqlalchemy.orm.attributes.ScalarObjectAttributeImpl object at 0x7ed67cab6700> │ │ │ │ state = <sqlalchemy.orm.state.InstanceState object at 0x7ed67b61e330> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/strategies.py:9 │ │ 78 in _load_for_state │ │ │ │ 975 │ │ │ ): │ │ 976 │ │ │ │ return LoaderCallableStatus.PASSIVE_NO_RESULT │ │ 977 │ │ │ │ ❱ 978 │ │ return self._emit_lazyload( │ │ 979 │ │ │ session, │ │ 980 │ │ │ state, │ │ 981 │ │ │ primary_key_identity, │ │ │ │ ╭────────────────────────────────────────── locals ──────────────────────────────────────────╮ │ │ │ alternate_effective_path = None │ │ │ │ execution_options = immutabledict({}) │ │ │ │ extra_criteria = () │ │ │ │ extra_options = () │ │ │ │ instance = None │ │ │ │ loadopt = None │ │ │ │ passive = symbol('PASSIVE_OFF') │ │ │ │ pending = False │ │ │ │ primary_key_identity = [26] │ │ │ │ self = <sqlalchemy.orm.strategies.LazyLoader object at 0x7ed67cabf4c0> │ │ │ │ session = <sqlalchemy.orm.session.Session object at 0x7ed67caf4fc0> │ │ │ │ state = <sqlalchemy.orm.state.InstanceState object at 0x7ed67b61e330> │ │ │ │ use_get = True │ │ │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/strategies.py:1 │ │ 079 in _emit_lazyload │ │ │ │ 1076 │ │ │ if self._raise_on_sql and not passive & PassiveFlag.NO_RAISE: │ │ 1077 │ │ │ │ self._invoke_raise_load(state, passive, "raise_on_sql") │ │ 1078 │ │ │ │ │ ❱ 1079 │ │ │ return loading.load_on_pk_identity( │ │ 1080 │ │ │ │ session, │ │ 1081 │ │ │ │ stmt, │ │ 1082 │ │ │ │ primary_key_identity, │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ alternate_effective_path = None │ │ │ │ clauseelement = Table('episodes', MetaData(), Column('id', Integer(), │ │ │ │ table=, primary_key=True, nullable=False), │ │ │ │ Column('series_id', Integer(), ForeignKey('anime_series.id'), │ │ │ │ table=, nullable=False), Column('season', Integer(), │ │ │ │ table=, nullable=False), Column('episode_number', │ │ │ │ Integer(), table=, nullable=False), Column('title', │ │ │ │ String(length=500), table=), Column('file_path', │ │ │ │ String(length=1000), table=), Column('is_downloaded', │ │ │ │ Boolean(), table=, nullable=False, │ │ │ │ default=ScalarElementColumnDefault(False)), Column('created_at', │ │ │ │ DateTime(timezone=True), table=, nullable=False, │ │ │ │ server_default=DefaultClause(<sqlalchemy.sql.functions.now at │ │ │ │ 0x7ed681946120; now>, for_update=False)), Column('updated_at', │ │ │ │ DateTime(timezone=True), table=, nullable=False, │ │ │ │ onupdate=ColumnElementColumnDefault(<sqlalchemy.sql.functions.now │ │ │ │ at 0x7ed681b1ae90; now>), │ │ │ │ server_default=DefaultClause(<sqlalchemy.sql.functions.now at │ │ │ │ 0x7ed681b1aad0; now>, for_update=False)), schema=None) │ │ │ │ effective_path = PropRegistry((<Mapper at 0x7ed681845590; DownloadQueueItem>, │ │ │ │ <_RelationshipDeclared at 0x7ed681866df0; episode>)) │ │ │ │ execution_options = immutabledict({}) │ │ │ │ extra_criteria = () │ │ │ │ extra_options = () │ │ │ │ load_options = default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>) │ │ │ │ loadopt = None │ │ │ │ opts = ( │ │ │ │ │ <sqlalchemy.orm.strategy_options.Load object at │ │ │ │ 0x7ed67b687e80>, │ │ │ │ ) │ │ │ │ passive = symbol('PASSIVE_OFF') │ │ │ │ pending = False │ │ │ │ primary_key_identity = [26] │ │ │ │ self = <sqlalchemy.orm.strategies.LazyLoader object at 0x7ed67cabf4c0> │ │ │ │ session = <sqlalchemy.orm.session.Session object at 0x7ed67caf4fc0> │ │ │ │ state = <sqlalchemy.orm.state.InstanceState object at 0x7ed67b61e330> │ │ │ │ stmt = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad55e0> │ │ │ │ strategy_options = <module 'sqlalchemy.orm.strategy_options' from │ │ │ │ '/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packag… │ │ │ │ use_get = True │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/loading.py:695 │ │ in load_on_pk_identity │ │ │ │ 692 │ │ execution_options, {"_sa_orm_load_options": load_options} │ │ 693 │ ) │ │ 694 │ result = ( │ │ ❱ 695 │ │ session.execute( │ │ 696 │ │ │ q, │ │ 697 │ │ │ params=params, │ │ 698 │ │ │ execution_options=execution_options, │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ _get_clause = <sqlalchemy.sql.elements.BinaryExpression object at 0x7ed67cab65d0> │ │ │ │ _get_params = { │ │ │ │ │ Column('id', Integer(), table=, primary_key=True, │ │ │ │ nullable=False): BindParameter('pk_1', None, type*=Integer()) │ │ │ │ } │ │ │ │ bindarguments = immutabledict({}) │ │ │ │ compile_options = default_compile_options(_current_path=PropRegistry((<Mapper at │ │ │ │ 0x7ed681845590; DownloadQueueItem>, <_RelationshipDeclared at │ │ │ │ 0x7ed681866df0; episode>))) │ │ │ │ execution_options = immutabledict({'_sa_orm_load_options': │ │ │ │ default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>)}) │ │ │ │ identity_token = None │ │ │ │ is_user_refresh = False │ │ │ │ load_options = default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>) │ │ │ │ mapper = <Mapper at 0x7ed681844a50; Episode> │ │ │ │ new_compile_options = default_compile_options(_current_path=PropRegistry((<Mapper at │ │ │ │ 0x7ed681845590; DownloadQueueItem>, <_RelationshipDeclared at │ │ │ │ 0x7ed681866df0; episode>))) │ │ │ │ no_autoflush = False │ │ │ │ only_load_props = None │ │ │ │ params = {'pk_1': 26} │ │ │ │ primary_key_identity = [26] │ │ │ │ q = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0> │ │ │ │ query = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad55e0> │ │ │ │ refresh_state = None │ │ │ │ require_pk_cols = False │ │ │ │ session = <sqlalchemy.orm.session.Session object at 0x7ed67caf4fc0> │ │ │ │ statement = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad55e0> │ │ │ │ version_check = False │ │ │ │ with_for_update = None │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/session.py:2351 │ │ in execute │ │ │ │ 2348 │ │ │ │ 2349 │ │ │ │ 2350 │ │ """ │ │ ❱ 2351 │ │ return self._execute_internal( │ │ 2352 │ │ │ statement, │ │ 2353 │ │ │ params, │ │ 2354 │ │ │ execution_options=execution_options, │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ _add_event = None │ │ │ │ _parent_execute_state = None │ │ │ │ bind_arguments = immutabledict({}) │ │ │ │ execution_options = immutabledict({'_sa_orm_load_options': │ │ │ │ default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>)}) │ │ │ │ params = {'pk_1': 26} │ │ │ │ self = <sqlalchemy.orm.session.Session object at 0x7ed67caf4fc0> │ │ │ │ statement = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/session.py:2249 │ │ in _execute_internal │ │ │ │ 2246 │ │ │ ) │ │ 2247 │ │ │ │ 2248 │ │ if compile_state_cls: │ │ ❱ 2249 │ │ │ result: Result[Any] = compile_state_cls.orm_execute_statement( │ │ 2250 │ │ │ │ self, │ │ 2251 │ │ │ │ statement, │ │ 2252 │ │ │ │ params or {}, │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ _add_event = None │ │ │ │ _parent_execute_state = None │ │ │ │ _scalar_result = False │ │ │ │ bind = Engine(sqlite+aiosqlite:///./data/aniworld.db) │ │ │ │ bind_arguments = { │ │ │ │ │ 'clause': <sqlalchemy.sql.selectable.Select object at │ │ │ │ 0x7ed67cad73e0>, │ │ │ │ │ 'mapper': <Mapper at 0x7ed681844a50; Episode> │ │ │ │ } │ │ │ │ conn = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ │ events_todo = <sqlalchemy.event.attr._EmptyListener object at 0x7ed67ce11380> │ │ │ │ execution_options = immutabledict({'_sa_orm_load_options': │ │ │ │ default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>), '_result_disable_adapt_to_context': True}) │ │ │ │ params = {'pk_1': 26} │ │ │ │ self = <sqlalchemy.orm.session.Session object at 0x7ed67caf4fc0> │ │ │ │ statement = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/orm/context.py:306 │ │ in orm_execute_statement │ │ │ │ 303 │ │ bind_arguments, │ │ 304 │ │ conn, │ │ 305 │ ) -> Result: │ │ ❱ 306 │ │ result = conn.execute( │ │ 307 │ │ │ statement, params or {}, execution_options=execution_options │ │ 308 │ │ ) │ │ 309 │ │ return cls.orm_setup_cursor_result( │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ bind_arguments = { │ │ │ │ │ 'clause': <sqlalchemy.sql.selectable.Select object at │ │ │ │ 0x7ed67cad73e0>, │ │ │ │ │ 'mapper': <Mapper at 0x7ed681844a50; Episode> │ │ │ │ } │ │ │ │ conn = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ │ execution_options = immutabledict({'_sa_orm_load_options': │ │ │ │ default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>), '_result_disable_adapt_to_context': True}) │ │ │ │ params = {'pk_1': 26} │ │ │ │ session = <sqlalchemy.orm.session.Session object at 0x7ed67caf4fc0> │ │ │ │ statement = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/engine/base.py:1419 │ │ in execute │ │ │ │ 1416 │ │ except AttributeError as err: │ │ 1417 │ │ │ raise exc.ObjectNotExecutableError(statement) from err │ │ 1418 │ │ else: │ │ ❱ 1419 │ │ │ return meth( │ │ 1420 │ │ │ │ self, │ │ 1421 │ │ │ │ distilled_parameters, │ │ 1422 │ │ │ │ execution_options or NO_OPTIONS, │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ distilled_parameters = [{'pk_1': 26}] │ │ │ │ execution_options = immutabledict({'_sa_orm_load_options': │ │ │ │ default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>), '_result_disable_adapt_to_context': True}) │ │ │ │ meth = <bound method ClauseElement._execute_on_connection of │ │ │ │ <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0>> │ │ │ │ parameters = {'pk_1': 26} │ │ │ │ self = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ │ statement = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/sql/elements.py:526 │ │ in _execute_on_connection │ │ │ │ 523 │ │ if self.supports_execution: │ │ 524 │ │ │ if TYPE_CHECKING: │ │ 525 │ │ │ │ assert isinstance(self, Executable) │ │ ❱ 526 │ │ │ return connection._execute_clauseelement( │ │ 527 │ │ │ │ self, distilled_params, execution_options │ │ 528 │ │ │ ) │ │ 529 │ │ else: │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ connection = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ │ distilled_params = [{'pk_1': 26}] │ │ │ │ execution_options = immutabledict({'_sa_orm_load_options': │ │ │ │ default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>), '_result_disable_adapt_to_context': True}) │ │ │ │ self = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/engine/base.py:1641 │ │ in _execute_clauseelement │ │ │ │ 1638 │ │ │ schema_translate_map=schema_translate_map, │ │ 1639 │ │ │ linting=self.dialect.compiler_linting | compiler.WARN_LINTING, │ │ 1640 │ │ ) │ │ ❱ 1641 │ │ ret = self._execute_context( │ │ 1642 │ │ │ dialect, │ │ 1643 │ │ │ dialect.execution_ctx_cls._init_compiled, │ │ 1644 │ │ │ compiled_sql, │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ cache_hit = <CacheStats.CACHE_MISS: 1> │ │ │ │ compiled_cache = <sqlalchemy.util._collections.LRUCache object at 0x7ed67ca2efc0> │ │ │ │ compiled_sql = <sqlalchemy.dialects.sqlite.base.SQLiteCompiler object at │ │ │ │ 0x7ed67cae5950> │ │ │ │ dialect = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteDialect_aiosqlite object │ │ │ │ at 0x7ed67cb3f8c0> │ │ │ │ distilled_parameters = [{'pk_1': 26}] │ │ │ │ elem = <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0> │ │ │ │ execution_options = immutabledict({'_sa_orm_load_options': │ │ │ │ default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>), '_result_disable_adapt_to_context': True}) │ │ │ │ extracted_params = [AnnotatedBindParameter('pk_1', None, type=Integer())] │ │ │ │ forexecutemany = False │ │ │ │ has_events = False │ │ │ │ keys = ['pk_1'] │ │ │ │ schema_translate_map = None │ │ │ │ self = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/engine/base.py:1846 │ │ in _execute_context │ │ │ │ 1843 │ │ if context.execute_style is ExecuteStyle.INSERTMANYVALUES: │ │ 1844 │ │ │ return self._exec_insertmany_context(dialect, context) │ │ 1845 │ │ else: │ │ ❱ 1846 │ │ │ return self._exec_single_context( │ │ 1847 │ │ │ │ dialect, context, statement, parameters │ │ 1848 │ │ │ ) │ │ 1849 │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ args = ( │ │ │ │ │ <sqlalchemy.dialects.sqlite.base.SQLiteCompiler object at │ │ │ │ 0x7ed67cae5950>, │ │ │ │ │ [{'pk_1': 26}], │ │ │ │ │ <sqlalchemy.sql.selectable.Select object at 0x7ed67cad73e0>, │ │ │ │ │ [AnnotatedBindParameter('pk_1', None, type=Integer())] │ │ │ │ ) │ │ │ │ conn = <sqlalchemy.pool.base.ConnectionFairy object at 0x7ed67b61daf0> │ │ │ │ constructor = <bound method DefaultExecutionContext._init_compiled of <class │ │ │ │ 'sqlalchemy.dialects.sqlite.aiosqlite.SQLiteExecutionContext_aiosqlite'… │ │ │ │ context = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteExecutionContext_aiosqlite │ │ │ │ object at 0x7ed67ca85260> │ │ │ │ dialect = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteDialect_aiosqlite object at │ │ │ │ 0x7ed67cb3f8c0> │ │ │ │ execution_options = immutabledict({'_sa_orm_load_options': │ │ │ │ default_load_options(_invoke_all_eagers=False, │ │ │ │ _lazy_loaded_from=<sqlalchemy.orm.state.InstanceState object at │ │ │ │ 0x7ed67b61e330>), '_result_disable_adapt_to_context': True}) │ │ │ │ kw = {'cache_hit': <CacheStats.CACHE_MISS: 1>} │ │ │ │ parameters = [{'pk_1': 26}] │ │ │ │ self = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ │ statement = <sqlalchemy.dialects.sqlite.base.SQLiteCompiler object at │ │ │ │ 0x7ed67cae5950> │ │ │ │ yp = None │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/engine/base.py:1986 │ │ in _exec_single_context │ │ │ │ 1983 │ │ │ result = context._setup_result_proxy() │ │ 1984 │ │ │ │ 1985 │ │ except BaseException as e: │ │ ❱ 1986 │ │ │ self._handle_dbapi_exception( │ │ 1987 │ │ │ │ e, str_statement, effective_parameters, cursor, context │ │ 1988 │ │ │ ) │ │ 1989 │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ context = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteExecutionContext_aiosqli… │ │ │ │ object at 0x7ed67ca85260> │ │ │ │ cursor = <sqlalchemy.dialects.sqlite.aiosqlite.AsyncAdapt_aiosqlite_cursor │ │ │ │ object at 0x7ed67b667be0> │ │ │ │ dialect = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteDialect_aiosqlite object │ │ │ │ at 0x7ed67cb3f8c0> │ │ │ │ effective_parameters = (26,) │ │ │ │ evt_handled = False │ │ │ │ parameters = [(26,)] │ │ │ │ self = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ │ statement = <sqlalchemy.dialects.sqlite.base.SQLiteCompiler object at │ │ │ │ 0x7ed67cae5950> │ │ │ │ str_statement = 'SELECT episodes.id AS episodes_id, episodes.series_id AS │ │ │ │ episodes_series_id, epi'+335 │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/engine/base.py:2358 │ │ in _handle_dbapi_exception │ │ │ │ 2355 │ │ │ │ raise sqlalchemy_exception.with_traceback(exc_info[2]) from e │ │ 2356 │ │ │ else: │ │ 2357 │ │ │ │ assert exc_info[1] is not None │ │ ❱ 2358 │ │ │ │ raise exc_info[1].with_traceback(exc_info[2]) │ │ 2359 │ │ finally: │ │ 2360 │ │ │ del self._reentrant_error │ │ 2361 │ │ │ if self._is_disconnect: │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ context = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteExecutionContex… │ │ │ │ object at 0x7ed67ca85260> │ │ │ │ cursor = <sqlalchemy.dialects.sqlite.aiosqlite.AsyncAdapt_aiosqlite… │ │ │ │ object at 0x7ed67b667be0> │ │ │ │ e = MissingGreenlet("greenletspawn has not been called; can't │ │ │ │ call await_only() here. Was IO attempted in an unexpected │ │ │ │ place?") │ │ │ │ exc_info = ( │ │ │ │ │ <class 'sqlalchemy.exc.MissingGreenlet'>, │ │ │ │ │ MissingGreenlet("greenlet_spawn has not been called; │ │ │ │ can't call await_only() here. Was IO attempted in an │ │ │ │ unexpected place?"), │ │ │ │ │ <traceback object at 0x7ed67b687240> │ │ │ │ ) │ │ │ │ invalidate_pool_on_disconnect = True │ │ │ │ is_exit_exception = False │ │ │ │ is_sub_exec = False │ │ │ │ ismulti = False │ │ │ │ newraise = None │ │ │ │ parameters = (26,) │ │ │ │ self = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ │ should_wrap = False │ │ │ │ sqlalchemy_exception = None │ │ │ │ statement = 'SELECT episodes.id AS episodes_id, episodes.series_id AS │ │ │ │ episodes_series_id, epi'+335 │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/engine/base.py:1967 │ │ in _exec_single_context │ │ │ │ 1964 │ │ │ │ │ │ │ evt_handled = True │ │ 1965 │ │ │ │ │ │ │ break │ │ 1966 │ │ │ │ if not evt_handled: │ │ ❱ 1967 │ │ │ │ │ self.dialect.do_execute( │ │ 1968 │ │ │ │ │ │ cursor, str_statement, effective_parameters, context │ │ 1969 │ │ │ │ │ ) │ │ 1970 │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ context = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteExecutionContext_aiosqli… │ │ │ │ object at 0x7ed67ca85260> │ │ │ │ cursor = <sqlalchemy.dialects.sqlite.aiosqlite.AsyncAdapt_aiosqlite_cursor │ │ │ │ object at 0x7ed67b667be0> │ │ │ │ dialect = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteDialect_aiosqlite object │ │ │ │ at 0x7ed67cb3f8c0> │ │ │ │ effective_parameters = (26,) │ │ │ │ evt_handled = False │ │ │ │ parameters = [(26,)] │ │ │ │ self = <sqlalchemy.engine.base.Connection object at 0x7ed67ca85480> │ │ │ │ statement = <sqlalchemy.dialects.sqlite.base.SQLiteCompiler object at │ │ │ │ 0x7ed67cae5950> │ │ │ │ str_statement = 'SELECT episodes.id AS episodes_id, episodes.series_id AS │ │ │ │ episodes_series_id, epi'+335 │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/engine/default.py:9 │ │ 51 in do_execute │ │ │ │ 948 │ │ cursor.executemany(statement, parameters) │ │ 949 │ │ │ 950 │ def do_execute(self, cursor, statement, parameters, context=None): │ │ ❱ 951 │ │ cursor.execute(statement, parameters) │ │ 952 │ │ │ 953 │ def do_execute_no_params(self, cursor, statement, context=None): │ │ 954 │ │ cursor.execute(statement) │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ context = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteExecutionContext_aiosqlite object │ │ │ │ at 0x7ed67ca85260> │ │ │ │ cursor = <sqlalchemy.dialects.sqlite.aiosqlite.AsyncAdapt_aiosqlite_cursor object at │ │ │ │ 0x7ed67b667be0> │ │ │ │ parameters = (26,) │ │ │ │ self = <sqlalchemy.dialects.sqlite.aiosqlite.SQLiteDialect_aiosqlite object at │ │ │ │ 0x7ed67cb3f8c0> │ │ │ │ statement = 'SELECT episodes.id AS episodes_id, episodes.series_id AS episodes_series_id, │ │ │ │ epi'+335 │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/aio │ │ sqlite.py:180 in execute │ │ │ │ 177 │ │ │ else: │ │ 178 │ │ │ │ self._cursor = _cursor # type: ignore[misc] │ │ 179 │ │ except Exception as error: │ │ ❱ 180 │ │ │ self._adapt_connection._handle_exception(error) │ │ 181 │ │ │ 182 │ def executemany( │ │ 183 │ │ self, │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ operation = 'SELECT episodes.id AS episodes_id, episodes.series_id AS episodes_series_id, │ │ │ │ epi'+335 │ │ │ │ parameters = (26,) │ │ │ │ self = <sqlalchemy.dialects.sqlite.aiosqlite.AsyncAdapt_aiosqlite_cursor object at │ │ │ │ 0x7ed67b667be0> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/aio │ │ sqlite.py:340 in _handle_exception │ │ │ │ 337 │ │ │ │ "no active connection" │ │ 338 │ │ │ ) from error │ │ 339 │ │ else: │ │ ❱ 340 │ │ │ raise error │ │ 341 │ │ 342 │ │ 343 class AsyncAdaptFallback_aiosqlite_connection(AsyncAdapt_aiosqlite_connection): │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ error = MissingGreenlet("greenlet_spawn has not been called; can't call await_only() here. │ │ │ │ Was IO attempted in an unexpected place?") │ │ │ │ self = <AdaptedConnection <Connection(Thread-1, started daemon 139459678959296)>> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/aio │ │ sqlite.py:157 in execute │ │ │ │ 154 │ ) -> Any: │ │ 155 │ │ │ │ 156 │ │ try: │ │ ❱ 157 │ │ │ _cursor: AsyncIODBAPICursor = self.await(self.connection.cursor()) # type │ │ 158 │ │ │ │ │ 159 │ │ │ if parameters is None: │ │ 160 │ │ │ │ self.await(_cursor.execute(operation)) │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ operation = 'SELECT episodes.id AS episodes_id, episodes.series_id AS episodes_series_id, │ │ │ │ epi'+335 │ │ │ │ parameters = (26,) │ │ │ │ self = <sqlalchemy.dialects.sqlite.aiosqlite.AsyncAdapt_aiosqlite_cursor object at │ │ │ │ 0x7ed67b667be0> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_p │ │ y3k.py:123 in await_only │ │ │ │ 120 │ if not getattr(current, "sqlalchemy_greenlet_provider", False): │ │ 121 │ │ _safe_cancel_awaitable(awaitable) │ │ 122 │ │ │ │ ❱ 123 │ │ raise exc.MissingGreenlet( │ │ 124 │ │ │ "greenlet_spawn has not been called; can't call await_only() " │ │ 125 │ │ │ "here. Was IO attempted in an unexpected place?" │ │ 126 │ │ ) │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ awaitable = <aiosqlite.context.Result object at 0x7ed67b63fa60> │ │ │ │ current = <greenlet.greenlet object at 0x7ed68264fb40 (otid=0x7ed68263b960) current active │ │ │ │ started main> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)
The above exception was the direct cause of the following exception:
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮ │ /home/lukas/Volume/repo/Aniworld/src/server/services/download_service.py:135 in initialize │ │ │ │ 132 │ │ │ │ │ 133 │ │ │ # Load all items from database - they all start as PENDING │ │ 134 │ │ │ # since status is now managed in-memory only │ │ ❱ 135 │ │ │ all_items = await repository.get_all_items() │ │ 136 │ │ │ for item in all_items: │ │ 137 │ │ │ │ # All items from database are treated as pending │ │ 138 │ │ │ │ item.status = DownloadStatus.PENDING │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ e = QueueRepositoryError("Failed to get all items: greenlet_spawn has not been │ │ │ │ called; can't call await_only() here. Was IO attempted in an unexpected place? │ │ │ │ (Background on this error at: https://sqlalche.me/e/20/xd2s)") │ │ │ │ repository = <src.server.services.queue_repository.QueueRepository object at 0x7ed67ca6b770> │ │ │ │ self = <src.server.services.download_service.DownloadService object at 0x7ed67ca6b620> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/lukas/Volume/repo/Aniworld/src/server/services/queue_repository.py:296 in get_all_items │ │ │ │ 293 │ │ │ │ 294 │ │ except Exception as e: │ │ 295 │ │ │ logger.error("Failed to get all items: %s", e) │ │ ❱ 296 │ │ │ raise QueueRepositoryError(f"Failed to get all items: {e}") from e │ │ 297 │ │ finally: │ │ 298 │ │ │ if manage_session: │ │ 299 │ │ │ │ await session.close() │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ db = None │ │ │ │ db_items = [ │ │ │ │ │ <DownloadQueueItem(id=8, series_id=146, episode_id=26)>, │ │ │ │ │ <DownloadQueueItem(id=9, series_id=146, episode_id=27)>, │ │ │ │ │ <DownloadQueueItem(id=10, series_id=146, episode_id=28)>, │ │ │ │ │ <DownloadQueueItem(id=11, series_id=146, episode_id=29)>, │ │ │ │ │ <DownloadQueueItem(id=12, series_id=146, episode_id=30)>, │ │ │ │ │ <DownloadQueueItem(id=13, series_id=146, episode_id=31)>, │ │ │ │ │ <DownloadQueueItem(id=14, series_id=146, episode_id=32)>, │ │ │ │ │ <DownloadQueueItem(id=15, series_id=146, episode_id=33)>, │ │ │ │ │ <DownloadQueueItem(id=16, series_id=83, episode_id=1)>, │ │ │ │ │ <DownloadQueueItem(id=17, series_id=83, episode_id=2)>, │ │ │ │ │ ... +21 │ │ │ │ ] │ │ │ │ manage_session = True │ │ │ │ self = <src.server.services.queue_repository.QueueRepository object at │ │ │ │ 0x7ed67ca6b770> │ │ │ │ session = <sqlalchemy.ext.asyncio.session.AsyncSession object at 0x7ed67caf4e90> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ QueueRepositoryError: Failed to get all items: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s)
- fix add issue
INFO: 127.0.0.1:54956 - "POST /api/anime/add HTTP/1.1" 500 ERROR: Exception in ASGI application Traceback (most recent call last): File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/anyio/streams/memory.py", line 98, in receive return self.receive_nowait()
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/anyio/streams/memory.py", line 93, in receive_nowait
raise WouldBlock
anyio.WouldBlock
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/base.py", line 78, in call_next
message = await recv_stream.receive()
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/anyio/streams/memory.py", line 118, in receive
raise EndOfStream
anyio.EndOfStream
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/uvicorn/protocols/http/httptools_impl.py", line 426, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.scope, self.receive, self.send
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/uvicorn/middleware/proxy_headers.py", line 84, in **call**
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/fastapi/applications.py", line 1106, in **call**
await super().**call**(scope, receive, send)
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/applications.py", line 122, in **call**
await self.middleware_stack(scope, receive, send)
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/errors.py", line 184, in **call**
raise exc
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/errors.py", line 162, in **call**
await self.app(scope, receive, \_send)
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/base.py", line 108, in **call**
response = await self.dispatch_func(request, call_next)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lukas/Volume/repo/Aniworld/src/server/middleware/auth.py", line 209, in dispatch
return await call_next(request)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/base.py", line 84, in call_next
raise app_exc
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/base.py", line 70, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/base.py", line 108, in **call**
response = await self.dispatch_func(request, call_next)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lukas/Volume/repo/Aniworld/src/server/middleware/setup_redirect.py", line 147, in dispatch
return await call_next(request)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/base.py", line 84, in call_next
raise app_exc
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/base.py", line 70, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/cors.py", line 91, in **call**
await self.simple_response(scope, receive, send, request_headers=headers)
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/cors.py", line 146, in simple_response
await self.app(scope, receive, send)
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/exceptions.py", line 79, in **call**
raise exc
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/starlette/middleware/exceptions.py", line 68, in **call**
await self.app(scope, receive, sender)
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/site-packages/fastapi/middleware/asyncexitstack.py", line 14, in **call**
async with AsyncExitStack() as stack:
~~~~~~~~~~~~~~^^
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/contextlib.py", line 768, in **aexit**
raise exc
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/contextlib.py", line 751, in **aexit**
cb_suppress = await cb(\*exc_details)
^^^^^^^^^^^^^^^^^^^^^^
File "/home/lukas/miniconda3/envs/AniWorld/lib/python3.13/contextlib.py", line 271, in **aexit**
raise RuntimeError("generator didn't stop after athrow()")
RuntimeError: generator didn't stop after athrow()
3. transactions
go throw code and add transactions. so that application stops the db is not curropted