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.2.tar.gz (74.9 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.2-py3-none-any.whl (11.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mooncompute-0.3.2.tar.gz
  • Upload date:
  • Size: 74.9 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.2.tar.gz
Algorithm Hash digest
SHA256 51023f071a3e32c9524e332915e45dafaa5148179891bb4a0e8b73bf49e7a726
MD5 5c008e80ed0c9a084458e23cc3994327
BLAKE2b-256 07e194c27e163c8c7679736bdfd8c82fead538bfc20ca0e8428dea5a34717be1

See more details on using hashes here.

Provenance

The following attestation bundles were made for mooncompute-0.3.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: mooncompute-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 11.2 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c6306d15c5be5a4f1370be77ee2d8a6ed545b217b3668b4c461b94c0f2f56c72
MD5 3408ea1ddbf0dc025acda3c73976502c
BLAKE2b-256 8c13a78188ffd080bd845bbc1f2f5028704b822688959f78936aa617259038b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for mooncompute-0.3.2-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