Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connections API is able to patch all fields correctly #48109

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

jscheffl
Copy link
Contributor

During implementation of #48102 we saw that the patch API for connections is not working correctly.

This PR fixes the problem - reason is that pydantic fields to not map 1:1 to API fields - as well as extends pytests to cover the difference

@boring-cyborg boring-cyborg bot added the area:API Airflow's REST/HTTP API label Mar 23, 2025
@jscheffl jscheffl added the type:bug-fix Changelog: Bug Fixes label Mar 23, 2025
Comment on lines 202 to 218
# Not all fields match, therefore copy manually
if not update_mask or "conn_type" in update_mask:
connection.conn_type = patch_body.conn_type
if not update_mask or "description" in update_mask:
connection.description = patch_body.description
if not update_mask or "host" in update_mask:
connection.host = patch_body.host
if not update_mask or "schema" in update_mask:
connection.schema = patch_body.schema_
if not update_mask or "login" in update_mask:
connection.login = patch_body.login
if not update_mask or "password" in update_mask:
connection._password = patch_body.password
if not update_mask or "port" in update_mask:
connection.port = patch_body.port
if not update_mask or "extra" in update_mask:
connection._extra = patch_body.extra
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if instead of hard-coding this list here, we should make use of Pydantic's aliases so that the mapping can be maintained in the datamodel and handled for us by pydantic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was before. And not working.
But we need a mapping in both directions unfortunately, schema is aliased to schema_ and on the other hand _password and _extra need to be aliased with underscore in the front :-(

Copy link
Contributor Author

@jscheffl jscheffl Mar 23, 2025

Choose a reason for hiding this comment

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

@ashb okay even worse. Took a look deeper into code. The model_dump()/property-transfer is only working if you create a new DB connection object (as this maps the internals in __init__()). Otherwise for password and extra because of encryption you need to walk via the official setters to properly update the fields.

Hope this is okay?

Also adjusted the Bulk API service, this had the same problem. Also consolidated the Pydantic to ORM mapping to one helper function.

Copy link
Member

@pierrejeambrun pierrejeambrun left a comment

Choose a reason for hiding this comment

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

Nice, thanks for the catch.

@jscheffl jscheffl force-pushed the bugfix/connections-api-patch-all-fields branch from 0ec69f1 to 1441339 Compare March 25, 2025 22:06
@jscheffl jscheffl requested a review from pierrejeambrun March 25, 2025 22:06
@jscheffl jscheffl added this to the Airflow 3.0.0 milestone Mar 25, 2025
Copy link
Member

@pierrejeambrun pierrejeambrun left a comment

Choose a reason for hiding this comment

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

Yep, sounds good to me.

Just a few nits and one test need fixing

@@ -569,7 +608,7 @@ def test_patch_should_respond_404(self, test_client, body):

@pytest.mark.enable_redact
@pytest.mark.parametrize(
"body, expected_response",
"body, expected_response, update_mask",
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need the update_mask update.

All fields that are wet will be updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, we should. Especially because of the Alias and logic you requested to make "better" the current pytest found a regression. Actually needed to scratch my head 3-times until I found the bug.

The more I look on the revised code comparing to the previous list the more I hate it. Over generlized. And error prone because of aliases. So we SHOULD keep this pytest with update mask.

@jscheffl jscheffl force-pushed the bugfix/connections-api-patch-all-fields branch from 1441339 to 7f187e5 Compare March 26, 2025 20:58
Copy link
Member

@pierrejeambrun pierrejeambrun left a comment

Choose a reason for hiding this comment

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

I think we removed the model_fields_set and this is the source of confusion.

When no 'mask' is passed to the function, only fields that are explicitely specified in the payload (even if passed to 'None') should be set. Other missing fields from the partial body should not be updated. I tried locally and we observe the opposite in this current state.

@jscheffl jscheffl force-pushed the bugfix/connections-api-patch-all-fields branch from 7f187e5 to a7ff401 Compare March 27, 2025 21:05
@jscheffl jscheffl requested a review from pierrejeambrun March 27, 2025 21:06
@jscheffl jscheffl force-pushed the bugfix/connections-api-patch-all-fields branch from a7ff401 to dca8763 Compare March 29, 2025 19:42
Copy link
Member

@pierrejeambrun pierrejeambrun left a comment

Choose a reason for hiding this comment

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

Nice thanks

Comment on lines +518 to +524
{
"connection_id": TEST_CONN_ID,
"conn_type": TEST_CONN_TYPE,
"extra": '{"key": "var"}',
"login": None,
"port": None,
},
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Such test case would be awesome for test_patch_should_respond_200 where no mask is provided. Just to be sure that it behaves as we expect. (setting to None login and port)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:API Airflow's REST/HTTP API type:bug-fix Changelog: Bug Fixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants