Dependabot PR #68816 grouped three dependency bumps that each collide with an intentional version cap in our pyproject.toml files. That PR was closed because none can be merged as a blind cap bump. This issue tracks the deliberate work needed to actually move each one — they are independent and should be done in separate PRs.
1. aiosqlite — capped <0.22.0 (airflow-core/pyproject.toml)
- Why capped: aiosqlite 0.22.x leaves a helper thread hanging under SQLAlchemy 2 (see the comment at the pin + aiosqlite#369). Our own test-session issue is fixed in 0.22.1, but the SQLAlchemy-side fix is only in
sqlalchemy main, not yet released.
- To unblock: wait for the SQLAlchemy release carrying the fix (tracked at sqlalchemy#13039), likely bump the
sqlalchemy floor to that version, then relax the aiosqlite cap to allow 0.22.1+.
2. fastapi — capped <0.137.0 (airflow-core/pyproject.toml)
3. datamodel-code-generator — pinned ==0.33.0 (task-sdk + airflow-ctl codegen groups)
- Why not bumped to 0.67.0: regenerating with 0.67.0 drops the
= None default from nullable-optional fields, turning ~200 fields across the Task SDK Execution API client (task-sdk/src/airflow/sdk/api/datamodels/_generated.py) and the airflow-ctl API client (airflow-ctl/src/airflowctl/api/datamodels/generated.py) from optional into required — a breaking Pydantic v2 model-contract change. It also shifts e.g. dict[str, JsonValue] → dict[str, JsonValue | None]. The config already sets use-default=true; 0.67.0 reinterprets that.
- To unblock: investigate whether a generator flag restores the previous
= None behaviour for nullable fields, or step the pin up incrementally to the last version that preserves defaults. Only bump when the regenerated _generated.py / generated.py diff is semantically equivalent.
Closes the loop on #68816.
Drafted-by: Claude Code (Opus 4.8); reviewed by @potiuk before posting
Dependabot PR #68816 grouped three dependency bumps that each collide with an intentional version cap in our
pyproject.tomlfiles. That PR was closed because none can be merged as a blind cap bump. This issue tracks the deliberate work needed to actually move each one — they are independent and should be done in separate PRs.1.
aiosqlite— capped<0.22.0(airflow-core/pyproject.toml)sqlalchemymain, not yet released.sqlalchemyfloor to that version, then relax the aiosqlite cap to allow0.22.1+.2.
fastapi— capped<0.137.0(airflow-core/pyproject.toml)RouterGenerationErrorand fails api-server / dag-processor startup. The cap was added deliberately in Cap fastapi <0.137 and fix execution API health empty-path route #68578 (which closed Execution API health route (empty path) breaks api-server, dag-processor startup under FastAPI 0.137.0 #68562).3.
datamodel-code-generator— pinned==0.33.0(task-sdk+airflow-ctlcodegengroups)= Nonedefault from nullable-optional fields, turning ~200 fields across the Task SDK Execution API client (task-sdk/src/airflow/sdk/api/datamodels/_generated.py) and the airflow-ctl API client (airflow-ctl/src/airflowctl/api/datamodels/generated.py) from optional into required — a breaking Pydantic v2 model-contract change. It also shifts e.g.dict[str, JsonValue]→dict[str, JsonValue | None]. The config already setsuse-default=true; 0.67.0 reinterprets that.= Nonebehaviour for nullable fields, or step the pin up incrementally to the last version that preserves defaults. Only bump when the regenerated_generated.py/generated.pydiff is semantically equivalent.Closes the loop on #68816.
Drafted-by: Claude Code (Opus 4.8); reviewed by @potiuk before posting