Skip to content

Provide a uniform serialization contract (to_dict/to_json) across trigger binding types #351

Description

@larohra

Summary

Trigger/input binding objects lack a consistent, machine-usable serialization contract. Some expose to_dict(), some expose to_json() (returning a str), and most expose neither. Any consumer that needs to turn a binding object into structured data (logging, diagnostics, message pipelines, or feeding an LLM prompt) must special-case every type, and the natural fallback — str(obj) — yields an unusable Python repr (<azure.functions.blob.InputStream object at 0x...>) that silently drops the entire payload.

The inconsistency today (azure-functions 2.2.0)

Binding type to_dict() to_json() get_body() get_json() str(obj) result
blob.InputStream ❌ (read()) <...InputStream object at 0x...>
QueueMessage <azure.QueueMessage id=... > (body lost)
ServiceBusMessage <...ServiceBusMessage object at 0x...>
EventGridEvent <azure.EventGridEvent id=.. topic=.. > (data lost)
EventHubEvent <azure.EventHubEvent partition_key=.. > (body lost)
KafkaEvent <azure.KafkaEvent key=.. > (body lost)
Document (works)
DocumentList [<azure.Document ...>]
SqlRow / MySqlRow ✅ (str) <SqlRow at 0x...>
SqlRowList / MySqlRowList [<SqlRow ...>]
TimerRequest <...TimerRequest object at 0x...>

So four different conventions (or none) for the same conceptual operation: "give me this binding as JSON-safe data."

Impact

Downstream consumers must maintain a per-type adapter matrix and re-derive field names (name/uri/metadata, get_body(), get_json(), enqueued_time, partition_key, …), including bytes→text/base64 and datetime→ISO handling, purely to avoid the str() repr trap. This is fragile across SDK versions and duplicated in every project that needs it.

Proposal

Introduce a uniform, documented serialization contract implemented consistently across all binding types, e.g. one of:

  1. A to_dict() -> dict (JSON-safe) on every binding object, with a companion to_json() -> str, consistent in name and return type (today to_json returns a str on rows but a JSON string elsewhere, and to_dict exists only on Document); or
  2. A shared Serializable/SupportsToJson protocol (or a mixin base) that guarantees the method surface and centralizes bytes/datetime normalization.

Guidelines for the payload: bytes decoded as UTF-8 when valid else base64 (with an encoding marker), datetimes as ISO-8601, and blob bindings surfaced as name/uri/length/metadata without forcing a read() of content.

Context

Found while building an LLM-agent runtime on Azure Functions, where trigger data is serialized into the agent prompt. We worked around it with a per-type adapter layer, but a first-party contract would let all consumers drop the shim. Downstream reports: Azure/azure-functions-agents-runtime#85 and Azure/azure-functions-bucees-planning#1197.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions