Ergonomic GCP data-access helpers: BigQuery <-> polars, GCS, and a SQL-hash parquet cache.
Project description
mooncompute
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: re-queries only when the SQL changes.pl2bq(df, dataset=, table=)- load a polars DataFrame into BigQuery, withenable_list_inferenceset so ARRAY columns load correctly.gcs.*- read/write parquet, JSON, and bytes overgs://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. Noteextract_cached's parquet cache only lives in ephemeral/tmp; prefergcs.*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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mooncompute-0.3.0.tar.gz.
File metadata
- Download URL: mooncompute-0.3.0.tar.gz
- Upload date:
- Size: 74.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0b1fa1473fdf365ae29efa6997449e7806556af58b53a86bf947a13038fa799
|
|
| MD5 |
90047e6667edeffd2b9933b0bc2ea53a
|
|
| BLAKE2b-256 |
928c824c4d5f7bd23ccc3f0f322137c31d5f0ed5639007da03bad03c355c457b
|
Provenance
The following attestation bundles were made for mooncompute-0.3.0.tar.gz:
Publisher:
ci.yml on GarrettMooney/mooncompute
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mooncompute-0.3.0.tar.gz -
Subject digest:
d0b1fa1473fdf365ae29efa6997449e7806556af58b53a86bf947a13038fa799 - Sigstore transparency entry: 1757122247
- Sigstore integration time:
-
Permalink:
GarrettMooney/mooncompute@1a18b3761081dca69fc30a980195b9a591d3f4fe -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/GarrettMooney
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@1a18b3761081dca69fc30a980195b9a591d3f4fe -
Trigger Event:
push
-
Statement type:
File details
Details for the file mooncompute-0.3.0-py3-none-any.whl.
File metadata
- Download URL: mooncompute-0.3.0-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2740040ab043f7b9d52ef96bf9d1682ca4daf3f626bc8cd2e4634d20d35bd9e0
|
|
| MD5 |
603d42e18149ac9ba448256e22a4009b
|
|
| BLAKE2b-256 |
dc83504106ea90b5ebe6fbd93ff38f9d281464c0c6825abd41b23fdb6fd98f87
|
Provenance
The following attestation bundles were made for mooncompute-0.3.0-py3-none-any.whl:
Publisher:
ci.yml on GarrettMooney/mooncompute
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mooncompute-0.3.0-py3-none-any.whl -
Subject digest:
2740040ab043f7b9d52ef96bf9d1682ca4daf3f626bc8cd2e4634d20d35bd9e0 - Sigstore transparency entry: 1757122264
- Sigstore integration time:
-
Permalink:
GarrettMooney/mooncompute@1a18b3761081dca69fc30a980195b9a591d3f4fe -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/GarrettMooney
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@1a18b3761081dca69fc30a980195b9a591d3f4fe -
Trigger Event:
push
-
Statement type: