frank-ye opened a new pull request, #74666:
URL: https://github.com/apache/airflow/pull/74666

   ## Description
   
   `AirflowRunFacet.task` now carries two new keys, `inlets_list` and 
`outlets_list`, with the same assets as `inlets` / `outlets` but as real JSON 
lists instead of a Python `str(list)` repr. Runtime-emitted asset events (from 
`outlet_events`) are included, same as in `outlets`.
   
   Values in `extra` that JSON can't encode are cast with `str()` (e.g. 
`Decimal("10")` -> `"10"`, a date -> `"2026-01-02"`), and a `str` Enum uri is 
sent as its value. If conversion still fails, a warning is logged and the key 
is omitted, so the rest of the facet is unaffected.
   
   The existing `inlets` / `outlets` string keys are unchanged, so current 
consumers keep working.
   
   Before / after for one outlet whose `extra` has a quoted etag and a bool:
   
       "outlets":      "[{'uri': 's3://b/o.csv', 'extra': {'etag': '\"0xABC\"', 
'ok': True}, 'type': 'asset'}]"
       "outlets_list": [{"uri": "s3://b/o.csv", "extra": {"etag": "\"0xABC\"", 
"ok": true}, "type": "asset"}]
   
   ## Motivation
   
   `inlets` / `outlets` are sent as a Python repr string, so consumers have to 
parse Python literal syntax to get the asset uris. Since #65727 added runtime 
asset events, `extra` routinely holds free-form user payloads, and values like 
a string containing `"` or `'`, `True`, `None` or `Decimal(...)` make the usual 
"swap quotes and parse as JSON" approach fail for the whole list. A consumer 
then silently drops every outlet of the task. Sending a real list removes the 
need to parse a repr at all.
   
   related: #65727
   
   ## Testing
   
   - [X] Unit tests added / updated
     - `extra` with quotes, apostrophe, `True`, `None` -> preserved as-is in 
`outlets_list`
     - runtime asset events with `Decimal` / `date` in `extra` -> stringified, 
alias events keep `source_alias`
     - task with no inlets / outlets -> empty lists
     - non-encodable value (tuple dict key) -> warning logged, key omitted
   - [X] Serialized an `AirflowRunFacet` through the OpenLineage client's 
`Serde.to_json` and confirmed `outlets_list` comes out as a JSON array with all 
values intact
   
   ## Notes for Reviewer
   
   - The lists are written onto the dict after `InfoJsonEncodable.__init__`, 
because `_cast_basic_types` turns any list into a repr string. Happy to move 
this into a generic "raw fields" option on the base class if preferred.
   - Key naming (`*_list`) is open to suggestions.
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes (please specify the tool below)
   
   Generated-by: Claude Code (Opus 5.5) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   


-- 
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]

Reply via email to