rahul-madaan opened a new pull request, #72711: URL: https://github.com/apache/airflow/pull/72711
Adds OAuth 2.0 client credentials authentication for the OpenLineage HTTP transport. The OpenLineage Python client ships only static `api_key` authentication (plus an API-key-to-JWT exchange) for HTTP transports, so backends that issue short-lived OAuth 2.0 access tokens could not be used from Airflow without a custom `TokenProvider` on the Python path. This PR adds: - `OAuth2ClientCredentialsTokenProvider`, usable as `auth.type` by import path (the client's documented extension mechanism) with `http` and `async_http` transports, including those nested in `composite`. Tokens are cached under a lock and re-requested `tokenRefreshBuffer` seconds before expiry (capped at half the token lifetime). Options accept camelCase and snake_case, so `OPENLINEAGE__TRANSPORT__AUTH__*` environment variables work as well. - `airflow_connection_oauth2_client_credentials` auth type, resolved like `airflow_connection_api_key` (#66342): client ID from the connection login, client secret from the password, token endpoint from the host. - Spark transport injection forwards the current access token as `api_key` (as already happens for the client's `jwt` provider) and logs the lifetime caveat; a token error logs a warning instead of failing the Spark task. Design notes: - The provider class lives in the Airflow provider because the connection-backed auth type and the Spark injection need it here. A generic version can be upstreamed to openlineage-python later and the connection alias pointed at it. - No short `oauth2_client_credentials` alias is introduced, so a future native client auth type of that name would not be shadowed by Airflow. - `time.monotonic` is mocked with `mock.patch` in tests because `time_machine` does not patch it. - `requests` is imported directly; it is a hard dependency of both `apache-airflow` and `openlineage-python`. Tested end to end against an OAuth-protected OpenLineage backend (Keycloak client credentials, 600 s tokens): `http`, `async_http` and `composite` transports, connection-backed configuration, a real Dag run, and a soak run confirming the token was refreshed before expiry while the original token was rejected once expired. --- ##### Was generative AI tooling used to co-author this PR? - [X] Yes — Claude Code (Fable 5.1) Generated-by: Claude Code (Fable 5.1) following [the guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01QBfMWG5AG33JMqGGQgAV6v -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
