Skip to main content

cloudfit-provider-gcp

PyPI version Tests License: Apache 2.0

GCP Compute Engine provider plugin for cloudfit-core.

Fetches machine types, availability, and on-demand, spot, and 1-year committed-use pricing from the GCP Compute Engine and Cloud Billing Catalog APIs, and normalizes them into MachineType objects that cloudfit-core understands, including each family's perf_factor and each GPU's gpu_type.


Installation

pip install cloudfit-provider-gcp

Requires Python 3.10 or newer (CI tests 3.10 through 3.14) and cloudfit-core>=0.8.2.


Authentication

Uses Application Default Credentials. Set up once with:

gcloud auth application-default login

Or set the GOOGLE_APPLICATION_CREDENTIALS environment variable to a service account key path. In production (Cloud Run, GKE), credentials are picked up automatically from the instance metadata server: no configuration needed.


Quick start

from cloudfit_provider_gcp import GCPProvider
from cloudfit import rank, WorkloadProfile

# initialize: no credentials needed if ADC is configured
provider = GCPProvider(project_id="your-gcp-project")

# fetch all machine types for a region
instances = provider.fetch_instances(region="us-central1")
print(f"fetched {len(instances)} machine types")

# plug directly into cloudfit-core
profile = WorkloadProfile(
    vcpu=60,
    ram_gb=224,
    workload="io-intensive",
    archetype="io",
    optimize_for="balanced",
)

results = rank(profile, instances)
for r in results[:3]:
    print(f"{r.instance.id:35s}  score={r.score:.2f}  ${r.instance.price_hr:.2f}/hr")

Fetching multiple regions

from cloudfit_provider_gcp import GCPProvider

provider = GCPProvider(project_id="your-gcp-project")

regions = ["us-central1", "us-east1", "europe-west1", "asia-east1"]
all_instances = []
for region in regions:
    all_instances.extend(provider.fetch_instances(region=region))

print(f"total: {len(all_instances)} machine types across {len(regions)} regions")

Examples

Runnable scripts are in examples/:

Script Needs GCP credentials? What it shows
recommend.py yes (ADC) live GCPProvider.fetch_instances() → cloudfit.rank()
recommend_offline.py no recorded fixture → normalize_machine_type() → cloudfit.rank()

Try the offline one first: it runs anywhere, no GCP account required:

python examples/recommend_offline.py
Ranking for 32 vCPU / 120 GB (optimize_for=balanced):

  ok  n2-standard-32            score=1.00  $  1.53/hr  [active]
  ok  c3d-standard-60-lssd      score=0.62  $  2.87/hr  [active]
  ok  c2-standard-60            score=0.59  $  2.82/hr  [active]
  --  a2-highgpu-1g             $  0.73/hr  [active]  ✗ RAM 85 GB < required 120 GB
  --  n1-standard-8             $  0.37/hr  [deprecated]  ✗ RAM 30 GB < required 120 GB
  --  f1-micro                  $  0.03/hr  [tombstoned]  ✗ RAM 1 GB < required 120 GB

Pricing

Pricing is fetched from the GCP Cloud Billing Catalog API, using each SKU's structured category (usage type, resource group, service regions) rather than parsing descriptions. fetch_instances fills three prices per machine type, each reconstructed from the family's per-vCPU and per-GB rates for the region:

Field Source SKUs
price_hr on-demand
spot_price_hr spot (preemptible)
cud_1yr_price_hr 1-year committed use

cloudfit-core scores whichever one the workload's pricing_mode selects. If a family's SKUs can't be matched, that price is left unset: price_hr falls back to 0.0 (the instance is still scored, with cost_score 0), and a missing spot or committed-use price falls back to on-demand at scoring time.

Limitation: the reconstruction covers CPU and RAM only. Accelerator cost is not added, so GPU machine types are under-priced by it; supply a known price_hr for GPU instances (the bundled snapshots do).

price_hr = provider.get_pricing("n2-standard-32", region="us-central1")  # on-demand
# → about 1.55

Scheduled refresh

Bundled snapshots (weekly, automated)

cloudfit-api and cloudfit-ui ship a curated 875-instance GCP snapshot (alongside the AWS one from cloudfit-provider-aws). The refresh-snapshot workflow in this repo runs every Monday at 06:00 UTC: it refreshes on-demand, spot, and committed-use prices in both snapshots in place with examples/refresh_prices.py (row set, regions, and statuses are preserved; GPU prices are left as is) and opens a pull request in each repo. The run fails instead of opening a PR if any region's prices can't be fetched. It authenticates to GCP with Workload Identity Federation (no stored keys) and needs the SNAPSHOT_TOKEN, GCP_WORKLOAD_IDENTITY_PROVIDER, and GCP_SERVICE_ACCOUNT secrets; see the comments in the workflow file.

