Skip to content

feat: scaffold publishable sdk foundation - #7

Merged
usmanabbas7 merged 1 commit into
dev-branchfrom
feat-story-1.1-scaffold-the-publishable-sdk-foundation
Apr 7, 2026
Merged

feat: scaffold publishable sdk foundation#7
usmanabbas7 merged 1 commit into
dev-branchfrom
feat-story-1.1-scaffold-the-publishable-sdk-foundation

Conversation

@usmanabbas7

Copy link
Copy Markdown
Collaborator

Summary

Implements Story 1.1, "Scaffold the Publishable SDK Foundation," from the Python SDK planning set in epics.md and the execution artifact in 1-1-scaffold-the-publishable-sdk-foundation.md.

This PR creates the initial publishable package scaffold for the Python SDK and freezes the package boundary decisions for later stories:

  • distribution name: convert-python-sdk
  • import package: convert_sdk
  • stable public root exports: Core, Context, and __version__

What Changed

  • Initialized the SDK as a uv library project with hatchling
  • Set package metadata to support Python >=3.9
  • Replaced the default scaffold package with src/convert_sdk/
  • Added stable placeholder public modules for Core, Context, and version metadata
  • Added py.typed so the package is typed for consumers
  • Added project-local test tooling and packaging/import tests
  • Updated the README with the canonical install/import contract
  • Generated and committed uv.lock

Why

The planning artifacts explicitly call for Story 1.1 to freeze the canonical package name, import path, and public entry point before implementation accelerates. This PR establishes that baseline so later stories can add initialization, config loading, evaluation, and tracking behavior without renaming the package surface.

Validation

  • uv sync --group dev
  • uv run pytest -p no:cacheprovider
  • uv build

Validation results:

  • test suite passed
  • wheel and sdist were built successfully
  • built artifacts include convert_sdk/* and py.typed
  • no framework or JavaScript runtime dependency was introduced

Notes

This PR is intentionally scaffold-only. It does not implement SDK initialization, config loading, evaluation, tracking, or persistence yet. Those remain in follow-up stories from the same planning set.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request establishes the initial scaffold for the Convert Python SDK, including project metadata, build configuration via Hatchling, and a stable public API boundary. The feedback focuses on improving the project's maintainability and portability: specifically, adopting dynamic versioning to avoid duplication, removing redundant build configurations in pyproject.toml, ensuring tests do not hardcode version strings, and making local development instructions in the README more portable by removing environment-specific cache overrides.

Comment thread pyproject.toml
@@ -0,0 +1,36 @@
[project]
name = "convert-python-sdk"
version = "0.1.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The package version is currently hardcoded in both pyproject.toml and src/convert_sdk/version.py. To avoid duplication and potential inconsistencies, it is recommended to use Hatch's dynamic versioning, treating the source code as the single source of truth.

Suggested change
version = "0.1.0"
dynamic = ["version"]

Comment thread pyproject.toml
Comment on lines +35 to +36
[tool.pytest.ini_options]
testpaths = ["tests"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When using dynamic versioning, you need to specify the source of the version metadata for Hatch. This ensures that the version defined in src/convert_sdk/version.py is used as the package version.

Suggested change
[tool.pytest.ini_options]
testpaths = ["tests"]
[tool.pytest.ini_options]
testpaths = ["tests"]
[tool.hatch.version]
path = "src/convert_sdk/version.py"

Comment thread tests/test_public_api.py
Comment on lines +1 to +9
from importlib import resources

from convert_sdk import Context, Core, __version__


def test_public_import_boundary_is_stable() -> None:
assert Core.__module__ == "convert_sdk.core"
assert Context.__module__ == "convert_sdk.context"
assert __version__ == "0.1.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Avoid hardcoding the version string in tests. It is more robust to compare the exported __version__ against the package metadata to ensure they are in sync.

Suggested change
from importlib import resources
from convert_sdk import Context, Core, __version__
def test_public_import_boundary_is_stable() -> None:
assert Core.__module__ == "convert_sdk.core"
assert Context.__module__ == "convert_sdk.context"
assert __version__ == "0.1.0"
from importlib import metadata, resources
from convert_sdk import Context, Core, __version__
def test_public_import_boundary_is_stable() -> None:
assert Core.__module__ == "convert_sdk.core"
assert Context.__module__ == "convert_sdk.context"
assert __version__ == metadata.version("convert-python-sdk")

Comment thread README.md
Comment on lines +16 to +18
UV_CACHE_DIR=/tmp/uv-cache uv sync --group dev
UV_CACHE_DIR=/tmp/uv-cache uv run pytest
UV_CACHE_DIR=/tmp/uv-cache uv build

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hardcoding UV_CACHE_DIR=/tmp/uv-cache is not portable across different operating systems (e.g., Windows) and may fail if the directory is not writable. uv automatically manages its cache in a platform-appropriate location, so this override is generally unnecessary for local development instructions.

Suggested change
UV_CACHE_DIR=/tmp/uv-cache uv sync --group dev
UV_CACHE_DIR=/tmp/uv-cache uv run pytest
UV_CACHE_DIR=/tmp/uv-cache uv build
uv sync --group dev
uv run pytest
uv build

Comment thread pyproject.toml
Comment on lines +24 to +25
[tool.hatch.build.targets.wheel.force-include]
"src/convert_sdk/py.typed" = "convert_sdk/py.typed"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This force-include configuration is redundant. Since src/convert_sdk is already defined in the packages list for the wheel target, all non-ignored files within that directory (including py.typed) are included by default by Hatchling. Removing this simplifies the configuration.

@usmanabbas7
usmanabbas7 merged commit c19fbb7 into dev-branch Apr 7, 2026
@abbaseya
abbaseya deleted the feat-story-1.1-scaffold-the-publishable-sdk-foundation branch June 18, 2026 16:37
abbaseya added a commit that referenced this pull request Aug 8, 2026
All eight open Dependabot alerts on this repo sit in `yarn.lock` — the
dev-only semantic-release tooling. None of them reach the published
wheel/sdist (httpx is still the only runtime dependency).

Three of the four highs were already reachable inside the existing semver
ranges; the fourth (sigstore GHSA-52v5-jr5w-gjxr, `certificateOIDs`
verification constraints silently dropped) needed sigstore >= 4.1.1, which
only arrives through a major bump:

  semantic-release 24.2.9 -> 25.0.9
    @semantic-release/npm 12.0.2 -> 13.1.5
      npm 10.9.8 -> 11.19.0
        libnpmpublish 10 -> 11.2.0  }-> sigstore ^3 -> ^4  (4.1.1)
        pacote        19 -> 21.5.1  }   @sigstore/core 2.0.0 -> 3.2.1
        tar 7.5.16 -> 7.5.22

`@semantic-release/github` moves to ^12 to match what semantic-release 25
depends on — leaving it at ^11 would hoist the older copy to the project
root and shadow the one core resolves.

Resolved (4 high, 4 medium — no criticals were open):

  #14 high    ip-address       10.2.0 -> 10.4.0   (needs >= 10.3.1)
  #9  high    brace-expansion  2.1.1  -> 5.0.9    (needs >= 2.1.2)
  #7  high    js-yaml          4.2.0  -> 4.3.1    (needs >= 4.3.0)
  #2  high    sigstore         3.1.0  -> 4.1.1    (needs >= 4.1.1)
  #13 medium  ip-address       (same bump as #14)
  #12 medium  ip-address       (same bump as #14)
  #4  medium  tar              7.5.16 -> 7.5.22   (needs >= 7.5.18)
  #1  medium  @sigstore/core   2.0.0  -> 3.2.1    (needs >= 3.2.1)

Node: semantic-release 25 requires ^22.14.0 || >= 24.10.0. release.yml
installs `lts/*`, currently Node 24.19.0 — satisfied, and every future LTS
line stays above the floor.

Verified: `yarn install --immutable` (what release.yml runs) passes against
the regenerated lockfile with the lockfile format unchanged (__metadata
version 10), and `yarn npm audit --all --recursive` reports no suggestions.
A `semantic-release --dry-run` against this branch loads all four configured
plugins, passes verifyConditions for both exec and github (GitHub
authentication + push permission), and analyzes commits to "no release" —
correct, since `chore` is a non-releasing type in release.config.mjs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant