Repository navigation
Add CRUD endpoint for XCom #9482
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
Changes from all commits
049b9e7
18297c6
2a5ecdc
4357e26
17cd801
c4e665c
a6f990a
d809420
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,25 +14,47 @@ | |||||||||||||||||||||||||||
| # KIND, either express or implied. See the License for the | ||||||||||||||||||||||||||||
| # specific language governing permissions and limitations | ||||||||||||||||||||||||||||
| # under the License. | ||||||||||||||||||||||||||||
| from flask import request | ||||||||||||||||||||||||||||
| from typing import List, Optional | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| from flask import Response, request | ||||||||||||||||||||||||||||
| from marshmallow import ValidationError | ||||||||||||||||||||||||||||
| from sqlalchemy import and_, func | ||||||||||||||||||||||||||||
| from sqlalchemy.orm.session import Session | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| from airflow.api_connexion import parameters | ||||||||||||||||||||||||||||
| from airflow.api_connexion.exceptions import NotFound | ||||||||||||||||||||||||||||
| from airflow.api_connexion.exceptions import BadRequest, NotFound | ||||||||||||||||||||||||||||
| from airflow.api_connexion.schemas.xcom_schema import ( | ||||||||||||||||||||||||||||
| XComCollection, XComCollectionItemSchema, XComCollectionSchema, xcom_collection_item_schema, | ||||||||||||||||||||||||||||
| xcom_collection_schema, | ||||||||||||||||||||||||||||
| xcom_collection_schema, xcom_schema, | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| from airflow.models import DagRun as DR, XCom | ||||||||||||||||||||||||||||
| from airflow.utils.session import provide_session | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def delete_xcom_entry(): | ||||||||||||||||||||||||||||
| @provide_session | ||||||||||||||||||||||||||||
| def delete_xcom_entry( | ||||||||||||||||||||||||||||
| dag_id: str, | ||||||||||||||||||||||||||||
| dag_run_id: str, | ||||||||||||||||||||||||||||
| task_id: str, | ||||||||||||||||||||||||||||
| xcom_key: str, | ||||||||||||||||||||||||||||
| session: Session | ||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| Delete an XCom entry | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| raise NotImplementedError("Not implemented yet.") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| dag_run = session.query(DR).filter(DR.run_id == dag_run_id, | ||||||||||||||||||||||||||||
| DR.dag_id == dag_id).first() | ||||||||||||||||||||||||||||
| if not dag_run: | ||||||||||||||||||||||||||||
| raise NotFound(f'DAGRun with dag_id:{dag_id} and run_id:{dag_run_id} not found') | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| entry = session.query(XCom).filter(XCom.dag_id == dag_id, | ||||||||||||||||||||||||||||
| XCom.task_id == task_id, | ||||||||||||||||||||||||||||
| XCom.key == xcom_key).delete() | ||||||||||||||||||||||||||||
| if not entry: | ||||||||||||||||||||||||||||
| raise NotFound("XCom entry not found") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return Response('', 204) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @provide_session | ||||||||||||||||||||||||||||
|
|
@@ -89,15 +111,78 @@ def get_xcom_entry( | |||||||||||||||||||||||||||
| return xcom_collection_item_schema.dump(query_object) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def patch_xcom_entry(): | ||||||||||||||||||||||||||||
| @provide_session | ||||||||||||||||||||||||||||
| def patch_xcom_entry( | ||||||||||||||||||||||||||||
| session: Session, | ||||||||||||||||||||||||||||
| dag_id: str, | ||||||||||||||||||||||||||||
| dag_run_id: str, | ||||||||||||||||||||||||||||
| task_id: str, | ||||||||||||||||||||||||||||
| xcom_key: str, | ||||||||||||||||||||||||||||
| update_mask: Optional[List[str]] = None | ||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| Update an XCom entry | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| raise NotImplementedError("Not implemented yet.") | ||||||||||||||||||||||||||||
| dag_run = session.query(DR).filter(DR.run_id == dag_run_id, | ||||||||||||||||||||||||||||
| DR.dag_id == dag_id).first() | ||||||||||||||||||||||||||||
| if not dag_run: | ||||||||||||||||||||||||||||
| raise NotFound(f'DAGRun with dag_id:{dag_id} and run_id:{dag_run_id} not found') | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| xcom_entry = session.query(XCom).filter(XCom.dag_id == dag_id, | ||||||||||||||||||||||||||||
| XCom.task_id == task_id, | ||||||||||||||||||||||||||||
| XCom.key == xcom_key).first() | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if not xcom_entry: | ||||||||||||||||||||||||||||
| raise NotFound("XCom not found") | ||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||
| body = xcom_schema.load(request.json, partial=("dag_id", "task_id", | ||||||||||||||||||||||||||||
| "key", "execution_date")) | ||||||||||||||||||||||||||||
| except ValidationError as err: | ||||||||||||||||||||||||||||
| raise BadRequest(detail=err.messages.get('_schema', [str(err.messages)])[0]) | ||||||||||||||||||||||||||||
| data = body.data | ||||||||||||||||||||||||||||
| # Check that other attributes are not being updated | ||||||||||||||||||||||||||||
| for field in data: | ||||||||||||||||||||||||||||
| if field != 'value' and data[field] != getattr(xcom_entry, field): | ||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this may result in error if there's no |
||||||||||||||||||||||||||||
| raise BadRequest(detail=f"'{field}' cannot be updated") | ||||||||||||||||||||||||||||
| if update_mask: | ||||||||||||||||||||||||||||
| update_mask = [i.strip() for i in update_mask] | ||||||||||||||||||||||||||||
| data_ = {} | ||||||||||||||||||||||||||||
| for field in update_mask: | ||||||||||||||||||||||||||||
| if field in data and field != 'value': | ||||||||||||||||||||||||||||
|
Comment on lines
+148
to
+151
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
One loop only, WDYT? |
||||||||||||||||||||||||||||
| raise BadRequest(detail=f"{field} cannot be updated") | ||||||||||||||||||||||||||||
| elif field in data and field == 'value': | ||||||||||||||||||||||||||||
| data_[field] = data[field] | ||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||
| raise BadRequest(detail=f"Unknown field '{field}' in update_mask") | ||||||||||||||||||||||||||||
|
Comment on lines
+151
to
+156
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
WDYT?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very nice 👍
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about: if field not in data:
raise BadRequest(detail=f"Unknown field '{field}' in update_mask")
if field != 'value':
raise BadRequest(detail=f"{field} cannot be updated")
if field == 'value':
data_[field] = data[field] |
||||||||||||||||||||||||||||
| data = data_ | ||||||||||||||||||||||||||||
| data['value'] = XCom.serialize_value(data['value']) | ||||||||||||||||||||||||||||
| xcom_entry.value = data['value'] | ||||||||||||||||||||||||||||
| session.add(xcom_entry) | ||||||||||||||||||||||||||||
| session.commit() | ||||||||||||||||||||||||||||
| return xcom_schema.dump(xcom_entry) | ||||||||||||||||||||||||||||
|
Comment on lines
+161
to
+162
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Which is correct. So I am for removing the manual commit from there. |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| def post_xcom_entries(): | ||||||||||||||||||||||||||||
| @provide_session | ||||||||||||||||||||||||||||
| def post_xcom_entries(dag_id: str, | ||||||||||||||||||||||||||||
| dag_run_id: str, | ||||||||||||||||||||||||||||
| task_id: str, | ||||||||||||||||||||||||||||
| session: Session | ||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| Create an XCom entry | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
| raise NotImplementedError("Not implemented yet.") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| dag_run = session.query(DR).filter(DR.run_id == dag_run_id, DR.dag_id == dag_id).first() | ||||||||||||||||||||||||||||
| if not dag_run: | ||||||||||||||||||||||||||||
| raise NotFound(f'DAGRun with dag_id:{dag_id} and run_id:{dag_run_id} not found') | ||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||
| xcom_entry = xcom_schema.load(request.json) | ||||||||||||||||||||||||||||
| except ValidationError as err: | ||||||||||||||||||||||||||||
| raise BadRequest(detail=err.messages.get('_schema', [str(err.messages)])[0]) | ||||||||||||||||||||||||||||
| session.query(XCom).filter(XCom.dag_id == dag_id, XCom.task_id == task_id).delete() | ||||||||||||||||||||||||||||
| data = xcom_entry.data | ||||||||||||||||||||||||||||
| data['value'] = XCom.serialize_value(data['value']) | ||||||||||||||||||||||||||||
| xcom = XCom(**data) | ||||||||||||||||||||||||||||
| session.add(xcom) | ||||||||||||||||||||||||||||
| session.commit() | ||||||||||||||||||||||||||||
| return xcom_schema.dump(xcom) | ||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.