Skip to main content

CommonGrants Python SDK

A Python SDK for interacting with the CommonGrants protocol, providing a type-safe interface for managing grant opportunities.

Table of contents

Installation

# Using pip
pip install common-grants-sdk

# Using Poetry
poetry add common-grants-sdk

Usage

Quick start

from common_grants_sdk.client import Client, Auth
from common_grants_sdk.client.config import Config

# 1. Create a client
config = Config(base_url="https://api.example.org", api_key="YOUR_API_KEY")
client = Client(config=config, auth=Auth.api_key("YOUR_API_KEY"))

# 2. List opportunities
response = client.opportunities.list()
for opp in response.items:
    print(f"{opp.title} ({opp.status.value})")

Kitchen sink example

This example shows how the SDK's modules work together: declaring a plugin with typed custom fields and a custom filter, getting a pre-bound client from it, searching with both standard and custom filters, and validating standalone data with schemas.

from typing import Optional

from pydantic import Field

from common_grants_sdk.client import Config
from common_grants_sdk.extensions import (
    CustomField,
    CustomFieldSet,
    PluginMeta,
    PluginRoutes,
    PluginSchemas,
    ResourceRoutes,
    define_plugin,
    f,
    schema,
)
from common_grants_sdk.schemas.pydantic.filters.opportunity import (
    OpportunityFilters,
    StringArray,
)
from common_grants_sdk.schemas.pydantic.models import OpportunityBase


# Custom fields attach to schemas. The value type on CustomField[V] flows through
# to opp.custom_fields.<field>.value on every parsed response row.
class OppFields(CustomFieldSet):
    program_area: Optional[CustomField[str]] = Field(
        default=None, description="Grant program area"
    )
    legacy_id: Optional[CustomField[int]] = Field(
        default=None, description="Legacy system ID"
    )


# Custom filters attach to routes. This one subclass both registers the filter
# and types the consumer's search(filters=...) call site.
class OppSearchFilters(OpportunityFilters, total=False):
    agency: StringArray


plugin = define_plugin(
    PluginSchemas(Opportunity=schema(common_schema=OpportunityBase[OppFields])),
    routes=PluginRoutes(opportunities=ResourceRoutes(search=OppSearchFilters)),
    meta=PluginMeta(name="my-system", source_system="my-system.example.gov"),
)

# A plugin-bound client parses responses with the plugin's schemas and types
# search(filters=...) by the filters it registered — no per-call schema argument.
client = plugin.get_client(
    Config(base_url="https://api.example.org", api_key="YOUR_API_KEY")
)

result = client.opportunities.search(
    search="education",
    filters={
        "status": f.in_(["open"]),  # standard filter → top-level request field
        "agency": f.in_(["HHS"]),   # registered custom filter → customFilters
    },
)

for opp in result.items:
    print(f"{opp.title} ({opp.status.value})")

    # Custom fields are fully typed
    fields = opp.custom_fields
    if fields is not None and fields.program_area is not None:
        print(f"  Program area: {fields.program_area.value}")  # typed as str

# Rows that failed to parse are partitioned out rather than raising
for err in result.errors:
    print(f"  parse error at row {err.index}: {err.message}")

# Validate standalone data directly against the schema
raw = {
    "id": "ac201443-5480-4e36-9799-a39765225153",
    "title": "Community Health Grant",
    "description": "A grant supporting community health initiatives.",
    "status": {"value": "open"},
    "createdAt": "2025-01-01T00:00:00Z",
    "lastModifiedAt": "2025-01-01T00:00:00Z",
}
validated_opp = OpportunityBase.model_validate(raw)
print(validated_opp.title)

Modules

The SDK is organized into modules, each with its own documentation:

Module Description
Client HTTP client with auth, pagination, and low-level HTTP methods
Schemas Pydantic models, validation, and generic response schemas
Extensions Custom fields and plugin framework

API Client

HTTP client with built-in authentication, auto-pagination, and environment variable configuration. See the Client guide for setup, authentication, and usage examples.

Schemas and Validation

Pydantic v2 models for validating and parsing CommonGrants data, along with type-safe enum constants. See the Schemas guide for validation examples, type safety patterns, and the full API reference.

Extensions and Plugins

Extension framework for adding typed custom fields to CommonGrants schemas, either ad hoc or as reusable plugins. See the Extensions guide for the full guide.

License

See LICENSE

Metadata

Release files for common-grants-sdk 0.9.0

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

Source distribution (sdist)

Source distribution for common-grants-sdk 0.9.0
File Size Uploaded Provenance
common_grants_sdk-0.9.0.tar.gz 87.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for common-grants-sdk 0.9.0
File Interpreter ABI Platform
common_grants_sdk-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 206.8 kB

Release files / common_grants_sdk-0.9.0.tar.gz

Download URL common_grants_sdk-0.9.0.tar.gz
Size 87.3 kB
Tags Source
SHA-256 checksum
How to use checksums
9aa43e80f5eb3c57a24af6890ecbbd230cb70d9f63fd80b53a09fcdb0f401d54
BLAKE2b-256 checksum
How to use checksums
1f763344db7b58c33df685f7d85e70fe4e2db2a575d54d8dc1c92f9b67866ff0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.5.1 CPython/3.11.17 Linux/6.17.0-1022-azure

Release files / common_grants_sdk-0.9.0-py3-none-any.whl

Download URL common_grants_sdk-0.9.0-py3-none-any.whl
Size 119.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0e8270d52a6476989680c1791c6834fc13d7111752d53751d8c20af0aed49366
BLAKE2b-256 checksum
How to use checksums
71f4f350e9d27711d0e7ecec0b9a2ae1fc5ce1348a5dadfb549ec44440543447
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.5.1 CPython/3.11.17 Linux/6.17.0-1022-azure

Security for common-grants-sdk 0.9.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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