To refresh locally (needs gcloud auth application-default login):

make refresh-snapshot      # refreshes ../cloudfit-api and ../cloudfit-ui snapshots in place

To build a brand-new snapshot from a live fetch instead, use examples/generate_snapshot.py.

Registry (PostgreSQL)

For a live registry, run the fetcher on a schedule and write results to the cloudfit registry store (PostgreSQL). The recommended pattern is a Cloud Scheduler trigger invoking a Cloud Run Job.

from cloudfit_provider_gcp import GCPProvider
from cloudfit_provider_gcp.registry import write_to_registry

provider = GCPProvider(project_id="your-gcp-project")
instances = provider.fetch_instances_all_regions()
write_to_registry(instances, database_url=os.environ["DATABASE_URL"])

Deprecation handling

When GCP marks a machine type as deprecated, the provider sets status="deprecated" on the MachineType. When a type is fully removed, it becomes status="tombstoned": it is never deleted from the registry, so existing configs can warn instead of silently breaking.


Repository structure

cloudfit-provider-gcp/
├── README.md
├── CHANGELOG.md             # release notes; GitHub Releases are built from it
├── CONTRIBUTING.md
├── CITATION.cff
├── pyproject.toml
├── Makefile                 # version bump, tag, test, lint, build
├── LICENSE
├── .gitignore
├── .github/
│   ├── dependabot.yml       # monthly GitHub Actions updates
│   └── workflows/
│       ├── ci.yml           # lint, mypy --strict, tests; PyPI publish and release on tags
│       └── refresh-snapshot.yml   # weekly price refresh PRs to cloudfit-api and cloudfit-ui
│
├── cloudfit_provider_gcp/
│   ├── __init__.py          # exports GCPProvider
│   ├── provider.py          # GCPProvider: implements Provider base class
│   ├── normalizer.py        # raw GCP API response → MachineType
│   ├── pricing.py           # Cloud Billing Catalog API → on-demand, spot, CUD prices
│   ├── regions.py           # GCP region list + helpers
│   └── registry.py          # write normalized instances to PostgreSQL
│
├── examples/
│   ├── recommend.py           # live fetch → rank (needs GCP credentials)
│   ├── recommend_offline.py   # fixture → rank (no credentials needed)
│   ├── generate_snapshot.py   # build a fresh snapshot from a live fetch
│   └── refresh_prices.py      # refresh prices in existing snapshots in place
│
└── tests/
    ├── test_normalizer.py   # unit tests: no API calls needed
    ├── test_pricing.py      # SKU parsing and price reconstruction
    ├── test_regions.py
    ├── test_registry.py
    └── fixtures/
        └── machine_type_response.json   # recorded GCP API response

License

Apache 2.0: see LICENSE.


Author: Chaitanya Krishna Kasaraneni  ·  Google Scholar  ·  ORCID 0000-0001-5792-1095

Metadata

Release files for cloudfit-provider-gcp 0.3.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cloudfit-provider-gcp 0.3.4
File Size Uploaded Provenance
cloudfit_provider_gcp-0.3.4.tar.gz 34.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for cloudfit-provider-gcp 0.3.4
File Interpreter ABI Platform
cloudfit_provider_gcp-0.3.4-py3-none-any.whl Python 3 none any Details

Total release size: 55.0 kB

Release files / cloudfit_provider_gcp-0.3.4.tar.gz

Download URL cloudfit_provider_gcp-0.3.4.tar.gz
Size 34.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e13eb35a59fce2387f6118bc218f6ea34ff1bc54ffb07e112141302297f8e07c
BLAKE2b-256 checksum
How to use checksums
d8233d6b48211728273ee9315fa06a1b8b7121bdeff2f3b818df111f8efaa024
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / cloudfit_provider_gcp-0.3.4-py3-none-any.whl

Download URL cloudfit_provider_gcp-0.3.4-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9b86db5bab10264347ec7632f621069f2563234e4a0e7536da86b3d78801a349
BLAKE2b-256 checksum
How to use checksums
c3d393b23c258a638fe58279357109e5fbc120a568abcd3b9e959deaca1faca6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for cloudfit-provider-gcp 0.3.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cloudfit_provider_gcp-0.3.4.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page