Repository: pydantic/pydantic-ai
File: pydantic_ai_slim/pydantic_ai/messages.py (Python)

Code before:
    dynamic_ref: str | None = None
    """The ref of the dynamic system prompt function that generated this part.

    Only set if system prompt is dynamic, see [`system_prompt`][pydantic_ai.Agent.system_prompt] for more information.
    """

    part_kind: Literal['system-prompt'] = 'system-prompt'
    """Part type identifier, this is available on all parts as a discriminator."""

    def otel_event(self, settings: InstrumentationSettings) -> Event:
        return Event(
            'gen_ai.system.message',
            body={'role': 'system', **({'content': self.content} if settings.include_content else {})},
        )

    __repr__ = _utils.dataclasses_no_defaults_repr


@dataclass(repr=False)
class FileUrl(ABC):
    """Abstract base class for any URL-based file."""

    url: str
    """The URL of the file."""

    _media_type: str | None = field(default=None, repr=False)
    """Optional override for the media type of the file, in case it cannot be inferred from the URL."""

    force_download: bool = False
    """If the model supports it:

    * If True, the file is downloaded and the data is sent to the model as bytes.
    * If False, the URL is sent directly to the model and no download is performed.
    """

    vendor_metadata: dict[str, Any] | None = None
    """Vendor-specific metadata for the file.

    Supported by:
    - `GoogleModel`: `VideoUrl.vendor_metadata` is used as `video_metadata`: https://ai.google.dev/gemini-api/docs/video-understanding#customize-video-processing
    """

    @abstractmethod
    def _infer_media_type_from_url(self) -> str:
        """Return the media type of the file, based on the url."""

    @property
    def media_type(self) -> str:
        """Return the media type of the file, based on the url or the provided `_media_type`."""
        if self._media_type is not None:
            return self._media_type

Review comment (suggestion):
@DouweM I diverged from your proposition of setting `media_type` in the `__post_init__`, because I realized (after the fact...) that it would make it mandatory to specify it in cases where it's not needed/relevant, e.g. when `force_download==True` or when it's a youtube video url. (I figured making the field optional would be too messy)


Code after:
    dynamic_ref: str | None = None
    """The ref of the dynamic system prompt function that generated this part.

    Only set if system prompt is dynamic, see [`system_prompt`][pydantic_ai.Agent.system_prompt] for more information.
    """

    part_kind: Literal['system-prompt'] = 'system-prompt'
    """Part type identifier, this is available on all parts as a discriminator."""

    def otel_event(self, settings: InstrumentationSettings) -> Event:
        return Event(
            'gen_ai.system.message',
            body={'role': 'system', **({'content': self.content} if settings.include_content else {})},
        )

    __repr__ = _utils.dataclasses_no_defaults_repr


@dataclass(init=False, repr=False)
class FileUrl(ABC):
    """Abstract base class for any URL-based file."""

    url: str
    """The URL of the file."""

    force_download: bool = False
    """If the model supports it:

    * If True, the file is downloaded and the data is sent to the model as bytes.
    * If False, the URL is sent directly to the model and no download is performed.
    """

    vendor_metadata: dict[str, Any] | None = None
    """Vendor-specific metadata for the file.

    Supported by:
    - `GoogleModel`: `VideoUrl.vendor_metadata` is used as `video_metadata`: https://ai.google.dev/gemini-api/docs/video-understanding#customize-video-processing
    """

    _media_type: str | None = field(init=False, repr=False)

    def __init__(
        self,
        url: str,
        force_download: bool = False,
        vendor_metadata: dict[str, Any] | None = None,
        media_type: str | None = None,
    ) -> None:
        self.url = url
        self.vendor_metadata = vendor_metadata
        self.force_download = force_download