Module trase.tools.aws.s3_helpers
Functions
def bucket_exists(client, bucket: str)def download_file(key, bucket='trase-storage', version_id=None, path=None, client=None, force=False)-
Download an object stored in S3, but skip if the file already exists.
In particular, we skip the download if the local file has the same byte size and hash as the remote object (see :func:
file_differs).Examples
>>> download_file("candyland/metadata/assets.csv") '/var/folders/_m/s00h1rdj3m75ptngsv9tv52w0000gp/T/assets.csv'Args
key- the key to the object on S3, e.g. "candyland/metadata/assets.csv"
bucket:optional- the S3 bucket, defaults to bucket defined in trase.config.settings
version_id:optional- the specific version ID of the file to download, e.g. "yiJXp1MC0N5U128RoBtlWOcAEjHFVowi"
path:optional- the file path on the local file system to download the file to. If not provided then a file will be made in the temporary directory of the operating system. (Such temporary directories are usually cleared on every restart of the operating system). This path will be checked to determine whether to skip downloading the file.
force:bool, optional- whether to re-download the file even if it already exists on the file system.
Returns
The path to the downloaded file
def get_etag(client, bucket: str, key: str, version_id: str | None = None) ‑> strdef get_latest_s3_inventory(client=<botocore.client.S3 object>) ‑> pandas.core.frame.DataFrame-
Read the most recent S3-Inventory snapshot (see :func:
read_s3_inventory_manifest()). def get_version_id(client, bucket: str, key: str) ‑> str | None-
Fetch the latest version id for an S3 object.
Returns: the version id or
Noneif it does not exist (for example, if the bucket does not have version control enabled) def head_object(client, bucket: str, key: str, version_id: str | None = None)def head_objects(client, bucket: str, keys: List[str]) ‑> List[dict | None]-
Head multiple objects at once, issuing as few requests to S3 as possible.
The S3 API has an operation called HeadObject. However, it only allows you to specify a single S3 object. When you have a lot of objects, the fact that you have to issue one request per object means that the whole operation can be quite slow.
This function gets around this by using the ListObjectsV2 operation instead. This allows you to specify a S3 prefix, and returns much of the same information as HeadObject, including LastModified, ETag, and Size.
However, this function does not support specifiying a specific VersionId: it will only list the latest version of objects. If you wish to specify VersionId then use
head_object().Returns: a list of dictionaries containing the response from ListObjectsV2. Each dictionary will have the keys Key, LastModified, ETag, Size and StorageClass. The order and size of the list will match the keys parameter that was passed in. If an object does not exist, the entry will be None.
def key_pattern_exists(client, bucket: str, key_pattern: str) ‑> bool-
Like :func:
object_exists(), but understands a dbt external-location '' glob (e.g."foo/bar_*_extracted_*.parquet"or"foo/*/*.json"): HeadObject can't match a wildcard key, so a literal head_object() call on a glob pattern always 404s even when matching files exist. Instead, this lists every object under the fixed prefix before the first '' and returns True if any of them matches the full pattern. def list_access_log_keys(after_key=None, client=<botocore.client.S3 object>)-
Return access-log object keys under
trase-storage-access-logs/, sorted ascending and skipping zero-byte objects.Filenames are date-prefixed (
YYYY-MM-DD-HH-MM-SS-<id>) so a lexical sort is chronological;after_key(exclusive) acts as a high-watermark for incremental loads. def list_objects(key_prefix, bucket='trase-storage', client=<botocore.client.S3 object>)def list_s3_inventory_manifests(client=<botocore.client.S3 object>)-
Return
[(snapshot_ts, manifest_key), …]for every S3-Inventory snapshot, sorted oldest→newest.snapshot_tsis the per-run directory name S3 writes (e.g.2026-05-31T01-00Z). def object_exists(client, bucket: str, key: str, version_id: str | None = None)def read_s3_inventory_manifest(manifest_key, client=<botocore.client.S3 object>, progress: bool = False) ‑> pandas.core.frame.DataFrame-
Read a single inventory snapshot — every gz CSV data file referenced by its
manifest.json— into a DataFrame with :data:INVENTORY_COLUMNS(all strings).Set
progress=Trueto print a line per data file (the gz CSVs can be tens of MB each, so this reassures long runs they're progressing). def split_s3_path(s3_path: str)-
Splits an S3 path into bucket and key.
Args
s3_path:str- Full S3 path (e.g., 's3://my-bucket/path/to/file.txt')
Returns
tuple- (bucket, key)