Skip to content

[Py SDK] Plugin packaging and publishing support #504

@widal001

Description

@widal001

Summary

Define the conventions and tooling for publishing a CommonGrants plugin as an installable Python package. This includes documenting the expected package structure, ensuring the generator runs at build time so that pre-generated schemas ship with the package, and validating that the exported Plugin provides fully typed .extensions and .schemas when imported by consumers.

Example

# After installing: pip install commongrants-hhs-plugin
# Consumer usage types resolve from the installed package

from commongrants_hhs import config as hhs

hhs.extensions.Opportunity["program_area"]      # CustomFieldSpec
opp = hhs.schemas.Opportunity.model_validate(data) # fully typed
# pyproject.toml for a published plugin
[tool.poetry]
name = "commongrants-hhs-plugin"
version = "1.0.0"
description = "HHS custom fields plugin for CommonGrants SDK"
packages = [{include = "commongrants_hhs"}]

[tool.poetry.dependencies]
python = "^3.10"
common-grants-sdk = "^0.6.0"

[tool.poetry.group.dev.dependencies]
pyright = "^1.1"
pytest = "^8.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
# Published package structure
commongrants_hhs/
├── __init__.py            # exports PluginConfig with .extensions and .schemas
├── cg_config.py           # defines SchemaExtensions
├── fields.py              # value models (e.g. LegacyIdValue)
└── generated/             # pre-generated by maintainer, shipped in package
    ├── __init__.py
    └── schemas.py          # typed Pydantic models

Acceptance criteria

  • Documentation describes the expected plugin package structure: cg_config.py defining extensions, generated/ directory with pre-built models, and __init__.py exporting a Plugin
  • The generator can be invoked as a build step (e.g. in a poetry or setuptools build hook) so that generated/ is produced before the package is built and published and pre-generated schemas ship with the installed package
  • A published plugin's Plugin instance provides fully typed .schemas attributes when imported by a consumer. Pyright resolves custom field types without the consumer running any generation step
  • (Stretch) A template or common_grants_sdk.create_plugin scaffolding command is available that generates the minimal plugin directory structure with cg.config.py, __init__.py, and pyproject.toml
  • End-to-end test:
    • build a plugin package locally
    • install it in a separate virtual environment
    • import the plugin
    • verify that .extensions and .schemas are available and typed
    • create with a local extension using merge_extensions()

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No fields configured for Task.

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions