Skip to content

[python] What TypeSpec type maps to IO[bytes] for a streaming binary body? #11107

Description

@l0lawrence

Question

What TypeSpec type is supposed to map to IO[bytes] in the Python emitter?

Today there does not seem to be a way to author a spec whose generated client method takes a streaming binary body as IO[bytes]:

  • A bytes body maps to Python bytes (read fully into memory), e.g.:

    @post
    op upload(
      @header contentType: "application/octet-stream",
      @body body: bytes,
    ): void;

    generates:

    def upload(self, body: bytes, **kwargs: Any) -> None: ...
  • A JSON model body is the only thing that produces an IO[bytes] form, and only as the auto-generated binary overload alongside the model (Union[Model, IO[bytes]]) — never on its own.

IO[bytes] itself (BinaryType) is only ever injected by the generator (pygen/preprocess/__init__.py add_body_param_type), gated on model/dict/list bodies with a JSON (or multipart) content type:

if (
    body_parameter
    and body_parameter["type"]["type"] in ("model", "dict", "list")
    and (
        has_json_content_type(body_parameter)
        or (self.is_tsp and has_multi_part_content_type(body_parameter))
    )
    ...
):
    ...
    body_parameter["type"]["types"].append(KNOWN_TYPES["binary"])

A bytes body has type == "bytes", so it never goes down this path.

So:

  1. Is there an existing TypeSpec type/pattern that is intended to emit IO[bytes] (streaming binary body) for the Python client, and we're just missing it?
  2. If not, should a bytes body grow an IO[bytes] overload (e.g. Union[bytes, IO[bytes]] or a true @overload) so callers can pass a file/stream without materializing the whole payload in memory?

The common motivation is binary upload operations where reading the entire body into bytes is undesirable.

Notes

  • The current JSON-only gating is long-standing (introduced with the original emitter migration, Migrate python emitter #4182), not a recent regression.

Metadata

Metadata

Assignees

No one assigned

    Labels

    emitter:client:pythonIssue for the Python client emitter: @typespec/http-client-pythonfeatureNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions