CommonGrants Python SDK: Complete Guide to Installation and Usage

Yes, CommonGrants offers a fully-featured, type-safe Python SDK (common-grants-sdk) that provides Pydantic models, data transformation utilities, and a high-level HTTP client for interacting with CommonGrants-compliant APIs.

The CommonGrants Python SDK is maintained in the hhs/simpler-grants-protocol repository under lib/python-sdk. It enables developers to serialize and validate grant opportunity data, transform legacy formats into the CommonGrants protocol, and query compliant APIs with minimal boilerplate.

Installing the CommonGrants Python SDK

You can install the SDK from PyPI using pip or Poetry:


# Using pip

pip install common-grants-sdk

# Or with Poetry

poetry add common-grants-sdk

For detailed configuration options and environment setup, refer to the SDK README located at lib/python-sdk/README.md.

Core Components of the Python SDK

The SDK is organized into three primary modules: Pydantic schemas for data validation, transformation utilities for data mapping, and an HTTP client for API interaction.

Pydantic Schema Models

The SDK provides ready-made Pydantic models located in lib/python-sdk/common_grants_sdk/schemas/pydantic that enforce the CommonGrants protocol specification. Key classes include:

  • OpportunityBase – The core opportunity model with validation
  • OppFunding – Funding details including Money amounts
  • OppStatus – Status enumeration with OppStatusOptions
  • OppTimeline – Key dates and deadlines using Event objects

These models automatically handle serialization, deserialization, and type validation.

Data Transformation Utilities

For integrating legacy systems, the SDK includes transform_from_mapping in lib/python-sdk/common_grants_sdk/utils/transformation.py. This utility maps third-party data structures into SDK-compatible dictionaries using a declarative mapping schema.

The transformation engine supports:

  • Direct field mapping
  • Nested object traversal (dot notation)
  • Value switching and case mapping
  • Default values for missing fields

HTTP Client

The Client class in lib/python-sdk/common_grants_sdk/client/ provides a high-level interface for API operations. It includes:

  • Client – Main entry point for API calls
  • Auth – Authentication handlers including API key support
  • Config – Base URL and timeout configuration

The client handles pagination, error responses, and request serialization automatically.

Practical Code Examples

Building Opportunity Objects with Pydantic

Create and validate opportunity data using the schema models:

from datetime import datetime, date, UTC
from uuid import uuid4

from common_grants_sdk.schemas.pydantic import (
    Event,
    Money,
    OpportunityBase,
    OppFunding,
    OppStatus,
    OppStatusOptions,
    OppTimeline,
)

opportunity = OpportunityBase(
    id=uuid4(),
    title="Research Grant 2024",
    description="Funding for innovative research projects",
    status=OppStatus(
        value=OppStatusOptions.OPEN,
        description="This opportunity is currently accepting applications",
    ),
    created_at=datetime.now(UTC),
    last_modified_at=datetime.now(UTC),
    funding=OppFunding(
        total_amount_available=Money(amount="100000.00", currency="USD"),
        min_award_amount=Money(amount="10000.00", currency="USD"),
        max_award_amount=Money(amount="50000.00", currency="USD"),
        estimated_award_count=5,
    ),
    key_dates=OppTimeline(
        app_opens=Event(name="Application Opens", date=date(2024, 1, 1), description="Applications open"),
        app_deadline=Event(name="Application Deadline", date=date(2024, 3, 31), description="Applications close"),
    ),
)

# Serialize to JSON

json_data = opportunity.dump_json()

# Deserialize back to a model

loaded = OpportunityBase.from_json(json_data)

Transforming Third-Party Data

Map external data formats into CommonGrants models using the transformation utility:

from common_grants_sdk.utils.transformation import transform_from_mapping

source_data = {
    "opportunity_id": 12345,
    "opportunity_title": "Research into ABC",
    "opportunity_status": "posted",
    "summary": {
        "award_ceiling": 100000,
        "award_floor": 10000,
        "forecasted_close_date": "2025-07-15",
        "forecasted_post_date": "2025-05-01",
    },
}

mapping = {
    "id": {"field": "opportunity_id"},
    "title": {"field": "opportunity_title"},
    "status": {
        "switch": {
            "field": "opportunity_status",
            "case": {"posted": "open", "closed": "closed"},
            "default": "custom",
        }
    },
    "funding": {
        "minAwardAmount": {"amount": {"field": "summary.award_floor"}, "currency": "USD"},
        "maxAwardAmount": {"amount": {"field": "summary.award_ceiling"}, "currency": "USD"},
    },
    "keyDates": {
        "appOpens": {"field": "summary.forecasted_post_date"},
        "appDeadline": {"field": "summary.forecasted_close_date"},
    },
}

