Migrate Flask based user APIs to Fastapi - #60973

Merged
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint
Jan 26, 2026
Merged

Migrate Flask based user APIs to Fastapi#60973
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint

Conversation

@Fury0508

Copy link
Copy Markdown
Contributor

This PR migrates the remaining user endpoints from Connexion to FastAPI as part of #56730.

What's Changed

New endpoints in api_fastapi/routes/users.py:

  • GET /fab/v1/users - List users with pagination and ordering
  • GET /fab/v1/users/{username} - Get a single user by username
  • PATCH /fab/v1/users/{username} - Update user with update_mask support
  • DELETE /fab/v1/users/{username} - Delete a user

New datamodels in api_fastapi/datamodels/users.py:

  • UserPatchBody - Request model for partial updates (all fields optional)
  • UserCollectionResponse - Response model for paginated user list

New service methods in api_fastapi/services/users.py:

  • get_user() - Retrieve single user
  • get_users() - List users with pagination/ordering
  • update_user() - Partial update with update_mask support
  • delete_user() - Remove user

Tests added:

  • Route tests for all new endpoints (success, 403, 404, 422 cases)
  • Service layer tests covering all methods
  • Datamodel tests for UserPatchBody and UserCollectionResponse

Notes

  • Follows existing patterns from roles.py implementation
  • update_mask uses comma-separated string format (consistent with roles endpoint)
  • All 125 tests pass locally

closes#60946


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Claude was used for:

  • Code review and suggestions for implementation patterns
  • Writing test cases for routes, services, and datamodels
  • Debugging test environment setup issues

- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
@henry3260

Copy link
Copy Markdown
Contributor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

Thanks for the question!

The new FastAPI endpoints have been created in api_fastapi/routes/users.py (you can see them in the "Files changed" tab):

  • GET /fab/v1/users
  • GET /fab/v1/users/{username}
  • PATCH /fab/v1/users/{username}
  • DELETE /fab/v1/users/{username}

The old Connexion file (api_endpoints/user_endpoint.py) is intentionally kept for now. This follows the same pattern as the roles migration (PR #58023) - create new FastAPI endpoints first, then remove old Connexion files in a separate cleanup PR after all migrations are complete.

The migration approach is:

  1. Create new FastAPI endpoints (this PR)
  2. Remove old Connexion endpoints (separate cleanup after Replace connexion with fast-api: role_and_permission_endpoint.py #60944, Replace connexion with fast-api: initialization, constants, exceptions, schemas. #60945 are done)

Comment threadproviders/imap/src/airflow/providers/imap/hooks/imap.py Outdated
@vincbeckvincbeck changed the title Fab fastapi user endpointMigrate Flask based user APIs to FastapiJan 23, 2026

@vincbeckvincbeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henry3260

Copy link
Copy Markdown
Contributor

Try running prek run --all-files locally, it should fix the formatting issues :)

@Fury0508

Copy link
Copy Markdown
ContributorAuthor

Try running prek run --all-files locally, it should fix the formatting issues :)

Thanks! Ran pre-commit run --all-files locally and pushed the fixes. Hopefully CI passes now 🤞

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@vincbeck CI has 2 failing checks:

  1. UI E2E tests - I only modified backend API code, no frontend changes

  2. Compat 3.0.6 - The error "Status code 204 must not have a response body" occurs in ALL FAB FastAPI route tests:

    • test_login.py (3 errors) - not modified by me
    • test_roles.py (23 errors) - not modified by me
    • test_users.py (22 errors) - my changes

The error happens during test setup, suggesting a TestClient compatibility issue with Airflow 3.0.6, not my code.

Could you confirm if these are known issues? Happy to investigate further if needed.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the CI failed because returning None results in a null response body, but HTTP 204 responses must not have a body. Please return an empty Response object instead.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. LGTM.

@vincbeck
vincbeck merged commit 9d64edf into apache:mainJan 26, 2026
128 checks passed
@boring-cyborg

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

shreyas-dev pushed a commit to shreyas-dev/airflow that referenced this pull request Jan 29, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jason810496 pushed a commit to abhijeets25012-tech/airflow that referenced this pull request Feb 3, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
choo121600 pushed a commit to choo121600/airflow that referenced this pull request Feb 22, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Ankurdeewan pushed a commit to Ankurdeewan/airflow that referenced this pull request Mar 15, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace connexion with fast-api: user_endpoint.py

3 participants

@Fury0508@henry3260@vincbeck
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Migrate Flask based user APIs to Fastapi - #60973

Merged
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint
Jan 26, 2026
Merged

Migrate Flask based user APIs to Fastapi#60973
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint

Conversation

@Fury0508

Copy link
Copy Markdown
Contributor

This PR migrates the remaining user endpoints from Connexion to FastAPI as part of #56730.

What's Changed

New endpoints in api_fastapi/routes/users.py:

  • GET /fab/v1/users - List users with pagination and ordering
  • GET /fab/v1/users/{username} - Get a single user by username
  • PATCH /fab/v1/users/{username} - Update user with update_mask support
  • DELETE /fab/v1/users/{username} - Delete a user

New datamodels in api_fastapi/datamodels/users.py:

  • UserPatchBody - Request model for partial updates (all fields optional)
  • UserCollectionResponse - Response model for paginated user list

New service methods in api_fastapi/services/users.py:

  • get_user() - Retrieve single user
  • get_users() - List users with pagination/ordering
  • update_user() - Partial update with update_mask support
  • delete_user() - Remove user

Tests added:

  • Route tests for all new endpoints (success, 403, 404, 422 cases)
  • Service layer tests covering all methods
  • Datamodel tests for UserPatchBody and UserCollectionResponse

Notes

  • Follows existing patterns from roles.py implementation
  • update_mask uses comma-separated string format (consistent with roles endpoint)
  • All 125 tests pass locally

closes#60946


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Claude was used for:

  • Code review and suggestions for implementation patterns
  • Writing test cases for routes, services, and datamodels
  • Debugging test environment setup issues

- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
@henry3260

Copy link
Copy Markdown
Contributor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

Thanks for the question!

The new FastAPI endpoints have been created in api_fastapi/routes/users.py (you can see them in the "Files changed" tab):

  • GET /fab/v1/users
  • GET /fab/v1/users/{username}
  • PATCH /fab/v1/users/{username}
  • DELETE /fab/v1/users/{username}

The old Connexion file (api_endpoints/user_endpoint.py) is intentionally kept for now. This follows the same pattern as the roles migration (PR #58023) - create new FastAPI endpoints first, then remove old Connexion files in a separate cleanup PR after all migrations are complete.

The migration approach is:

  1. Create new FastAPI endpoints (this PR)
  2. Remove old Connexion endpoints (separate cleanup after Replace connexion with fast-api: role_and_permission_endpoint.py #60944, Replace connexion with fast-api: initialization, constants, exceptions, schemas. #60945 are done)

Comment threadproviders/imap/src/airflow/providers/imap/hooks/imap.py Outdated
@vincbeckvincbeck changed the title Fab fastapi user endpointMigrate Flask based user APIs to FastapiJan 23, 2026

@vincbeckvincbeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henry3260

Copy link
Copy Markdown
Contributor

Try running prek run --all-files locally, it should fix the formatting issues :)

@Fury0508

Copy link
Copy Markdown
ContributorAuthor

Try running prek run --all-files locally, it should fix the formatting issues :)

Thanks! Ran pre-commit run --all-files locally and pushed the fixes. Hopefully CI passes now 🤞

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@vincbeck CI has 2 failing checks:

  1. UI E2E tests - I only modified backend API code, no frontend changes

  2. Compat 3.0.6 - The error "Status code 204 must not have a response body" occurs in ALL FAB FastAPI route tests:

    • test_login.py (3 errors) - not modified by me
    • test_roles.py (23 errors) - not modified by me
    • test_users.py (22 errors) - my changes

The error happens during test setup, suggesting a TestClient compatibility issue with Airflow 3.0.6, not my code.

Could you confirm if these are known issues? Happy to investigate further if needed.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the CI failed because returning None results in a null response body, but HTTP 204 responses must not have a body. Please return an empty Response object instead.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. LGTM.

@vincbeck
vincbeck merged commit 9d64edf into apache:mainJan 26, 2026
128 checks passed
@boring-cyborg

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

shreyas-dev pushed a commit to shreyas-dev/airflow that referenced this pull request Jan 29, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jason810496 pushed a commit to abhijeets25012-tech/airflow that referenced this pull request Feb 3, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
choo121600 pushed a commit to choo121600/airflow that referenced this pull request Feb 22, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Ankurdeewan pushed a commit to Ankurdeewan/airflow that referenced this pull request Mar 15, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace connexion with fast-api: user_endpoint.py

3 participants

@Fury0508@henry3260@vincbeck
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Migrate Flask based user APIs to Fastapi - #60973

Merged
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint
Jan 26, 2026
Merged

Migrate Flask based user APIs to Fastapi#60973
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint

Conversation

@Fury0508

Copy link
Copy Markdown
Contributor

This PR migrates the remaining user endpoints from Connexion to FastAPI as part of #56730.

What's Changed

New endpoints in api_fastapi/routes/users.py:

  • GET /fab/v1/users - List users with pagination and ordering
  • GET /fab/v1/users/{username} - Get a single user by username
  • PATCH /fab/v1/users/{username} - Update user with update_mask support
  • DELETE /fab/v1/users/{username} - Delete a user

New datamodels in api_fastapi/datamodels/users.py:

  • UserPatchBody - Request model for partial updates (all fields optional)
  • UserCollectionResponse - Response model for paginated user list

New service methods in api_fastapi/services/users.py:

  • get_user() - Retrieve single user
  • get_users() - List users with pagination/ordering
  • update_user() - Partial update with update_mask support
  • delete_user() - Remove user

Tests added:

  • Route tests for all new endpoints (success, 403, 404, 422 cases)
  • Service layer tests covering all methods
  • Datamodel tests for UserPatchBody and UserCollectionResponse

Notes

  • Follows existing patterns from roles.py implementation
  • update_mask uses comma-separated string format (consistent with roles endpoint)
  • All 125 tests pass locally

closes#60946


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Claude was used for:

  • Code review and suggestions for implementation patterns
  • Writing test cases for routes, services, and datamodels
  • Debugging test environment setup issues

- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
@henry3260

Copy link
Copy Markdown
Contributor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

Thanks for the question!

The new FastAPI endpoints have been created in api_fastapi/routes/users.py (you can see them in the "Files changed" tab):

  • GET /fab/v1/users
  • GET /fab/v1/users/{username}
  • PATCH /fab/v1/users/{username}
  • DELETE /fab/v1/users/{username}

The old Connexion file (api_endpoints/user_endpoint.py) is intentionally kept for now. This follows the same pattern as the roles migration (PR #58023) - create new FastAPI endpoints first, then remove old Connexion files in a separate cleanup PR after all migrations are complete.

The migration approach is:

  1. Create new FastAPI endpoints (this PR)
  2. Remove old Connexion endpoints (separate cleanup after Replace connexion with fast-api: role_and_permission_endpoint.py #60944, Replace connexion with fast-api: initialization, constants, exceptions, schemas. #60945 are done)

Comment threadproviders/imap/src/airflow/providers/imap/hooks/imap.py Outdated
@vincbeckvincbeck changed the title Fab fastapi user endpointMigrate Flask based user APIs to FastapiJan 23, 2026

@vincbeckvincbeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henry3260

Copy link
Copy Markdown
Contributor

Try running prek run --all-files locally, it should fix the formatting issues :)

@Fury0508

Copy link
Copy Markdown
ContributorAuthor

Try running prek run --all-files locally, it should fix the formatting issues :)

Thanks! Ran pre-commit run --all-files locally and pushed the fixes. Hopefully CI passes now 🤞

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@vincbeck CI has 2 failing checks:

  1. UI E2E tests - I only modified backend API code, no frontend changes

  2. Compat 3.0.6 - The error "Status code 204 must not have a response body" occurs in ALL FAB FastAPI route tests:

    • test_login.py (3 errors) - not modified by me
    • test_roles.py (23 errors) - not modified by me
    • test_users.py (22 errors) - my changes

The error happens during test setup, suggesting a TestClient compatibility issue with Airflow 3.0.6, not my code.

Could you confirm if these are known issues? Happy to investigate further if needed.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the CI failed because returning None results in a null response body, but HTTP 204 responses must not have a body. Please return an empty Response object instead.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. LGTM.

@vincbeck
vincbeck merged commit 9d64edf into apache:mainJan 26, 2026
128 checks passed
@boring-cyborg

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

shreyas-dev pushed a commit to shreyas-dev/airflow that referenced this pull request Jan 29, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jason810496 pushed a commit to abhijeets25012-tech/airflow that referenced this pull request Feb 3, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
choo121600 pushed a commit to choo121600/airflow that referenced this pull request Feb 22, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Ankurdeewan pushed a commit to Ankurdeewan/airflow that referenced this pull request Mar 15, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace connexion with fast-api: user_endpoint.py

3 participants

@Fury0508@henry3260@vincbeck
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Migrate Flask based user APIs to Fastapi - #60973

Merged
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint
Jan 26, 2026
Merged

Migrate Flask based user APIs to Fastapi#60973
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint

Conversation

@Fury0508

Copy link
Copy Markdown
Contributor

This PR migrates the remaining user endpoints from Connexion to FastAPI as part of #56730.

What's Changed

New endpoints in api_fastapi/routes/users.py:

  • GET /fab/v1/users - List users with pagination and ordering
  • GET /fab/v1/users/{username} - Get a single user by username
  • PATCH /fab/v1/users/{username} - Update user with update_mask support
  • DELETE /fab/v1/users/{username} - Delete a user

New datamodels in api_fastapi/datamodels/users.py:

  • UserPatchBody - Request model for partial updates (all fields optional)
  • UserCollectionResponse - Response model for paginated user list

New service methods in api_fastapi/services/users.py:

  • get_user() - Retrieve single user
  • get_users() - List users with pagination/ordering
  • update_user() - Partial update with update_mask support
  • delete_user() - Remove user

Tests added:

  • Route tests for all new endpoints (success, 403, 404, 422 cases)
  • Service layer tests covering all methods
  • Datamodel tests for UserPatchBody and UserCollectionResponse

Notes

  • Follows existing patterns from roles.py implementation
  • update_mask uses comma-separated string format (consistent with roles endpoint)
  • All 125 tests pass locally

closes#60946


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Claude was used for:

  • Code review and suggestions for implementation patterns
  • Writing test cases for routes, services, and datamodels
  • Debugging test environment setup issues

- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
@henry3260

Copy link
Copy Markdown
Contributor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

Thanks for the question!

The new FastAPI endpoints have been created in api_fastapi/routes/users.py (you can see them in the "Files changed" tab):

  • GET /fab/v1/users
  • GET /fab/v1/users/{username}
  • PATCH /fab/v1/users/{username}
  • DELETE /fab/v1/users/{username}

The old Connexion file (api_endpoints/user_endpoint.py) is intentionally kept for now. This follows the same pattern as the roles migration (PR #58023) - create new FastAPI endpoints first, then remove old Connexion files in a separate cleanup PR after all migrations are complete.

The migration approach is:

  1. Create new FastAPI endpoints (this PR)
  2. Remove old Connexion endpoints (separate cleanup after Replace connexion with fast-api: role_and_permission_endpoint.py #60944, Replace connexion with fast-api: initialization, constants, exceptions, schemas. #60945 are done)

Comment threadproviders/imap/src/airflow/providers/imap/hooks/imap.py Outdated
@vincbeckvincbeck changed the title Fab fastapi user endpointMigrate Flask based user APIs to FastapiJan 23, 2026

@vincbeckvincbeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henry3260

Copy link
Copy Markdown
Contributor

Try running prek run --all-files locally, it should fix the formatting issues :)

@Fury0508

Copy link
Copy Markdown
ContributorAuthor

Try running prek run --all-files locally, it should fix the formatting issues :)

Thanks! Ran pre-commit run --all-files locally and pushed the fixes. Hopefully CI passes now 🤞

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@vincbeck CI has 2 failing checks:

  1. UI E2E tests - I only modified backend API code, no frontend changes

  2. Compat 3.0.6 - The error "Status code 204 must not have a response body" occurs in ALL FAB FastAPI route tests:

    • test_login.py (3 errors) - not modified by me
    • test_roles.py (23 errors) - not modified by me
    • test_users.py (22 errors) - my changes

The error happens during test setup, suggesting a TestClient compatibility issue with Airflow 3.0.6, not my code.

Could you confirm if these are known issues? Happy to investigate further if needed.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the CI failed because returning None results in a null response body, but HTTP 204 responses must not have a body. Please return an empty Response object instead.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. LGTM.

@vincbeck
vincbeck merged commit 9d64edf into apache:mainJan 26, 2026
128 checks passed
@boring-cyborg

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

shreyas-dev pushed a commit to shreyas-dev/airflow that referenced this pull request Jan 29, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jason810496 pushed a commit to abhijeets25012-tech/airflow that referenced this pull request Feb 3, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
choo121600 pushed a commit to choo121600/airflow that referenced this pull request Feb 22, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Ankurdeewan pushed a commit to Ankurdeewan/airflow that referenced this pull request Mar 15, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace connexion with fast-api: user_endpoint.py

3 participants

@Fury0508@henry3260@vincbeck
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Migrate Flask based user APIs to Fastapi - #60973

Merged
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint
Jan 26, 2026
Merged

Migrate Flask based user APIs to Fastapi#60973
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint

Conversation

@Fury0508

Copy link
Copy Markdown
Contributor

This PR migrates the remaining user endpoints from Connexion to FastAPI as part of #56730.

What's Changed

New endpoints in api_fastapi/routes/users.py:

  • GET /fab/v1/users - List users with pagination and ordering
  • GET /fab/v1/users/{username} - Get a single user by username
  • PATCH /fab/v1/users/{username} - Update user with update_mask support
  • DELETE /fab/v1/users/{username} - Delete a user

New datamodels in api_fastapi/datamodels/users.py:

  • UserPatchBody - Request model for partial updates (all fields optional)
  • UserCollectionResponse - Response model for paginated user list

New service methods in api_fastapi/services/users.py:

  • get_user() - Retrieve single user
  • get_users() - List users with pagination/ordering
  • update_user() - Partial update with update_mask support
  • delete_user() - Remove user

Tests added:

  • Route tests for all new endpoints (success, 403, 404, 422 cases)
  • Service layer tests covering all methods
  • Datamodel tests for UserPatchBody and UserCollectionResponse

Notes

  • Follows existing patterns from roles.py implementation
  • update_mask uses comma-separated string format (consistent with roles endpoint)
  • All 125 tests pass locally

closes#60946


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Claude was used for:

  • Code review and suggestions for implementation patterns
  • Writing test cases for routes, services, and datamodels
  • Debugging test environment setup issues

- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
@henry3260

Copy link
Copy Markdown
Contributor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

Thanks for the question!

The new FastAPI endpoints have been created in api_fastapi/routes/users.py (you can see them in the "Files changed" tab):

  • GET /fab/v1/users
  • GET /fab/v1/users/{username}
  • PATCH /fab/v1/users/{username}
  • DELETE /fab/v1/users/{username}

The old Connexion file (api_endpoints/user_endpoint.py) is intentionally kept for now. This follows the same pattern as the roles migration (PR #58023) - create new FastAPI endpoints first, then remove old Connexion files in a separate cleanup PR after all migrations are complete.

The migration approach is:

  1. Create new FastAPI endpoints (this PR)
  2. Remove old Connexion endpoints (separate cleanup after Replace connexion with fast-api: role_and_permission_endpoint.py #60944, Replace connexion with fast-api: initialization, constants, exceptions, schemas. #60945 are done)

Comment threadproviders/imap/src/airflow/providers/imap/hooks/imap.py Outdated
@vincbeckvincbeck changed the title Fab fastapi user endpointMigrate Flask based user APIs to FastapiJan 23, 2026

@vincbeckvincbeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henry3260

Copy link
Copy Markdown
Contributor

Try running prek run --all-files locally, it should fix the formatting issues :)

@Fury0508

Copy link
Copy Markdown
ContributorAuthor

Try running prek run --all-files locally, it should fix the formatting issues :)

Thanks! Ran pre-commit run --all-files locally and pushed the fixes. Hopefully CI passes now 🤞

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@vincbeck CI has 2 failing checks:

  1. UI E2E tests - I only modified backend API code, no frontend changes

  2. Compat 3.0.6 - The error "Status code 204 must not have a response body" occurs in ALL FAB FastAPI route tests:

    • test_login.py (3 errors) - not modified by me
    • test_roles.py (23 errors) - not modified by me
    • test_users.py (22 errors) - my changes

The error happens during test setup, suggesting a TestClient compatibility issue with Airflow 3.0.6, not my code.

Could you confirm if these are known issues? Happy to investigate further if needed.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the CI failed because returning None results in a null response body, but HTTP 204 responses must not have a body. Please return an empty Response object instead.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. LGTM.

@vincbeck
vincbeck merged commit 9d64edf into apache:mainJan 26, 2026
128 checks passed
@boring-cyborg

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

shreyas-dev pushed a commit to shreyas-dev/airflow that referenced this pull request Jan 29, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jason810496 pushed a commit to abhijeets25012-tech/airflow that referenced this pull request Feb 3, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
choo121600 pushed a commit to choo121600/airflow that referenced this pull request Feb 22, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Ankurdeewan pushed a commit to Ankurdeewan/airflow that referenced this pull request Mar 15, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace connexion with fast-api: user_endpoint.py

3 participants

@Fury0508@henry3260@vincbeck
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Migrate Flask based user APIs to Fastapi - #60973

Merged
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint
Jan 26, 2026
Merged

Migrate Flask based user APIs to Fastapi#60973
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint

Conversation

@Fury0508

Copy link
Copy Markdown
Contributor

This PR migrates the remaining user endpoints from Connexion to FastAPI as part of #56730.

What's Changed

New endpoints in api_fastapi/routes/users.py:

  • GET /fab/v1/users - List users with pagination and ordering
  • GET /fab/v1/users/{username} - Get a single user by username
  • PATCH /fab/v1/users/{username} - Update user with update_mask support
  • DELETE /fab/v1/users/{username} - Delete a user

New datamodels in api_fastapi/datamodels/users.py:

  • UserPatchBody - Request model for partial updates (all fields optional)
  • UserCollectionResponse - Response model for paginated user list

New service methods in api_fastapi/services/users.py:

  • get_user() - Retrieve single user
  • get_users() - List users with pagination/ordering
  • update_user() - Partial update with update_mask support
  • delete_user() - Remove user

Tests added:

  • Route tests for all new endpoints (success, 403, 404, 422 cases)
  • Service layer tests covering all methods
  • Datamodel tests for UserPatchBody and UserCollectionResponse

Notes

  • Follows existing patterns from roles.py implementation
  • update_mask uses comma-separated string format (consistent with roles endpoint)
  • All 125 tests pass locally

closes#60946


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Claude was used for:

  • Code review and suggestions for implementation patterns
  • Writing test cases for routes, services, and datamodels
  • Debugging test environment setup issues

- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
@henry3260

Copy link
Copy Markdown
Contributor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

Thanks for the question!

The new FastAPI endpoints have been created in api_fastapi/routes/users.py (you can see them in the "Files changed" tab):

  • GET /fab/v1/users
  • GET /fab/v1/users/{username}
  • PATCH /fab/v1/users/{username}
  • DELETE /fab/v1/users/{username}

The old Connexion file (api_endpoints/user_endpoint.py) is intentionally kept for now. This follows the same pattern as the roles migration (PR #58023) - create new FastAPI endpoints first, then remove old Connexion files in a separate cleanup PR after all migrations are complete.

The migration approach is:

  1. Create new FastAPI endpoints (this PR)
  2. Remove old Connexion endpoints (separate cleanup after Replace connexion with fast-api: role_and_permission_endpoint.py #60944, Replace connexion with fast-api: initialization, constants, exceptions, schemas. #60945 are done)

Comment threadproviders/imap/src/airflow/providers/imap/hooks/imap.py Outdated
@vincbeckvincbeck changed the title Fab fastapi user endpointMigrate Flask based user APIs to FastapiJan 23, 2026

@vincbeckvincbeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henry3260

Copy link
Copy Markdown
Contributor

Try running prek run --all-files locally, it should fix the formatting issues :)

@Fury0508

Copy link
Copy Markdown
ContributorAuthor

Try running prek run --all-files locally, it should fix the formatting issues :)

Thanks! Ran pre-commit run --all-files locally and pushed the fixes. Hopefully CI passes now 🤞

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@vincbeck CI has 2 failing checks:

  1. UI E2E tests - I only modified backend API code, no frontend changes

  2. Compat 3.0.6 - The error "Status code 204 must not have a response body" occurs in ALL FAB FastAPI route tests:

    • test_login.py (3 errors) - not modified by me
    • test_roles.py (23 errors) - not modified by me
    • test_users.py (22 errors) - my changes

The error happens during test setup, suggesting a TestClient compatibility issue with Airflow 3.0.6, not my code.

Could you confirm if these are known issues? Happy to investigate further if needed.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the CI failed because returning None results in a null response body, but HTTP 204 responses must not have a body. Please return an empty Response object instead.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. LGTM.

@vincbeck
vincbeck merged commit 9d64edf into apache:mainJan 26, 2026
128 checks passed
@boring-cyborg

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

shreyas-dev pushed a commit to shreyas-dev/airflow that referenced this pull request Jan 29, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jason810496 pushed a commit to abhijeets25012-tech/airflow that referenced this pull request Feb 3, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
choo121600 pushed a commit to choo121600/airflow that referenced this pull request Feb 22, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Ankurdeewan pushed a commit to Ankurdeewan/airflow that referenced this pull request Mar 15, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace connexion with fast-api: user_endpoint.py

3 participants

@Fury0508@henry3260@vincbeck
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Migrate Flask based user APIs to Fastapi - #60973

Merged
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint
Jan 26, 2026
Merged

Migrate Flask based user APIs to Fastapi#60973
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint

Conversation

@Fury0508

Copy link
Copy Markdown
Contributor

This PR migrates the remaining user endpoints from Connexion to FastAPI as part of #56730.

What's Changed

New endpoints in api_fastapi/routes/users.py:

  • GET /fab/v1/users - List users with pagination and ordering
  • GET /fab/v1/users/{username} - Get a single user by username
  • PATCH /fab/v1/users/{username} - Update user with update_mask support
  • DELETE /fab/v1/users/{username} - Delete a user

New datamodels in api_fastapi/datamodels/users.py:

  • UserPatchBody - Request model for partial updates (all fields optional)
  • UserCollectionResponse - Response model for paginated user list

New service methods in api_fastapi/services/users.py:

  • get_user() - Retrieve single user
  • get_users() - List users with pagination/ordering
  • update_user() - Partial update with update_mask support
  • delete_user() - Remove user

Tests added:

  • Route tests for all new endpoints (success, 403, 404, 422 cases)
  • Service layer tests covering all methods
  • Datamodel tests for UserPatchBody and UserCollectionResponse

Notes

  • Follows existing patterns from roles.py implementation
  • update_mask uses comma-separated string format (consistent with roles endpoint)
  • All 125 tests pass locally

closes#60946


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Claude was used for:

  • Code review and suggestions for implementation patterns
  • Writing test cases for routes, services, and datamodels
  • Debugging test environment setup issues

- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
@henry3260

Copy link
Copy Markdown
Contributor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

Thanks for the question!

The new FastAPI endpoints have been created in api_fastapi/routes/users.py (you can see them in the "Files changed" tab):

  • GET /fab/v1/users
  • GET /fab/v1/users/{username}
  • PATCH /fab/v1/users/{username}
  • DELETE /fab/v1/users/{username}

The old Connexion file (api_endpoints/user_endpoint.py) is intentionally kept for now. This follows the same pattern as the roles migration (PR #58023) - create new FastAPI endpoints first, then remove old Connexion files in a separate cleanup PR after all migrations are complete.

The migration approach is:

  1. Create new FastAPI endpoints (this PR)
  2. Remove old Connexion endpoints (separate cleanup after Replace connexion with fast-api: role_and_permission_endpoint.py #60944, Replace connexion with fast-api: initialization, constants, exceptions, schemas. #60945 are done)

Comment threadproviders/imap/src/airflow/providers/imap/hooks/imap.py Outdated
@vincbeckvincbeck changed the title Fab fastapi user endpointMigrate Flask based user APIs to FastapiJan 23, 2026

@vincbeckvincbeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henry3260

Copy link
Copy Markdown
Contributor

Try running prek run --all-files locally, it should fix the formatting issues :)

@Fury0508

Copy link
Copy Markdown
ContributorAuthor

Try running prek run --all-files locally, it should fix the formatting issues :)

Thanks! Ran pre-commit run --all-files locally and pushed the fixes. Hopefully CI passes now 🤞

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@vincbeck CI has 2 failing checks:

  1. UI E2E tests - I only modified backend API code, no frontend changes

  2. Compat 3.0.6 - The error "Status code 204 must not have a response body" occurs in ALL FAB FastAPI route tests:

    • test_login.py (3 errors) - not modified by me
    • test_roles.py (23 errors) - not modified by me
    • test_users.py (22 errors) - my changes

The error happens during test setup, suggesting a TestClient compatibility issue with Airflow 3.0.6, not my code.

Could you confirm if these are known issues? Happy to investigate further if needed.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the CI failed because returning None results in a null response body, but HTTP 204 responses must not have a body. Please return an empty Response object instead.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. LGTM.

@vincbeck
vincbeck merged commit 9d64edf into apache:mainJan 26, 2026
128 checks passed
@boring-cyborg

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

shreyas-dev pushed a commit to shreyas-dev/airflow that referenced this pull request Jan 29, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jason810496 pushed a commit to abhijeets25012-tech/airflow that referenced this pull request Feb 3, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
choo121600 pushed a commit to choo121600/airflow that referenced this pull request Feb 22, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Ankurdeewan pushed a commit to Ankurdeewan/airflow that referenced this pull request Mar 15, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace connexion with fast-api: user_endpoint.py

3 participants

@Fury0508@henry3260@vincbeck
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Migrate Flask based user APIs to Fastapi - #60973

Merged
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint
Jan 26, 2026
Merged

Migrate Flask based user APIs to Fastapi#60973
vincbeck merged 6 commits into
apache:mainfrom
Fury0508:fab-fastapi-user-endpoint

Conversation

@Fury0508

Copy link
Copy Markdown
Contributor

This PR migrates the remaining user endpoints from Connexion to FastAPI as part of #56730.

What's Changed

New endpoints in api_fastapi/routes/users.py:

  • GET /fab/v1/users - List users with pagination and ordering
  • GET /fab/v1/users/{username} - Get a single user by username
  • PATCH /fab/v1/users/{username} - Update user with update_mask support
  • DELETE /fab/v1/users/{username} - Delete a user

New datamodels in api_fastapi/datamodels/users.py:

  • UserPatchBody - Request model for partial updates (all fields optional)
  • UserCollectionResponse - Response model for paginated user list

New service methods in api_fastapi/services/users.py:

  • get_user() - Retrieve single user
  • get_users() - List users with pagination/ordering
  • update_user() - Partial update with update_mask support
  • delete_user() - Remove user

Tests added:

  • Route tests for all new endpoints (success, 403, 404, 422 cases)
  • Service layer tests covering all methods
  • Datamodel tests for UserPatchBody and UserCollectionResponse

Notes

  • Follows existing patterns from roles.py implementation
  • update_mask uses comma-separated string format (consistent with roles endpoint)
  • All 125 tests pass locally

closes#60946


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Claude was used for:

  • Code review and suggestions for implementation patterns
  • Writing test cases for routes, services, and datamodels
  • Debugging test environment setup issues

- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
@henry3260

Copy link
Copy Markdown
Contributor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

Thanks for the PR! I just have one question:

It seems user_endpoint.py hasn't been migrated to FastAPI yet, but the commit message says it has. Did we miss this file?

Thanks for the question!

The new FastAPI endpoints have been created in api_fastapi/routes/users.py (you can see them in the "Files changed" tab):

  • GET /fab/v1/users
  • GET /fab/v1/users/{username}
  • PATCH /fab/v1/users/{username}
  • DELETE /fab/v1/users/{username}

The old Connexion file (api_endpoints/user_endpoint.py) is intentionally kept for now. This follows the same pattern as the roles migration (PR #58023) - create new FastAPI endpoints first, then remove old Connexion files in a separate cleanup PR after all migrations are complete.

The migration approach is:

  1. Create new FastAPI endpoints (this PR)
  2. Remove old Connexion endpoints (separate cleanup after Replace connexion with fast-api: role_and_permission_endpoint.py #60944, Replace connexion with fast-api: initialization, constants, exceptions, schemas. #60945 are done)

Comment threadproviders/imap/src/airflow/providers/imap/hooks/imap.py Outdated
@vincbeckvincbeck changed the title Fab fastapi user endpointMigrate Flask based user APIs to FastapiJan 23, 2026

@vincbeckvincbeck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@henry3260

Copy link
Copy Markdown
Contributor

Try running prek run --all-files locally, it should fix the formatting issues :)

@Fury0508

Copy link
Copy Markdown
ContributorAuthor

Try running prek run --all-files locally, it should fix the formatting issues :)

Thanks! Ran pre-commit run --all-files locally and pushed the fixes. Hopefully CI passes now 🤞

@Fury0508

Fury0508 commented Jan 23, 2026

Copy link
Copy Markdown
ContributorAuthor

@vincbeck CI has 2 failing checks:

  1. UI E2E tests - I only modified backend API code, no frontend changes

  2. Compat 3.0.6 - The error "Status code 204 must not have a response body" occurs in ALL FAB FastAPI route tests:

    • test_login.py (3 errors) - not modified by me
    • test_roles.py (23 errors) - not modified by me
    • test_users.py (22 errors) - my changes

The error happens during test setup, suggesting a TestClient compatibility issue with Airflow 3.0.6, not my code.

Could you confirm if these are known issues? Happy to investigate further if needed.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the CI failed because returning None results in a null response body, but HTTP 204 responses must not have a body. Please return an empty Response object instead.

@henry3260henry3260 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix. LGTM.

@vincbeck
vincbeck merged commit 9d64edf into apache:mainJan 26, 2026
128 checks passed
@boring-cyborg

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

shreyas-dev pushed a commit to shreyas-dev/airflow that referenced this pull request Jan 29, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jason810496 pushed a commit to abhijeets25012-tech/airflow that referenced this pull request Feb 3, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
jhgoebbert pushed a commit to jhgoebbert/airflow_Owen-CH-Leung that referenced this pull request Feb 8, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
choo121600 pushed a commit to choo121600/airflow that referenced this pull request Feb 22, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Subham-KRLX pushed a commit to Subham-KRLX/airflow that referenced this pull request Mar 4, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Ankurdeewan pushed a commit to Ankurdeewan/airflow that referenced this pull request Mar 15, 2026
* changes
* Replace connexion with FastAPI: user_endpoint.py
- Add GET /fab/v1/users (list with pagination/ordering)
- Add GET /fab/v1/users/{username}
- Add PATCH /fab/v1/users/{username} with update_mask support
- Add DELETE /fab/v1/users/{username}
- Add UserPatchBody and UserCollectionResponse datamodels
- Add comprehensive tests for routes, services, and datamodels
closesapache#60946
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace connexion with fast-api: user_endpoint.py

3 participants

@Fury0508@henry3260@vincbeck