upgrade-fab-provider

Upgrade the pinned Flask-AppBuilder (FAB) dependency in the Apache Airflow FAB provider (`providers/fab/`). Bumps the exact `flask-appbuilder==` pin and its…

npx skills add https://github.com/astronomer/airflow --skill upgrade-fab-provider

upgrade-fab-provider

Airflow's FAB provider is tightly coupled to a specific Flask-AppBuilder release because it vendors-in and subclasses large parts of FAB's security manager. A version bump is therefore never "just change the pin" — it must be reconciled against the vendored code, and that reconciliation is enforced by a pytest alignment test, not a prek hook.

The canonical reference for a real bump is PR #66841 ("Bump flask-appbuilder to 5.2.1 and mirror new auth event hooks") — commit c72b6613fd. Read its diff first when in doubt: git show c72b6613fd.

The coupling — why this is not a one-line change

  • providers/fab/pyproject.toml:75-80 explains it: Airflow vendored FAB's security-manager code into providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py (~2700 lines) as FabAirflowSecurityManagerOverride. Every bump must review that class against upstream FAB for new / changed / removed methods.
  • test_fab_alignment.py mechanically detects drift between the installed FAB package and the vendored override, and fails CI until the developer reconciles it.

Inputs

  • Target version — the FAB version to move to. If not given, use the latest release on PyPI (https://pypi.org/pypi/flask-appbuilder/jsoninfo.version). Confirm the target with the user if it is a major or minor bump (higher reconciliation risk); a patch bump can proceed.

The files a bump touches

Always:

  1. providers/fab/pyproject.toml — line ~80, the flask-appbuilder==X.Y.Z pin (the only real dependency pin in the repo).
  2. providers/fab/tests/unit/fab/auth_manager/security_manager/test_fab_alignment.pyEXPECTED_FAB_VERSION = "X.Y.Z" (line ~43). Must move in lockstep with the pin.
  3. providers/fab/docs/index.rst — the dependency table row ``flask-appbuilder`` ``==X.Y.Z`` (line ~114).
  4. providers/fab/README.rst — the Requirements table row (line ~60). Do not hand-edit — it is auto-generated. Regenerate it from the bumped pyproject.toml with the sync-provider-readme prek hook (Step 8); the hook re-renders the table whenever pyproject.toml changes. (Pre-existing bumps that predate this hook left it to release-time regeneration; today the hook is per-commit, so CI flags the drift — run it.)
  5. uv.lock — regenerated (see Step 4 for the pinned-uv caveat).

Conditionally:

  1. providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py — transplant any relevant upstream FAB changes (new auth hooks, changed signatures, ported fixes). The reference bump added +37 lines here. Note: a green alignment test does not prove the transplant is unnecessary — a security fix may live inside a method Airflow vendors (see the 5.2.2 worked example below).
  2. providers/fab/src/airflow/providers/fab/www/** + providers/fab/www-hash.txt — only if the new FAB ships changed static assets / templates that are re-vendored (see Step 6).
  3. providers/fab/src/airflow/providers/fab/migrations/versions/** — only if the new FAB version ships DB migrations (see Step 7).

Never: no newsfragment, and do not hand-edit providers/fab/docs/changelog.rst — providers are released from main and the release manager regenerates the changelog from git log (per providers/AGENTS.md). The commit subject is the changelog entry.

Procedure

Step 1 — Determine the target version and current state

  • Read the current pin: grep flask-appbuilder== providers/fab/pyproject.toml.
  • Resolve the target (PyPI latest, or the user's requested version).
  • Classify the jump: patch / minor / major. For minor/major, skim the FAB release notes (https://github.com/dpgaspar/Flask-AppBuilder/releases) for security-manager / model / template changes before editing.

Step 2 — Bump the three source pins

Edit in lockstep:

  • providers/fab/pyproject.toml — the flask-appbuilder==X.Y.Z line (keep the trailing # Whenever updating the version, run test_fab_alignment.py to verify. comment).
  • test_fab_alignment.pyEXPECTED_FAB_VERSION = "X.Y.Z". It is the tripwire; editing it now is fine — you will keep re-running the test until it and the other three tests pass.
  • providers/fab/docs/index.rst — the dependency-table ==X.Y.Z row.

Step 3 — Install the new FAB into the provider venv

uv --project providers/fab sync installs the new pin. Confirm the installed version:

uv run --project providers/fab python -c \
  "import importlib.metadata as m; print(m.version('flask-appbuilder'))"

Step 4 — Regenerate uv.lock (pinned uv!)

The lock must be regenerated with the repo's pinned uv version, or it drifts hundreds of unrelated marker lines:

AIRFLOW_UV_VERSION=$(grep -oE 'AIRFLOW_UV_VERSION=[0-9.]+' Dockerfile.ci | head -1 | cut -d= -f2)
uvx --from uv==$AIRFLOW_UV_VERSION uv lock

If a conflict is irrecoverable, delete uv.lock and re-run uv lock with the pinned version. Confirm the diff is limited to the FAB bump, not a wholesale marker rewrite.

Step 5 — Run the alignment test and reconcile override.py

uv run --project providers/fab pytest \
  providers/fab/tests/unit/fab/auth_manager/security_manager/test_fab_alignment.py -xvs

Under the host sandbox the test needs a writable AIRFLOW_HOME and the rerun-failures socket disabled — if it errors on a socket bind or on ~/airflow, run it as:

AIRFLOW_HOME="$TMPDIR/fab_home" uv run --project providers/fab pytest \
  providers/fab/tests/.../test_fab_alignment.py -q -p no:rerunfailures

The four tests and how to fix each:

  1. test_fab_version_matches_expected — trips on the version mismatch. It passes once EXPECTED_FAB_VERSION == installed version, but only after you have done the review below.
  2. test_no_unaudited_fab_methods — a new FAB public method exists that is neither implemented in override.py nor listed in AUDITED_EXCLUSIONS. Fix: either implement/override it in override.py, or add it to AUDITED_EXCLUSIONS with a justification comment.
  3. test_no_stale_exclusionsAUDITED_EXCLUSIONS lists a method the new FAB no longer has. Fix: remove that entry.
  4. test_shared_method_signatures_compatible — FAB changed a method signature (new required param). Fix: update the override.py signature, or add to KNOWN_SIGNATURE_DEVIATIONS if the divergence is intentional.

The manual review that the test cannot fully automate: diff the vendored override.py against the new FAB's flask_appbuilder/security/sqla/manager.py and BaseSecurityManager and transplant behavioural changes (bug fixes, new auth event hooks), not just signatures — the test only checks method presence and required params. Locate the installed source:

uv run --project providers/fab python -c \
  "import flask_appbuilder.security.sqla.manager as m; print(m.__file__)"

Step 6 — Re-vendor static assets / templates (only if changed)

If the new FAB changed frontend assets that Airflow vendors under providers/fab/src/airflow/providers/fab/www/ (templates in templates/appbuilder/, static JS/CSS), re-vendor them, then regenerate the fingerprint:

prek run compile-fab-assets --all-files

This runs scripts/ci/prek/compile_provider_assets.py fab (pnpm build over www/) and rewrites providers/fab/www-hash.txt. A patch bump usually does not touch assets — skip this step unless FAB's templates/static changed. Commit the regenerated www-hash.txt if it changed.

Step 7 — DB migrations (only if FAB ships them)

If the new FAB adds/changes security-model tables, add the corresponding migration under providers/fab/src/airflow/providers/fab/migrations/versions/ and run:

prek run update-migration-references-fab check-revision-heads-map-fab --all-files

Patch bumps normally have no migrations — skip unless the release notes mention schema changes.

Step 8 — Static checks + tests

prek run --from-ref main --stage pre-commit
uv run --project providers/fab pytest providers/fab/tests/unit/fab/auth_manager -xvs

The pre-commit stage runs sync-provider-readme (regenerating README.rst) and other FAB hooks. Re-run the alignment test until all four tests pass. The full provider suite is breeze testing providers-tests --test-type "Providers[fab]".

Step 9 — Self-review and commit

  • git diff main...HEAD — verify only the intended files changed, and uv.lock is a clean FAB-scoped diff.
  • Commit subject in imperative mood, plain prose, no Conventional-Commits prefix, e.g. Bump flask-appbuilder to X.Y.Z in FAB provider. Body explains why (what upstream changes were mirrored), not what.
  • No newsfragment, no changelog edit (provider release manager regenerates from git log).
  • Prepend your PR to the history list in providers/fab/CONTRIBUTING.rst so the FAB-upgrade record stays current.
  • Push to origin and open the PR per the repo's PR conventions.

Gotchas

  • EXPECTED_FAB_VERSION is a second pin. Forgetting it makes test_fab_alignment.py fail even when everything else is correct.
  • uv.lock marker drift. Always use the pinned uv (Step 4) — a bare uv lock rewrites hundreds of environment-marker lines and buries the real diff.
  • The alignment test uses AST, not import, to read FAB's SecurityManager (to avoid SQLAlchemy model-registry collisions with Airflow's vendored models). A green test proves structural alignment; it does not prove behavioural parity — Step 5's manual transplant review is still required.
  • docs/index.rst dependency table may look auto-generated but the reference PR edited it by hand; if a docs-regen prek hook rewrites it, let the hook win.
  • README.rst is generated, but the sync hook is per-commit. Don't hand-edit it; run prek run sync-provider-readme (or the full pre-commit stage) after bumping pyproject.toml — CI fails on the drift otherwise.
  • Don't touch providers/fab/docs/upgrading.rst — that is end-user guidance for upgrading the provider package in a deployment, not the developer bump workflow.

Worked example — 5.2.1 to 5.2.2 (patch)

A patch bump that needed no override.py change, but only after a real behavioural review — the green alignment test alone was not sufficient evidence:

  • FAB 5.2.2 shipped three security-manager fixes: LDAP search-filter escaping, OAuth email-allowlist regex anchoring (email + "$"), and API-login provider validation.
  • All three touch methods Airflow vendors (_search_ldap, auth_user_ldap, auth_user_oauth) — so the alignment test passing did not mean "nothing to do". Each had to be checked by hand:
    • LDAP escaping — Airflow's vendored _search_ldap already escapes via ldap.filter.escape_filter_chars (and adds filter-parenthesis validation); it was ahead of FAB. No transplant.
    • OAuth allowlist anchoring — the match lives in FAB's AuthOAuthView (views.py), and Airflow's CustomAuthOAuthView.oauth_authorized delegates via super().oauth_authorized(), so the fix is inherited from the installed FAB 5.2.2. No transplant.
    • API-login validation / Azure-JWT warning / uuid4 — in FAB core Airflow doesn't vendor. Inherited.
  • Net change set: pyproject.toml, test_fab_alignment.py, docs/index.rst, README.rst (via hook), uv.lock. Commit: Bump flask-appbuilder to 5.2.2 in FAB provider.

The lesson the skill encodes: for every security/behavioural fix in the FAB release notes, locate the method and check whether Airflow vendors it — the alignment test guards structure, you guard behaviour.

Plus de skills de astronomer

airflow
astronomer
Interroger, gérer et dépanner les DAGs, exécutions, tâches et configurations système d'Apache Airflow. Prend en charge plus de 30 commandes pour l'inspection des DAGs, la gestion des exécutions, la journalisation des tâches, les requêtes de configuration et l'accès direct à l'API REST. Gérez plusieurs instances Airflow avec une configuration persistante ; découvrez automatiquement les déploiements locaux et Astro. Déclenchez des exécutions de DAG de manière synchrone (attente de fin) ou asynchrone, diagnostiquez les échecs, effacez les exécutions pour réessayer, et accédez aux journaux de tâches avec filtrage par tentative et index de carte. Sortie...
official
airflow-hitl
astronomer
Portes d'approbation humaine, entrées de formulaire et branchement dans les DAG Airflow à l'aide d'opérateurs différés. Quatre types d'opérateurs : ApprovalOperator pour les décisions d'approbation/rejet, HITLOperator pour la sélection multi-options avec formulaires, HITLBranchOperator pour le routage des tâches piloté par l'humain, et HITLEntryOperator pour la collecte de données de formulaire. Tous les opérateurs sont différés, libérant les emplacements de travail en attendant une réponse humaine via l'onglet Actions requises de l'interface utilisateur Airflow ou l'API REST. Prend en charge des fonctionnalités optionnelles, y compris personnalisées...
official
airflow-state-store
astronomer
Persists task and asset state across retries and DAG runs using Airflow 3.3's AIP-103 key/value stores (`task_state_store`, `asset_state_store`) and the…
official
analyzing-data
astronomer
Interrogez votre entrepôt de données pour répondre à des questions métier à l'aide de motifs mis en cache et de correspondances de concepts. Prend en charge la recherche de motifs et la mise en cache pour les types de questions récurrentes, avec enregistrement des résultats pour améliorer les requêtes futures. Inclut un cache de correspondance concept-table et la découverte de schémas de tables via INFORMATION_SCHEMA ou grep du code source. Fournit les fonctions noyau run_sql() et run_sql_pandas() renvoyant des DataFrames Polars ou Pandas pour l'analyse. Commandes CLI pour gérer les caches de concepts, motifs et tables, plus...
official
annotating-task-lineage
astronomer
Annotez les tâches Airflow avec la traçabilité des données à l'aide d'inlets et d'outlets. Prend en charge les objets Dataset OpenLineage, les Assets Airflow et les Datasets Airflow pour définir les entrées et sorties entre bases de données, entrepôts de données et stockage cloud. Utilisez-le comme solution de repli lorsque les opérateurs ne disposent pas d'extracteurs OpenLineage intégrés ; suit un système de priorité à quatre niveaux où les extracteurs personnalisés et les méthodes OpenLineage ont la priorité. Inclut des assistants de nommage de datasets pour Snowflake, BigQuery, S3 et PostgreSQL afin de garantir une cohérence...
official
authoring-dags
astronomer
Workflow guidé pour créer des DAGs Apache Airflow avec validation et intégration de tests. Approche structurée en six phases : découvrir l'environnement et les modèles existants, planifier la structure du DAG, implémenter en suivant les bonnes pratiques, valider avec les commandes CLI af, tester avec le consentement de l'utilisateur, et itérer sur les correctifs. Les commandes CLI pour la découverte (af config connections, af config providers, af dags list) et la validation (af dags errors, af dags get, af dags explore) fournissent un retour immédiat sur le DAG...
official
authoring-go-sdk-tasks
astronomer
Writes Airflow task logic in Go using the Airflow Go SDK. Use when the user wants to implement Airflow tasks in Go, asks about `BundleProvider`/`RegisterDags`,…
official
authoring-java-sdk-tasks
astronomer
Écrit la logique des tâches Airflow en Java, Kotlin ou tout langage JVM utilisant le SDK Java d'Airflow. À utiliser lorsque l'utilisateur souhaite implémenter des tâches Airflow en Java/JVM, demande…
official