Skip to main content

Ergonomic GCP data-access helpers: BigQuery <-> polars, GCS, and a SQL-hash parquet cache.

Project description

mooncompute

PyPI Python versions CI License: MIT

Ergonomic GCP data-access helpers, so you stop re-writing the same BigQuery <-> polars, GCS, and credential boilerplate in every project.

mooncompute.gcp gives you:

  • bq2pl(sql) - run SQL, get a polars DataFrame (Decimal columns cast to Float64 by default).
  • extract_cached(sql, cache, ...) - the same, wrapped in a local parquet cache keyed by a hash of the SQL. You must pick an invalidation mode: content_only=True (re-query on SQL change only) or max_age=<timedelta> (also re-query past a TTL); a bare call raises.
  • pl2bq(df, dataset=, table=) - load a polars DataFrame into BigQuery, with enable_list_inference set so ARRAY columns load correctly.
  • gcs.* - read/write parquet, JSON, and bytes over gs:// URIs.

Install

Dependencies are split into extras so you install only what you use. The base package is dependency-free (credential helper + gs:// URI parsing); pull an extra for actual I/O:

uv add "mooncompute[bq]"        # BigQuery <-> polars (polars, pyarrow, bigquery, db-dtypes)
uv add "mooncompute[gcs]"       # GCS JSON/bytes I/O (google-cloud-storage only)
uv add "mooncompute[bq,gcs]"    # both; also what you need for parquet on GCS
uv add "mooncompute[all]"       # alias for [bq,gcs]

GCS parquet helpers (gcs.read_parquet / write_parquet) lazily require polars, so install [bq,gcs] for them; the JSON/bytes path stays polars-free under [gcs] alone, keeping Cloud Function cold-starts light.

Configuration

The common path: set GOOGLE_CLOUD_PROJECT once and omit project= everywhere. The gcloud SDK already sets it, so on a configured machine there is nothing to do; otherwise:

export GOOGLE_CLOUD_PROJECT=my-project

Pass project= on any call to override it (e.g. multi-project work). A call that is given neither an explicit project= nor the env var raises.

Credentials use Application Default Credentials; in a Modal container, set a GOOGLE_APPLICATION_CREDENTIALS_JSON secret and it is materialized to ADC automatically.

Usage

from pathlib import Path

from mooncompute.gcp import bq, gcs

# With GOOGLE_CLOUD_PROJECT set, calls need no project= (pass project= to override):
df = bq.bq2pl("SELECT * FROM `proj.ds.tbl` LIMIT 10")

# SQL-hash-keyed parquet cache. You must pick an invalidation mode; a bare
# call raises. For a deterministic query (e.g. pinned to a snapshot date) pass
# content_only=True to invalidate on SQL change only:
df = bq.extract_cached(
    bq.read_sql("features.sql", snapshot="2024-10-01"),
    Path("data/features.parquet"),
    content_only=True,
)

# For a live/relative query, pass max_age to also re-query past a TTL (or use
# bq2pl for an always-live read). content_only and max_age are mutually exclusive.
from datetime import timedelta

df = bq.extract_cached(
    bq.read_sql("daily_active.sql"),
    Path("data/dau.parquet"),
    max_age=timedelta(hours=12),
)

# polars -> BQ (ARRAY columns handled via enable_list_inference)
bq.pl2bq(df, dataset="scratch", table="out")

# GCS round-trips over gs:// URIs
gcs.write_parquet(df, "gs://my-bucket/out.parquet")
df = gcs.read_parquet("gs://my-bucket/out.parquet")

Deploying on GCP

mooncompute is happiest baked into a container. ADC comes from the workload's service account, so credential materialization no-ops and the BQ/GCS clients just work.

Recommended path (Cloud Run service or job, Vertex custom job, Kubeflow container component): install at image-build time, then push to your registry.

FROM python:3.11-slim
ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
RUN pip install "mooncompute[bq,gcs]"

Caveats by target:

  • Cloud Run (service or job): best fit. No install-auth or cold-start concerns once baked into the image.
  • Kubeflow lightweight components (packages_to_install=[...]): the install runs in-pod at runtime; prefer a container component for a public/private install you control.
  • Cloud Functions: weakest fit, but install mooncompute[gcs] to keep the JSON/bytes path free of polars + pyarrow and their cold-start cost. Note extract_cached's parquet cache only lives in ephemeral /tmp; prefer gcs.* for durable artifacts there.

Scope

v1 ships mooncompute.gcp only. Modal, LLM/eval, and run-utils tiers may follow; see docs/ROADMAP.md.

Develop

just            # fmt + lint + typecheck + test
just ci         # non-mutating gate (check formatting, lint, typecheck, test)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mooncompute-0.3.1.tar.gz (74.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mooncompute-0.3.1-py3-none-any.whl (11.0 kB view details)

Uploaded Python 3

File details

Details for the file mooncompute-0.3.1.tar.gz.

File metadata

  • Download URL: mooncompute-0.3.1.tar.gz
  • Upload date:
  • Size: 74.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mooncompute-0.3.1.tar.gz
Algorithm Hash digest
SHA256 8d8a7e806e3d0af8089c6dfc34856e827648666b72841c25b0a34b0e09c39747
MD5 89f658e97d9f3d27f456adcf2a323fcb
BLAKE2b-256 0e2dc5e61181674feef44a196911ca1cfc6d54b324fe60a81dfd7a31a8b52cc6

See more details on using hashes here.

Provenance

The following attestation bundles were made for mooncompute-0.3.1.tar.gz:

Publisher: ci.yml on GarrettMooney/mooncompute

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mooncompute-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: mooncompute-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 11.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mooncompute-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e1db6ecb11aa5797a6b074361350f247be92b176f2887889446016f1a7324133
MD5 966424451e7dfba516c7bfb95e69d6ed
BLAKE2b-256 a4d12e2e3cca195b390b4f6ee79f53d9fddd233a0aea6fd0e00efe7d627dc29f

See more details on using hashes here.

Provenance

The following attestation bundles were made for mooncompute-0.3.1-py3-none-any.whl:

Publisher: ci.yml on GarrettMooney/mooncompute

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page