yggdrasil.aws¶
AWS integration — AWSClient singleton, S3 filesystem, and credential management. Mirrors the Databricks-side organization.
Optional dependency: boto3. Install with pip install "ygg[aws]" (or pip install boto3).
One-liner¶
from yggdrasil.aws import AWSClient
from yggdrasil.aws.fs import S3Path
p = S3Path("s3://my-bucket/data/events.parquet")
print(p.read_bytes()[:50])
AWSClient¶
AWSClient is a singleton-cached client per identity configuration. Passing the same arguments returns the same instance.
from yggdrasil.aws import AWSClient
# Default credential chain (env vars → profile → instance metadata)
client = AWSClient()
# Explicit role (STS assume-role)
client = AWSClient(
role_arn="arn:aws:iam::123456789012:role/DataReader",
region="us-east-1",
)
# Named profile
client = AWSClient(profile="prod-readonly")
# IAM Identity Center (SSO) with browser login
client = AWSClient(
sso_start_url="https://example.awsapps.com/start",
sso_region="us-east-1",
sso_account_id="123456789012",
sso_role_name="DataReader",
)
S3 service and paths¶
from yggdrasil.aws import AWSClient
client = AWSClient(region="eu-west-1")
s3 = client.s3 # S3Service
# Build a path via the service (credentials already bound)
path = s3.path("s3://my-bucket/prefix/file.parquet")
# Or build directly (uses default credential chain)
from yggdrasil.aws.fs import S3Path
path = S3Path("s3://my-bucket/prefix/file.parquet")
S3Path — file operations¶
S3Path behaves like a pathlib.Path over S3:
from yggdrasil.aws.fs import S3Path
path = S3Path("s3://my-bucket/data/events.parquet")
# Read / write bytes
content = path.read_bytes()
path.write_bytes(b"hello world")
# Read / write text
text = path.read_text()
path.write_text("hello world")
# Check existence
print(path.exists())
# List a prefix (directory-like)
prefix = S3Path("s3://my-bucket/data/")
for child in prefix.iterdir():
print(child)
# Delete
path.unlink(missing_ok=True)
# Copy
path.copy_to(S3Path("s3://my-bucket/data/events_backup.parquet"))
Arrow filesystem integration¶
Use S3Path with pyarrow for Parquet / Feather / CSV I/O:
import pyarrow.parquet as pq
import pyarrow as pa
from yggdrasil.aws import AWSClient
client = AWSClient(region="us-east-1", role_arn="arn:aws:iam::123:role/Reader")
fs = client.s3.arrow_filesystem()
# Write Parquet
table = pa.table({"id": [1, 2, 3], "score": [9.1, 8.7, 7.4]})
pq.write_table(table, "my-bucket/scores/batch.parquet", filesystem=fs)
# Read Parquet
tbl = pq.read_table("my-bucket/scores/", filesystem=fs)
Credentials¶
from yggdrasil.aws import AwsCredentials, AWSClient
# STS credentials (from a Databricks storage credential vend, for example)
creds = AwsCredentials(
access_key_id="AKIA...",
secret_access_key="...",
session_token="...",
)
client = AWSClient.from_credentials(creds, region="us-east-1")
# Credentials provider (refreshes automatically)
from yggdrasil.aws import AwsCredentialsProvider
provider = AwsCredentialsProvider(client=client)
Databricks volume → S3 bridge¶
When a Databricks external volume is backed by S3, the volume vends temporary credentials. Use them to build an AWSClient:
from yggdrasil.databricks import DatabricksClient
from yggdrasil.aws import AWSClient
from yggdrasil.data.enums import Mode
vol = DatabricksClient().volumes["main.external.s3data"]
creds = vol.temporary_credentials(mode=Mode.READ)
client = AWSClient.from_credentials(creds)
fs = client.s3.arrow_filesystem()
import pyarrow.parquet as pq
tbl = pq.read_table("s3data/events/", filesystem=fs)
Full S3 ingest pipeline¶
from yggdrasil.aws import AWSClient
from yggdrasil.aws.fs import S3Path
import pyarrow as pa
import pyarrow.parquet as pq
client = AWSClient(role_arn="arn:aws:iam::123:role/ETL", region="eu-west-1")
fs = client.s3.arrow_filesystem()
# Read all Parquet files under a prefix
table = pq.read_table("my-bucket/raw/events/2026/05/", filesystem=fs)
# Transform
import polars as pl
df = pl.from_arrow(table).filter(pl.col("status") == "active")
# Write back
pq.write_table(df.to_arrow(), "my-bucket/curated/events_active.parquet", filesystem=fs)