transformed = transform_from_mapping(source_data, mapping)
print(transformed)

The transform_from_mapping function is implemented in lib/python-sdk/common_grants_sdk/utils/transformation.py.

Using the HTTP Client

Query CommonGrants-compliant APIs with automatic pagination and error handling:

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

# Configuration can come from environment vars or be explicit

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

# Get a single opportunity

opp = client.opportunity.get("123e4567-e89b-12d3-a456-426614174000")
print(opp.title, opp.description)

# List opportunities (first page)

response = client.opportunity.list(page=1)
print(f"Found {len(response.items)} opportunities on page {response.pagination_info.page}")
for opp in response.items:
    print(opp.id, opp.title)

For advanced configuration options, see the client documentation at lib/python-sdk/common_grants_sdk/client/README.md.

Extending Schemas with Custom Fields

Add organization-specific fields to the base models while maintaining validation:

from uuid import uuid4
from datetime import datetime
from common_grants_sdk.schemas.pydantic import OpportunityBase, CustomFieldType, OppStatus, OppStatusOptions
from common_grants_sdk.extensions.specs import CustomFieldSpec

# Define custom fields you need

custom_fields = {
    "legacyId": CustomFieldSpec(field_type=CustomFieldType.INTEGER, value=int),
    "groupName": CustomFieldSpec(field_type=CustomFieldType.STRING, value=str),
}

# Create a new model class that includes these fields

Opportunity = OpportunityBase.with_custom_fields(custom_fields=custom_fields, model_name="Opportunity")

opp_data = {
    "id": uuid4(),
    "title": "Foo bar",
    "status": OppStatus(value=OppStatusOptions.OPEN),
    "description": "Example opportunity",
    "createdAt": datetime.now(),
    "lastModifiedAt": datetime.now(),
    "customFields": {
        "legacyId": {"name": "legacyId", "fieldType": "integer", "value": 12345},
        "groupName": {"name": "groupName", "fieldType": "string", "value": "TEST_GROUP"},
    },
}

opp = Opportunity.model_validate(opp_data)
print(opp.custom_fields.legacy_id.value)   # → 12345

Custom field support is documented in the SDK README under the "Custom Fields Extensions" section.

Summary

  • CommonGrants Python SDK is available as common-grants-sdk on PyPI and is maintained in lib/python-sdk within the hhs/simpler-grants-protocol repository.
  • Pydantic models in common_grants_sdk/schemas/pydantic provide type-safe validation for opportunities, funding, timelines, and status enumerations.
  • Data transformation utilities via transform_from_mapping in utils/transformation.py enable mapping of legacy or third-party data formats into CommonGrants-compliant structures.
  • HTTP client in common_grants_sdk/client supports API authentication, pagination, and error handling for interacting with CommonGrants-compliant endpoints.
  • Custom field extensions allow organizations to extend base models with additional metadata while maintaining full validation and serialization capabilities.

Frequently Asked Questions

How do I install the CommonGrants Python SDK?

Install the SDK using pip with pip install common-grants-sdk or add it to your Poetry project with poetry add common-grants-sdk. The package is distributed via PyPI and requires Python 3.9 or higher. After installation, import the modules from common_grants_sdk to begin working with Pydantic models and the HTTP client.

What Pydantic models are included in the SDK?

The SDK includes comprehensive Pydantic models located in lib/python-sdk/common_grants_sdk/schemas/pydantic. Key models include OpportunityBase for core opportunity data, OppFunding and Money for financial details, OppStatus with OppStatusOptions for state management, and OppTimeline with Event objects for key dates. These models provide automatic JSON serialization, validation, and type checking.

Can I map existing data formats to CommonGrants schemas?

Yes, the SDK provides the transform_from_mapping utility in lib/python-sdk/common_grants_sdk/utils/transformation.py to map third-party or legacy data structures into CommonGrants-compatible dictionaries. This function accepts a source dictionary and a mapping configuration that supports field aliasing, nested path traversal, value switching with case statements, and default values, enabling seamless integration with existing grant databases.

Does the SDK support custom fields for organization-specific data?

Yes, the SDK supports custom field extensions through the OpportunityBase.with_custom_fields class method. By defining CustomFieldSpec objects with types from CustomFieldType (such as INTEGER, STRING, or DATE), organizations can generate specialized model classes that validate organization-specific metadata while maintaining full compatibility with the base CommonGrants protocol. This feature is documented in the SDK README under "Custom Fields Extensions".

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →