From 0b9e2a78ccf82c12bb0c2fa052958188eb93bb62 Mon Sep 17 00:00:00 2001 From: Brent Bovenzi Date: Fri, 23 Feb 2024 11:07:04 -0500 Subject: [PATCH] Add excluded/included events to get_event_logs api (#37641) * Add excluded/included events to get_event_logs api * Clean up tests * fix tests --- .../endpoints/event_log_endpoint.py | 8 +++++++ airflow/api_connexion/openapi/v1.yaml | 16 +++++++++++++ airflow/www/static/js/types/api-generated.ts | 10 ++++++++ .../endpoints/test_event_log_endpoint.py | 24 +++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/airflow/api_connexion/endpoints/event_log_endpoint.py b/airflow/api_connexion/endpoints/event_log_endpoint.py index 75c951d8f10c2..9489d7a7bb149 100644 --- a/airflow/api_connexion/endpoints/event_log_endpoint.py +++ b/airflow/api_connexion/endpoints/event_log_endpoint.py @@ -58,6 +58,8 @@ def get_event_logs( task_id: str | None = None, owner: str | None = None, event: str | None = None, + excluded_events: str | None = None, + included_events: str | None = None, before: str | None = None, after: str | None = None, limit: int, @@ -88,6 +90,12 @@ def get_event_logs( query = query.where(Log.owner == owner) if event: query = query.where(Log.event == event) + if included_events: + included_events_list = included_events.split(",") + query = query.where(Log.event.in_(included_events_list)) + if excluded_events: + excluded_events_list = excluded_events.split(",") + query = query.where(Log.event.notin_(excluded_events_list)) if before: query = query.where(Log.dttm < timezone.parse(before)) if after: diff --git a/airflow/api_connexion/openapi/v1.yaml b/airflow/api_connexion/openapi/v1.yaml index 8637612df8194..4e8a3ac618f4d 100644 --- a/airflow/api_connexion/openapi/v1.yaml +++ b/airflow/api_connexion/openapi/v1.yaml @@ -1160,6 +1160,22 @@ paths: - $ref: "#/components/parameters/Owner" - $ref: "#/components/parameters/Before" - $ref: "#/components/parameters/After" + - name: included_events + in: query + schema: + type: string + required: false + description: | + One or more event names separated by commas. If set, only return event logs with events matching this pattern. + *New in version 2.9.0* + - name: excluded_events + in: query + schema: + type: string + required: false + description: | + One or more event names separated by commas. If set, only return event logs with events that do not match this pattern. + *New in version 2.9.0* responses: "200": description: Success. diff --git a/airflow/www/static/js/types/api-generated.ts b/airflow/www/static/js/types/api-generated.ts index 1184dd5323732..3d6688d7b33fd 100644 --- a/airflow/www/static/js/types/api-generated.ts +++ b/airflow/www/static/js/types/api-generated.ts @@ -3510,6 +3510,16 @@ export interface operations { before?: components["parameters"]["Before"]; /** Timestamp to select event logs occurring after. */ after?: components["parameters"]["After"]; + /** + * One or more event names separated by commas. If set, only return event logs with events matching this pattern. + * *New in version 2.9.0* + */ + included_events?: string; + /** + * One or more event names separated by commas. If set, only return event logs with events that do not match this pattern. + * *New in version 2.9.0* + */ + excluded_events?: string; }; }; responses: { diff --git a/tests/api_connexion/endpoints/test_event_log_endpoint.py b/tests/api_connexion/endpoints/test_event_log_endpoint.py index 6c1811506cf71..064aa3fba33f8 100644 --- a/tests/api_connexion/endpoints/test_event_log_endpoint.py +++ b/tests/api_connexion/endpoints/test_event_log_endpoint.py @@ -291,6 +291,30 @@ def test_should_filter_eventlogs_by_when(self, create_log_model, session): assert response.status_code == 200 assert {eventlog["event"] for eventlog in response.json["event_logs"]} == expected_eventlogs + def test_should_filter_eventlogs_by_included_events(self, create_log_model): + for event in ["TEST_EVENT_1", "TEST_EVENT_2", "cli_scheduler"]: + create_log_model(event=event, when=self.default_time) + response = self.client.get( + "/api/v1/eventLogs?included_events=TEST_EVENT_1,TEST_EVENT_2", + environ_overrides={"REMOTE_USER": "test_granular"}, + ) + assert response.status_code == 200 + response_data = response.json + assert len(response_data["event_logs"]) == 2 + assert {"TEST_EVENT_1", "TEST_EVENT_2"} == {x["event"] for x in response_data["event_logs"]} + + def test_should_filter_eventlogs_by_excluded_events(self, create_log_model): + for event in ["TEST_EVENT_1", "TEST_EVENT_2", "cli_scheduler"]: + create_log_model(event=event, when=self.default_time) + response = self.client.get( + "/api/v1/eventLogs?excluded_events=TEST_EVENT_1,TEST_EVENT_2", + environ_overrides={"REMOTE_USER": "test_granular"}, + ) + assert response.status_code == 200 + response_data = response.json + assert len(response_data["event_logs"]) == 1 + assert {"cli_scheduler"} == {x["event"] for x in response_data["event_logs"]} + class TestGetEventLogPagination(TestEventLogEndpoint): @pytest.mark.parametrize(