Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Do not guess or iterate blindly. Download the artifact first.
## Files You Can Safely Edit

- `overlays/python_speakeasy.yaml` — Speakeasy overlay
- `scripts/post_generate.py` — Post-generation patch script
- `scripts/post_generate.uv` — Post-generation patch script (standalone uv script)
- `poe_tasks.toml` — Build task definitions
- `.github/workflows/` — CI workflows
- `.github/dependabot.yml` — Dependabot configuration
Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The Python SDK is generated through a multi-step pipeline:
┌──────────────────────────────────────────┐
│ 4. Post-Generation Patches │
│ (scripts/post_generate.py) │
│ (scripts/post_generate.uv) │
└──────────────────┬───────────────────────┘
Expand All @@ -49,15 +49,15 @@ The Python SDK is generated through a multi-step pipeline:

3. **Speakeasy Code Generation** — Speakeasy consumes the spec (+ overlay if enabled) and generates the Python SDK in `src/airbyte_api/`. These files should never be edited by hand.

4. **Post-Generation Patches** — A Python script applies any SDK-specific patches after generation (currently a no-op placeholder):
[`scripts/post_generate.py`](https://github.com/airbytehq/airbyte-api-python-sdk/blob/main/scripts/post_generate.py)
4. **Post-Generation Patches** — A standalone uv script applies SDK-specific patches after generation (e.g. replacing the hardcoded `__version__` with `importlib.metadata`):
[`scripts/post_generate.uv`](https://github.com/airbytehq/airbyte-api-python-sdk/blob/main/scripts/post_generate.uv)

5. **Package Build & Publish** — The generated SDK is built with `uv build` and published to PyPI via OIDC trusted publishing.

> **Tip:** If you need to change SDK behavior, determine which layer is appropriate:
> - **API changes** → submit to the [upstream OpenAPI spec](https://github.com/airbytehq/airbyte-platform/blob/main/airbyte-api/server-api/src/main/openapi/api_sdk.yaml)
> - **Python SDK-specific schema tweaks** → modify the [overlay](https://github.com/airbytehq/airbyte-api-python-sdk/blob/main/overlays/python_speakeasy.yaml)
> - **Post-generation fixes** → modify the [post-generate script](https://github.com/airbytehq/airbyte-api-python-sdk/blob/main/scripts/post_generate.py)
> - **Post-generation fixes** → modify the [post-generate script](https://github.com/airbytehq/airbyte-api-python-sdk/blob/main/scripts/post_generate.uv)
> - Then trigger regeneration (see below)

## For Maintainers
Expand Down
2 changes: 1 addition & 1 deletion poe_tasks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ speakeasy run $ARGS
[tasks._post-generate]
help = "Run post-generation patches."
shell = """
uv run python scripts/post_generate.py
uv run scripts/post_generate.uv
"""

[tasks._generate-readme]
Expand Down
16 changes: 0 additions & 16 deletions scripts/post_generate.py

This file was deleted.

70 changes: 70 additions & 0 deletions scripts/post_generate.uv
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env -S uv run --python 3.10 --script
# /// script
# requires-python = ">=3.10,<3.14"
# dependencies = []
# ///
"""Post-generation patch pipeline.

Runs after Speakeasy code generation to apply durable fixes to generated code.
See the terraform-provider-airbyte repo for more examples of post-generation patches.
"""

import re
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parent.parent
VERSION_FILE = REPO_ROOT / "src" / "airbyte_api" / "_version.py"


def patch_version_file() -> None:
"""Replace the hardcoded `__version__` in `_version.py` with a dynamic lookup.

Speakeasy generates a `_version.py` with a hardcoded `__version__` string
and a static `__user_agent__`. This patch rewrites both so that the
installed package version (set at build time by `uv-dynamic-versioning`
from the git tag) is used instead. Generation metadata
(`__openapi_doc_version__`, `__gen_version__`) is left intact.
"""
text = VERSION_FILE.read_text()
original = text

# 1. Replace the hardcoded __version__ assignment with importlib.metadata lookup.
# Matches: __version__: str = "1.0.0" (any semver-ish string)
text = re.sub(
r'^__version__: str = ".*"$',
"__version__: str = importlib.metadata.version(__title__)",
text,
count=1,
flags=re.MULTILINE,
)

# 2. Replace the static __user_agent__ string with an f-string using the
# dynamic __version__.
# Matches: __user_agent__: str = "speakeasy-sdk/python 1.0.0 2.911.0 1.0.0 airbyte-api"
text = re.sub(
r'^__user_agent__: str = "speakeasy-sdk/python .+"$',
(
"__user_agent__: str = (\n"
' f"speakeasy-sdk/python {__version__} {__gen_version__}"\n'
' f" {__openapi_doc_version__} {__title__}"\n'
")"
),
text,
count=1,
flags=re.MULTILINE,
)

if text == original:
print("post_generate: _version.py already patched (no changes)")
return

VERSION_FILE.write_text(text)
print("post_generate: patched _version.py (hardcoded __version__ → importlib.metadata)")


def main() -> None:
patch_version_file()


if __name__ == "__main__":
main()
7 changes: 5 additions & 2 deletions src/airbyte_api/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import importlib.metadata

__title__: str = "airbyte-api"
__version__: str = "1.0.0"
__version__: str = importlib.metadata.version(__title__)
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.911.0"
__user_agent__: str = "speakeasy-sdk/python 1.0.0 2.911.0 1.0.0 airbyte-api"
__user_agent__: str = (
f"speakeasy-sdk/python {__version__} {__gen_version__}"
f" {__openapi_doc_version__} {__title__}"
)

try:
if __package__ is not None:
Expand Down
Loading