<#7009 Add file_extension field to BlobType> Pull ...
# flyte-github
a
#7009 Add file_extension field to BlobType Pull request opened by ddl-rliu Tracking issue Closes #7024 [BUG] [copilot] File extensions are missing when copilot downloads Blob/FlyteFile inputs Why are the changes needed? We'll assume the above behavior is not a bug (it is long-standing, and a "bugfix" will likely break existing workflows). Instead, this PR proposes enhancements to FlyteFile/Blob to support writing workflow inputs with the file extension. This PR includes several changes across flyteidl and flytecopilot. The enhancements allow workflows to be flexible when writing blobs. Specifically, the existing behavior where flytecopilot writes blobs during the download phase without the file extension (e.g. "inputs/data") can now be enhanced so that the file extension is included (e.g. "inputs/data.csv"). edit: Just to add to the above - personally, I can use the
/inputs/data
path, and using user code the file can be renamed to
/inputs/data.csv
or something similar, if needed. But the key issue(s)/use case(s) is this: • We have a lot of users using Flyte, and bringing with them a great variety of user code. Highly technical users are comfortable changing the user code to rename file names for example, but the rest of the users get stuck and they find that their code fails when it runs in Flyte (namely, the user code expects
.csv
but flytecopilot writes the file without
.csv
) • So Flyte uses blob storage. But in parallel, all the data that users work with is living in an NFS file system. Namely, all their files in the NFS are typical files (
data.csv
, etc. - files with extensions). Then, all of their user code expects paths more-or-less like
/inputs/data.csv
. • Even though in Python, something like
pandas.read_csv(path)
is easily interchangeable with
path=/inputs/data vs. path=/inputs/data.csv
, many of our users write "SAS" code. SAS is a weird language where SAS datasets must have a particular name, like
/inputs/data.sas7bdat
, and it fails to process a file like
/inputs/data
. So unfortunately, a lot of the SAS scripts out-of-the-box will fail, but with a copilot file extensions fix, it does work! What changes were proposed in this pull request? [flyteidl] Add a new
file_extension
string field to the BlobType protobuf message, allowing FlyteFile to optionally specify a file extension (e.g. "csv") that flytecopilot appends when writing blobs during the download phase (e.g. "data.csv"). When empty (the default), behavior is unchanged. Add a new
enable_legacy_filename
bool field to the BlobType protobuf message, allowing FlyteFile to optionally specify whether to preserve backward compatibility for tasks that read from the extensionless path.
Regenerated all protobuf bindings (Go, Python, JS, Rust, ES, Swagger). [flytecopilot] The copilot download phase infers the desired download behavior(s) from the input interface. [flytekit] PR: flyteorg/flytekit#3406 Alternatives considered The PR's approach configures the file download behaviors at the BlobType level (e.g. per FlyteFile). This has several pros (granularity, explicitness). But, one con is that unlike
BlobType.format
(which can be inferred from the output filename e.g. "data.csv" ->
format: "csv"
), the new fields
BlobType.file_extension, BlobType.enable_legacy_filename
could not be inferred from the output filename (does "data.csv" match to
file_extension: "csv"
?). Ultimately, this seems like it is introducing a minor inconsistency, but acceptable given the benefits. (It also seems like this is all hypothetical - copilot upload does not actually infer the format from the filename, so this concern may be somewhat moot?) Here are the other approaches I considered: 1. New flyte-copilot CLI flags
--file_extension_config ENUM=(disabled, enabled, legacy)
file_extension_config = disabled (by default) - Same behavior as today (
data: FlyteFile[csv]
is written to
outputs/data
) file_extension_config = enabled - New behavior (
data: FlyteFile[csv]
is written to
outputs/data.csv
) file_extension_config = legacy - New behavior but backwards compatible, (
data: FlyteFile[csv]
is written to
outputs/data
and
outputs/data.csv
) Cons: • The download behavior is granular at the file level, but the CLI flag is granular at the task level (more or less). This makes the configuration less flexible, and begins to somewhat overload the configurability of copilot at the CLI level. 2. No changes, user code should be modified to read from the existing path e.g.
data
and add the extension itself
Cons: • Migrating large projects to Flyte becomes burdensome, when needing to add another extra step like this here - user code needs to be modified to handle adjusting the file extensions on inputs. How was this patch tested?
Copy code
# Container task python code
def t1(datasetA: FlyteFile[TypeVar('csv')], datasetB=Annotated[FlyteFile[TypeVar('csv')], FileDownloadConfig(file_extension="csv", enable_legacy_filename=True)]): …

# flyte-copilot logs
{"json":{},"level":"debug","msg":"inputInterface: [variables:{key:\"datasetA\"  value:{type:{blob:{format:\"csv\"}}  description:\"datasetA\"}}  variables:{key:\"datasetB\"  value:{type:{blob:{format:\"csv\"  file_extension:\"csv\"  enable_legacy_filename:true}}  description:\"datasetB\"}}]","ts":"2026-03-10T23:20:55Z"}
{"json":{},"level":"debug","msg":"varFilenames: map[datasetA:[datasetA[] datasetB:[datasetB.csv datasetB]]","ts":"2026-03-10T23:20:55Z"}
...
{"json":{},"level":"info","msg":"Successfully copied [4119] bytes remote data from [<s3://rliucp108882-flyte-data//a0c46ac7-eea3-427d-91c1-a3c6b4a27e83/datasetB>] to local [/execution-vol/flows/workflow/inputs/datasetB]","ts":"2026-03-10T23:20:55Z"}
{"json":{},"level":"info","msg":"Successfully copied [4119] bytes remote data from [<s3://rliucp108882-flyte-data//a0c46ac7-eea3-427d-91c1-a3c6b4a27e83/datasetB>] to local [/execution-vol/flows/workflow/inputs/datasetB.csv]","ts":"2026-03-10T23:20:55Z"}
{"json":{},"level":"info","msg":"Successfully copied [3904] bytes remote data from [<s3://rliucp108882-flyte-data//af859c71-811d-4c26-9845-b3fd8830ab6b/datasetA>] to local [/execution-vol/flows/workflow/inputs/datasetA]","ts":"2026-03-10T23:20:55Z"}
Labels Please add one or more of the following labels to categorize your PR: • added: For new features. • changed: For changes in existing functionality. • deprecated: For soon-to-be-removed features. • removed: For features being removed. • fixed: For any bug fixed. • security: In case of vulnerabilities This is important to improve the readability of release notes. Setup process Screenshots Check all the applicable boxes • I updated the documentation accordingly. • All new and existing tests passed. • All commits are signed-off. Related PRs Docs link flyteorg/flyte