# CommonGrants Python SDK: Complete Guide to Installation and Usage

> Install and use the CommonGrants Python SDK to interact with CommonGrants APIs. This guide covers installation, Pydantic models, data transformation, and HTTP client usage.

- Repository: [U.S. Department of Health & Human Services/simpler-grants-protocol](https://github.com/hhs/simpler-grants-protocol)
- Tags: getting-started
- Published: 2026-03-03

---

**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**:

```bash

# 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](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/python-sdk/README.md) located at [`lib/python-sdk/README.md`](https://github.com/hhs/simpler-grants-protocol/blob/main/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`](https://github.com/hhs/simpler-grants-protocol/blob/main/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:

```python
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:

```python
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`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/python-sdk/common_grants_sdk/utils/transformation.py).

### Using the HTTP Client

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

```python
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`](https://github.com/hhs/simpler-grants-protocol/blob/main/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:

```python
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`](https://github.com/hhs/simpler-grants-protocol/blob/main/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`](https://github.com/hhs/simpler-grants-protocol/blob/main/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".