IncomingFile Class
A lazy handle to a file attached to the current inbound activity.
Nothing is downloaded until a byte method is called. The handle stays live and holds no memoized bytes, so each of stream()/download()/text()/save_as() fetches afresh. For a personal file that re-fetch is bounded by the short-lived download URL lifetime and may hit its expiry; to read the same file several ways, call download() once and reuse the returned DownloadedFile.
Constructor
IncomingFile(*, name: str, scope: Literal['personal', 'groupChat', 'channel'] | str, source: Literal['botActivity', 'graph'], unique_id: str | None = None, content_type: str | None = None, extension: str | None = None, content_url: str | None = None, raw: Any = None, download_url: str | None = None, client: AsyncClient | None = None, credential: GraphCredential | None = None)
Keyword-Only Parameters
| Name | Description |
|---|---|
|
name
Required
|
|
|
scope
Required
|
|
|
source
Required
|
|
|
unique_id
|
Default value: None
|
|
content_type
|
Default value: None
|
|
extension
|
Default value: None
|
|
content_url
|
Default value: None
|
|
raw
|
Default value: None
|
|
download_url
|
Default value: None
|
|
client
|
Default value: None
|
|
credential
|
Default value: None
|
Methods
| download |
Fetch the whole file and buffer it into a DownloadedFile snapshot you own. Lazy and not memoized: calling again re-fetches. If you already hold a DownloadedFile, call its save_as() rather than this handle's, which would re-fetch. |
| save_as |
Stream the bytes straight to a local file path, so saving a large file never materializes it in memory. |
| stream |
Stream the bytes. Low-level primitive: yields the response body chunks directly from the fetch, single-consumption, not buffered or retained. Use for large files and pipelines (parse-as-you-go, pipe to disk). download() is built on this. Uncapped: the consumer bounds it by how much it reads. |
| text |
Convenience: run download() then decode the bytes as UTF-8 (or a provided encoding). Re-fetches on each call (no memoized bytes); to read bytes several ways hold one DownloadedFile instead. No content-type check; decoding is lossy (invalid bytes become U+FFFD and never throw). For strict or binary-safe reads, use download().bytes. |
download
Fetch the whole file and buffer it into a DownloadedFile snapshot you own. Lazy and not memoized: calling again re-fetches. If you already hold a DownloadedFile, call its save_as() rather than this handle's, which would re-fetch.
async download() -> DownloadedFile
save_as
Stream the bytes straight to a local file path, so saving a large file never materializes it in memory.
async save_as(path: str) -> None
Parameters
| Name | Description |
|---|---|
|
path
Required
|
|
stream
Stream the bytes. Low-level primitive: yields the response body chunks directly from the fetch, single-consumption, not buffered or retained. Use for large files and pipelines (parse-as-you-go, pipe to disk). download() is built on this. Uncapped: the consumer bounds it by how much it reads.
async stream() -> AsyncIterator[bytes]
text
Convenience: run download() then decode the bytes as UTF-8 (or a provided encoding). Re-fetches on each call (no memoized bytes); to read bytes several ways hold one DownloadedFile instead. No content-type check; decoding is lossy (invalid bytes become U+FFFD and never throw). For strict or binary-safe reads, use download().bytes.
async text(encoding: str = 'utf-8') -> str
Parameters
| Name | Description |
|---|---|
|
encoding
|
Default value: utf-8
|
Attributes
content_type
a file.download.info attachment carries no MIME type, only the file_type extension surfaced as extension. Populated for sources that do carry one, such as a graph drive item. To learn the type of the bytes you actually received, read DownloadedFile.content_type, which is resolved from the download response.
content_type: str | None
content_url
Browsable URL to the file in OneDrive/SharePoint, as sent on the attachment's content_url.
Not fetchable for bytes despite the name, but it is the locator a Graph /shares resolution keys off; bytes come from download() or stream().
content_url: str | None
extension
File extension without the dot (e.g. pdf), taken from the platform-supplied file_type. Absent when the wire omits it.
extension: str | None
name
Display name including extension when known.
name: str
raw
The raw underlying attachment/graph object for escape-hatch access.
raw: Any
scope
Conversation scope the file arrived in (the SDK's ConversationType).
scope: Literal['personal', 'groupChat', 'channel'] | str
source
Where the SDK found the file. Only botActivity is produced today.
source: Literal['botActivity', 'graph']
unique_id
The ODSP/OneDrive identifier for the file when the platform reports it (content.uniqueId). Useful for correlation, dedup and logging, but not for retrieval: the Graph fetch resolves bytes from content_url through /shares, and this value arrives as a GUID, which is a SharePoint listItemUniqueId shape rather than a Graph driveItem.id. Present only when the wire provided it.
unique_id: str | None