onepin 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. onepin-0.2.0/.commitlintrc.json +1 -0
  2. onepin-0.2.0/.github/workflows/ci.yml +60 -0
  3. onepin-0.2.0/.github/workflows/commitlint.yml +10 -0
  4. onepin-0.2.0/.github/workflows/publish.yml +109 -0
  5. onepin-0.2.0/.github/workflows/release-please-validate.yml +13 -0
  6. onepin-0.2.0/.github/workflows/release-please.yml +12 -0
  7. onepin-0.2.0/.gitignore +53 -0
  8. onepin-0.2.0/.python-version +1 -0
  9. onepin-0.2.0/.release-please-manifest.json +1 -0
  10. onepin-0.2.0/CHANGELOG.md +27 -0
  11. onepin-0.2.0/LICENSE +21 -0
  12. onepin-0.2.0/Makefile +19 -0
  13. onepin-0.2.0/PKG-INFO +98 -0
  14. onepin-0.2.0/README.md +69 -0
  15. onepin-0.2.0/RUNBOOK.md +54 -0
  16. onepin-0.2.0/pyproject.toml +81 -0
  17. onepin-0.2.0/release-please-config.json +12 -0
  18. onepin-0.2.0/scripts/post_fern.sh +7 -0
  19. onepin-0.2.0/src/onepin/.fern/metadata.json +14 -0
  20. onepin-0.2.0/src/onepin/CONTRIBUTING.md +125 -0
  21. onepin-0.2.0/src/onepin/__init__.py +48 -0
  22. onepin-0.2.0/src/onepin/_cli/__init__.py +13 -0
  23. onepin-0.2.0/src/onepin/_cli/_ctx.py +28 -0
  24. onepin-0.2.0/src/onepin/_cli/_http.py +126 -0
  25. onepin-0.2.0/src/onepin/_cli/_state.py +7 -0
  26. onepin-0.2.0/src/onepin/_cli/auth/__init__.py +3 -0
  27. onepin-0.2.0/src/onepin/_cli/auth/credentials.py +114 -0
  28. onepin-0.2.0/src/onepin/_cli/auth/resolver.py +76 -0
  29. onepin-0.2.0/src/onepin/_cli/commands/__init__.py +3 -0
  30. onepin-0.2.0/src/onepin/_cli/commands/_registry.py +17 -0
  31. onepin-0.2.0/src/onepin/_cli/commands/auth.py +149 -0
  32. onepin-0.2.0/src/onepin/_cli/commands/templates.py +44 -0
  33. onepin-0.2.0/src/onepin/_cli/commands/uploads.py +52 -0
  34. onepin-0.2.0/src/onepin/_cli/commands/voices.py +21 -0
  35. onepin-0.2.0/src/onepin/_cli/commands/workflows.py +54 -0
  36. onepin-0.2.0/src/onepin/_cli/main.py +80 -0
  37. onepin-0.2.0/src/onepin/_cli/py.typed +0 -0
  38. onepin-0.2.0/src/onepin/_cli/render.py +77 -0
  39. onepin-0.2.0/src/onepin/_default_clients.py +30 -0
  40. onepin-0.2.0/src/onepin/client.py +162 -0
  41. onepin-0.2.0/src/onepin/core/__init__.py +127 -0
  42. onepin-0.2.0/src/onepin/core/api_error.py +23 -0
  43. onepin-0.2.0/src/onepin/core/client_wrapper.py +104 -0
  44. onepin-0.2.0/src/onepin/core/datetime_utils.py +70 -0
  45. onepin-0.2.0/src/onepin/core/file.py +67 -0
  46. onepin-0.2.0/src/onepin/core/force_multipart.py +18 -0
  47. onepin-0.2.0/src/onepin/core/http_client.py +839 -0
  48. onepin-0.2.0/src/onepin/core/http_response.py +59 -0
  49. onepin-0.2.0/src/onepin/core/http_sse/__init__.py +42 -0
  50. onepin-0.2.0/src/onepin/core/http_sse/_api.py +148 -0
  51. onepin-0.2.0/src/onepin/core/http_sse/_decoders.py +61 -0
  52. onepin-0.2.0/src/onepin/core/http_sse/_exceptions.py +7 -0
  53. onepin-0.2.0/src/onepin/core/http_sse/_models.py +17 -0
  54. onepin-0.2.0/src/onepin/core/jsonable_encoder.py +120 -0
  55. onepin-0.2.0/src/onepin/core/logging.py +107 -0
  56. onepin-0.2.0/src/onepin/core/parse_error.py +36 -0
  57. onepin-0.2.0/src/onepin/core/pydantic_utilities.py +646 -0
  58. onepin-0.2.0/src/onepin/core/query_encoder.py +58 -0
  59. onepin-0.2.0/src/onepin/core/remove_none_from_dict.py +11 -0
  60. onepin-0.2.0/src/onepin/core/request_options.py +35 -0
  61. onepin-0.2.0/src/onepin/core/serialization.py +276 -0
  62. onepin-0.2.0/src/onepin/environment.py +15 -0
  63. onepin-0.2.0/src/onepin/py.typed +0 -0
  64. onepin-0.2.0/src/onepin/reference.md +1 -0
  65. onepin-0.2.0/src/onepin/tests/conftest.py +21 -0
  66. onepin-0.2.0/src/onepin/tests/test_aiohttp_autodetect.py +113 -0
  67. onepin-0.2.0/tests/__init__.py +0 -0
  68. onepin-0.2.0/tests/build/__init__.py +0 -0
  69. onepin-0.2.0/tests/build/test_dist_contents.py +32 -0
  70. onepin-0.2.0/tests/cli/__init__.py +0 -0
  71. onepin-0.2.0/tests/cli/test_cli_errors.py +51 -0
  72. onepin-0.2.0/tests/cli/test_cli_login.py +133 -0
  73. onepin-0.2.0/tests/cli/test_cli_logout.py +33 -0
  74. onepin-0.2.0/tests/cli/test_cli_templates.py +33 -0
  75. onepin-0.2.0/tests/cli/test_cli_uploads.py +36 -0
  76. onepin-0.2.0/tests/cli/test_cli_voices.py +23 -0
  77. onepin-0.2.0/tests/cli/test_cli_whoami.py +94 -0
  78. onepin-0.2.0/tests/cli/test_cli_workflows.py +31 -0
  79. onepin-0.2.0/tests/conftest.py +71 -0
  80. onepin-0.2.0/tests/unit/__init__.py +0 -0
  81. onepin-0.2.0/tests/unit/test_auth_resolver.py +87 -0
  82. onepin-0.2.0/tests/unit/test_credentials_file.py +82 -0
  83. onepin-0.2.0/tests/unit/test_render.py +59 -0
  84. onepin-0.2.0/uv.lock +1364 -0
@@ -0,0 +1 @@
1
+ { "extends": ["@commitlint/config-conventional"] }
@@ -0,0 +1,60 @@
1
+ name: CI
2
+ on:
3
+ pull_request:
4
+ push:
5
+ branches: [main]
6
+ jobs:
7
+ test:
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ python: ["3.10", "3.11", "3.12", "3.13"]
12
+ os: [ubuntu-latest, macos-latest, windows-latest]
13
+ runs-on: ${{ matrix.os }}
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ # diff-cover needs to see origin/main to compute PR diff coverage
18
+ fetch-depth: 0
19
+ - uses: actions/setup-python@v5
20
+ with: { python-version: '${{ matrix.python }}' }
21
+ - run: pip install uv
22
+ - run: uv sync --all-extras
23
+ # Lint scope: hand-rolled code only. `src/onepin/` (except `_cli/`) is
24
+ # Fern-generated and not subject to project style rules.
25
+ - run: uv run ruff check src/onepin/_cli tests
26
+ - run: uv run ruff format --check src/onepin/_cli tests
27
+ - run: uv run pytest -q --cov=onepin._cli --cov-report=xml --cov-fail-under=80
28
+ - name: Diff coverage
29
+ if: github.event_name == 'pull_request'
30
+ run: uv run diff-cover coverage.xml --compare-branch=origin/main --fail-under=90
31
+ timeout-minutes: 20
32
+ fresh-venv-smoke:
33
+ runs-on: ubuntu-latest
34
+ needs: test
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: actions/setup-python@v5
38
+ with: { python-version: '3.12' }
39
+ - run: pip install build
40
+ - run: python -m build
41
+ - run: python -m venv /tmp/v && /tmp/v/bin/pip install dist/*.whl && /tmp/v/bin/onepin --version
42
+ - run: python -m venv /tmp/vs && /tmp/vs/bin/pip install --no-binary onepin dist/onepin-*.tar.gz && /tmp/vs/bin/onepin --version
43
+ notify-failure:
44
+ if: failure()
45
+ needs: [test, fresh-venv-smoke]
46
+ runs-on: ubuntu-latest
47
+ steps:
48
+ - name: Notify Slack
49
+ if: env.SLACK_WEBHOOK_URL != ''
50
+ uses: slackapi/slack-github-action@v1
51
+ with:
52
+ payload: |
53
+ {"text":"CI failed in ${{ github.repository }}\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
54
+ env:
55
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_ONEPIN_SDK }}
56
+ - name: Skip Slack notification
57
+ if: env.SLACK_WEBHOOK_URL == ''
58
+ run: echo "SLACK_WEBHOOK_ONEPIN_SDK is not configured; skipping Slack notification."
59
+ env:
60
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_ONEPIN_SDK }}
@@ -0,0 +1,10 @@
1
+ name: commitlint
2
+ on:
3
+ pull_request:
4
+ jobs:
5
+ lint:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - uses: actions/checkout@v4
9
+ with: { fetch-depth: 0 }
10
+ - uses: wagoid/commitlint-github-action@v6
@@ -0,0 +1,109 @@
1
+ name: Publish
2
+ on:
3
+ push:
4
+ # Accept both formats: release-please default `onepin-v0.2.0` (component
5
+ # prefix on single-package repos) and the plain `v0.2.0` shape used after
6
+ # `include-component-in-tag: false` lands in release-please-config.json.
7
+ tags: ['v*.*.*', 'onepin-v*.*.*']
8
+ workflow_dispatch:
9
+ inputs:
10
+ tag:
11
+ description: 'Tag to publish (e.g. onepin-v0.2.0)'
12
+ required: true
13
+ jobs:
14
+ build:
15
+ runs-on: ubuntu-latest
16
+ outputs:
17
+ version: ${{ steps.ver.outputs.version }}
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ - uses: actions/setup-python@v5
21
+ with: { python-version: '3.12' }
22
+ - run: pip install build twine trove-classifiers check-wheel-contents pytest
23
+ - run: python -m build
24
+ - run: twine check --strict dist/*
25
+ - run: check-wheel-contents dist/*.whl
26
+ - run: |
27
+ python -c "
28
+ from trove_classifiers import classifiers
29
+ import tomllib, pathlib
30
+ data = tomllib.loads(pathlib.Path('pyproject.toml').read_text())
31
+ for c in data['project'].get('classifiers', []):
32
+ assert c in classifiers, f'Unknown classifier: {c}'
33
+ print('All classifiers valid.')
34
+ "
35
+ - run: python -m pytest tests/build/test_dist_contents.py
36
+ - id: ver
37
+ # Strip everything up to + including the last "v" so both tag formats
38
+ # resolve to a clean PEP 440 version:
39
+ # onepin-v0.2.0 -> 0.2.0
40
+ # v0.2.0 -> 0.2.0
41
+ run: echo "version=${GITHUB_REF_NAME##*v}" >> "$GITHUB_OUTPUT"
42
+ - uses: actions/upload-artifact@v4
43
+ with: { name: dist, path: dist/* }
44
+ smoke-install:
45
+ needs: build
46
+ runs-on: ubuntu-latest
47
+ steps:
48
+ - uses: actions/download-artifact@v4
49
+ with: { name: dist, path: dist }
50
+ - run: pip install dist/*.whl && onepin --version
51
+ - run: pip install --no-binary onepin dist/onepin-*.tar.gz && onepin --version
52
+ test-pypi:
53
+ needs: smoke-install
54
+ runs-on: ubuntu-latest
55
+ environment: testpypi
56
+ permissions: { id-token: write }
57
+ steps:
58
+ - uses: actions/download-artifact@v4
59
+ with: { name: dist, path: dist }
60
+ - uses: pypa/gh-action-pypi-publish@release/v1
61
+ with:
62
+ repository-url: https://test.pypi.org/legacy/
63
+ # Allow re-runs on the same tag: TestPyPI rejects identical-version
64
+ # re-uploads, but a retag (e.g. after fixing a workflow bug) shouldn't
65
+ # cause the whole publish chain to fail.
66
+ skip-existing: true
67
+ testpypi-smoke:
68
+ needs: [build, test-pypi]
69
+ runs-on: ubuntu-latest
70
+ steps:
71
+ - uses: actions/setup-python@v5
72
+ with: { python-version: '3.12' }
73
+ - run: |
74
+ pip install \
75
+ --index-url https://test.pypi.org/simple/ \
76
+ --extra-index-url https://pypi.org/simple/ \
77
+ onepin==${{ needs.build.outputs.version }} \
78
+ && onepin --version
79
+ pypi:
80
+ needs: testpypi-smoke
81
+ runs-on: ubuntu-latest
82
+ environment: pypi
83
+ permissions: { id-token: write, contents: write, attestations: write }
84
+ steps:
85
+ - uses: actions/download-artifact@v4
86
+ with: { name: dist, path: dist }
87
+ - uses: pypa/gh-action-pypi-publish@release/v1
88
+ - name: Verify provenance attestation
89
+ run: gh attestation verify dist/*.whl --owner podonos
90
+ env:
91
+ GH_TOKEN: ${{ github.token }}
92
+ notify-failure:
93
+ if: failure()
94
+ needs: [build, smoke-install, test-pypi, testpypi-smoke, pypi]
95
+ runs-on: ubuntu-latest
96
+ steps:
97
+ - name: Notify Slack
98
+ if: env.SLACK_WEBHOOK_URL != ''
99
+ uses: slackapi/slack-github-action@v1
100
+ with:
101
+ payload: |
102
+ {"text":"Publish failed for ${{ github.ref_name }} in ${{ github.repository }}\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
103
+ env:
104
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_ONEPIN_SDK }}
105
+ - name: Skip Slack notification
106
+ if: env.SLACK_WEBHOOK_URL == ''
107
+ run: echo "SLACK_WEBHOOK_ONEPIN_SDK is not configured; skipping Slack notification."
108
+ env:
109
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_ONEPIN_SDK }}
@@ -0,0 +1,13 @@
1
+ name: release-please validate
2
+ on:
3
+ pull_request:
4
+ paths:
5
+ - 'release-please-config.json'
6
+ - '.release-please-manifest.json'
7
+ jobs:
8
+ dry-run:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: googleapis/release-please-action@v4
13
+ with: { skip-github-release: true }
@@ -0,0 +1,12 @@
1
+ name: release-please
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ permissions:
6
+ contents: write
7
+ pull-requests: write
8
+ jobs:
9
+ release-please:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: googleapis/release-please-action@v4
@@ -0,0 +1,53 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ !tests/build/
11
+ .eggs/
12
+ *.whl
13
+ pip-wheel-metadata/
14
+ .installed.cfg
15
+ lib/
16
+ lib64/
17
+
18
+ # Virtual environments
19
+ .venv/
20
+ venv/
21
+ env/
22
+ ENV/
23
+
24
+ # uv
25
+ .uv/
26
+
27
+ # Testing
28
+ .pytest_cache/
29
+ .coverage
30
+ coverage.xml
31
+ htmlcov/
32
+ .tox/
33
+
34
+ # Type checking
35
+ .mypy_cache/
36
+ .pytype/
37
+
38
+ # IDE
39
+ .idea/
40
+ .vscode/
41
+ *.swp
42
+ *.swo
43
+ .DS_Store
44
+
45
+ # Build artifacts
46
+ /dist/
47
+ /_local/
48
+
49
+ # Secrets
50
+ .env
51
+ .env.*
52
+ !.env.example
53
+ *.credentials
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1 @@
1
+ {".":"0.2.0"}
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.2.0](https://github.com/podonos/onepin-python/compare/onepin-v0.1.0...onepin-v0.2.0) (2026-05-28)
6
+
7
+
8
+ ### Features
9
+
10
+ * **cli:** implement auth commands and package smoke fixes ([dbc49d8](https://github.com/podonos/onepin-python/commit/dbc49d809382aa3424b283084a0a3cfe5be6a571))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **ci:** decouple from Fern-overwritten __init__.py + scope pytest ([f034d45](https://github.com/podonos/onepin-python/commit/f034d456e3bd9d82597567897104e5422d510483))
16
+ * **cli:** move __version__ to onepin._cli (avoid Fern __init__.py overwrite) ([09a778c](https://github.com/podonos/onepin-python/commit/09a778ca9baa3e7f30164ecfdd5dee15d8045932))
17
+ * **cli:** respect HOME on Windows credentials path ([14e7519](https://github.com/podonos/onepin-python/commit/14e7519ae947d1a80651324cb9dc0399ba73c856))
18
+
19
+ ## [Unreleased]
20
+
21
+ ### Features
22
+
23
+ - Initial scaffold: Typer CLI (`onepin`) with auth, workflows, voices, templates, uploads commands
24
+ - `py.typed` PEP 561 marker for typed SDK consumers
25
+ - Full CI matrix: Python 3.10–3.13 × Ubuntu/macOS/Windows
26
+ - OIDC-based PyPI publish via trusted publisher (no token stored)
27
+ - release-please bot manages version bumps and CHANGELOG
onepin-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Podonos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
onepin-0.2.0/Makefile ADDED
@@ -0,0 +1,19 @@
1
+ .PHONY: install lint test build publish-test help
2
+
3
+ help:
4
+ @echo "Targets: install lint test build publish-test"
5
+
6
+ install:
7
+ uv sync --all-extras
8
+
9
+ lint:
10
+ uv run ruff check . && uv run ruff format --check .
11
+
12
+ test:
13
+ uv run pytest -q
14
+
15
+ build:
16
+ uv run python -m build
17
+
18
+ publish-test:
19
+ uv run twine upload --repository testpypi dist/*
onepin-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: onepin
3
+ Version: 0.2.0
4
+ Summary: OnePin Python SDK + CLI
5
+ Project-URL: Documentation, https://docs.onepin.ai
6
+ Project-URL: Source, https://github.com/podonos/onepin-python
7
+ Project-URL: Issues, https://github.com/podonos/onepin-python/issues
8
+ Project-URL: Changelog, https://github.com/podonos/onepin-python/blob/main/CHANGELOG.md
9
+ Author-email: Podonos <kj@podonos.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: click>=8.1
23
+ Requires-Dist: httpx<1.0,>=0.27
24
+ Requires-Dist: pydantic<3.0,>=2.7
25
+ Requires-Dist: rich>=13
26
+ Requires-Dist: tomli; python_version < '3.11'
27
+ Requires-Dist: typer<1.0,>=0.12
28
+ Description-Content-Type: text/markdown
29
+
30
+ # onepin
31
+
32
+ Python SDK + CLI for [OnePin](https://onepin.ai) — the AI-powered voice workflow platform.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install onepin
38
+ ```
39
+
40
+ ## Quickstart
41
+
42
+ Full documentation: [docs.onepin.ai](https://docs.onepin.ai)
43
+
44
+ ### Authentication
45
+
46
+ Mint an API key at [app.onepin.ai/settings/api-keys](https://app.onepin.ai/settings/api-keys), then:
47
+
48
+ ```bash
49
+ onepin login
50
+ # Paste your key when prompted — saved to ~/.onepin/credentials (mode 0600)
51
+ ```
52
+
53
+ ### Common commands
54
+
55
+ ```bash
56
+ onepin whoami # Show active auth source + workspace
57
+ onepin workflows list # List workflows
58
+ onepin workflows run <id> --watch # Start a run and stream status
59
+ onepin voices list # Browse available voices
60
+ onepin templates list # Browse gallery templates
61
+ onepin templates run <id> # Clone a template and start a run
62
+ onepin uploads create --file script.txt --category script
63
+ ```
64
+
65
+ Global flags available on every command:
66
+
67
+ ```
68
+ --api-key Override stored credentials
69
+ --base-url Override API base URL (useful for dev/staging)
70
+ --workspace Target workspace UUID
71
+ --json Emit machine-readable JSON instead of rich tables
72
+ --no-color Disable ANSI coloring
73
+ -v/--verbose Log HTTP requests/responses to stderr
74
+ --debug Verbose + full tracebacks on failure
75
+ ```
76
+
77
+ ## SDK usage
78
+
79
+ > The SDK surface is generated by Fern from the OpenAPI spec. It will be available after the first Fern regen lands.
80
+
81
+ ```python
82
+ from onepin import __version__
83
+ print(__version__)
84
+ ```
85
+
86
+ ## Repository structure
87
+
88
+ - `src/onepin/` — Fern-generated SDK (do not hand-edit; overwritten on each regen)
89
+ - `src/onepin/_cli/` — hand-rolled Typer CLI atop the generated client
90
+ - `scripts/post_fern.sh` — restores `py.typed` markers after Fern overwrites `src/onepin/`
91
+
92
+ ## License
93
+
94
+ MIT — see [LICENSE](LICENSE).
95
+
96
+ ## Status
97
+
98
+ Pre-launch. First published release: v0.1.0 (pending TestPyPI rehearsal + production publish).
onepin-0.2.0/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # onepin
2
+
3
+ Python SDK + CLI for [OnePin](https://onepin.ai) — the AI-powered voice workflow platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install onepin
9
+ ```
10
+
11
+ ## Quickstart
12
+
13
+ Full documentation: [docs.onepin.ai](https://docs.onepin.ai)
14
+
15
+ ### Authentication
16
+
17
+ Mint an API key at [app.onepin.ai/settings/api-keys](https://app.onepin.ai/settings/api-keys), then:
18
+
19
+ ```bash
20
+ onepin login
21
+ # Paste your key when prompted — saved to ~/.onepin/credentials (mode 0600)
22
+ ```
23
+
24
+ ### Common commands
25
+
26
+ ```bash
27
+ onepin whoami # Show active auth source + workspace
28
+ onepin workflows list # List workflows
29
+ onepin workflows run <id> --watch # Start a run and stream status
30
+ onepin voices list # Browse available voices
31
+ onepin templates list # Browse gallery templates
32
+ onepin templates run <id> # Clone a template and start a run
33
+ onepin uploads create --file script.txt --category script
34
+ ```
35
+
36
+ Global flags available on every command:
37
+
38
+ ```
39
+ --api-key Override stored credentials
40
+ --base-url Override API base URL (useful for dev/staging)
41
+ --workspace Target workspace UUID
42
+ --json Emit machine-readable JSON instead of rich tables
43
+ --no-color Disable ANSI coloring
44
+ -v/--verbose Log HTTP requests/responses to stderr
45
+ --debug Verbose + full tracebacks on failure
46
+ ```
47
+
48
+ ## SDK usage
49
+
50
+ > The SDK surface is generated by Fern from the OpenAPI spec. It will be available after the first Fern regen lands.
51
+
52
+ ```python
53
+ from onepin import __version__
54
+ print(__version__)
55
+ ```
56
+
57
+ ## Repository structure
58
+
59
+ - `src/onepin/` — Fern-generated SDK (do not hand-edit; overwritten on each regen)
60
+ - `src/onepin/_cli/` — hand-rolled Typer CLI atop the generated client
61
+ - `scripts/post_fern.sh` — restores `py.typed` markers after Fern overwrites `src/onepin/`
62
+
63
+ ## License
64
+
65
+ MIT — see [LICENSE](LICENSE).
66
+
67
+ ## Status
68
+
69
+ Pre-launch. First published release: v0.1.0 (pending TestPyPI rehearsal + production publish).
@@ -0,0 +1,54 @@
1
+ # RUNBOOK — onepin-python
2
+
3
+ Rollback and incident procedures per plan §F-ter.5.
4
+
5
+ ## Bad SDK on PyPI
6
+
7
+ Use `twine yank` (PEP 592). Yanked versions are skipped for new installs but still reachable by pinned requirements. NEVER use `twine delete` — PyPI deletion is irrevocable.
8
+
9
+ ```bash
10
+ # Yank a broken release
11
+ twine yank onepin==0.1.3 --reason "broken upload flow — install 0.1.4 instead"
12
+
13
+ # Unyank if the concern was a false alarm
14
+ twine unyank onepin==0.1.3
15
+ ```
16
+
17
+ ## Bad tag (not yet on PyPI)
18
+
19
+ Only viable before `publish.yml` completes. After PyPI upload, use yank instead.
20
+
21
+ ```bash
22
+ git tag -d v0.X.Y
23
+ git push --delete origin v0.X.Y
24
+ ```
25
+
26
+ ## Bad release-please PR
27
+
28
+ Close the PR. The bot recreates it on the next push to main with a rebased state.
29
+
30
+ ## Compromised `ONEPIN_DEV_API_KEY`
31
+
32
+ 1. Rotate via [app.onepin.ai/settings/api-keys](https://app.onepin.ai/settings/api-keys)
33
+ 2. Update the `ONEPIN_DEV_API_KEY` GitHub organization secret
34
+ 3. Re-run any failed live-smoke jobs
35
+
36
+ ## Compromised `SLACK_WEBHOOK_ONEPIN_SDK`
37
+
38
+ 1. Regenerate in Slack app settings
39
+ 2. Update the `SLACK_WEBHOOK_ONEPIN_SDK` GitHub organization secret
40
+
41
+ ## Fern auto-PR introduced a regression
42
+
43
+ Revert the merged Fern PR on `onepin-python`. The next event-driven Fern regen (triggered by the next spec-sync merge in `onepin-sdks`) will produce a fresh PR with the corrected SDK.
44
+
45
+ ## Docs site is broken
46
+
47
+ 1. Quick fix: In Cloudflare Pages dashboard → onepin-sdks project → Deployments → click "Rollback to this deployment" on last known-good deploy.
48
+ 2. Permanent fix: Revert the bad markdown commit on `onepin-sdks` main → Cloudflare Pages auto-rebuilds.
49
+
50
+ ## CI pipeline is stuck
51
+
52
+ Alert channel: **#alert-onepin-sdk**
53
+
54
+ All CI/release/docs failures across donut-be webhook, onepin-sdks, and onepin-python route here. Check the linked action run URL in the Slack message.
@@ -0,0 +1,81 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "onepin"
7
+ version = "0.2.0"
8
+ description = "OnePin Python SDK + CLI"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.10"
13
+ authors = [{ name = "Podonos", email = "kj@podonos.com" }]
14
+
15
+ dependencies = [
16
+ "click>=8.1",
17
+ "httpx>=0.27,<1.0",
18
+ "typer>=0.12,<1.0",
19
+ "rich>=13",
20
+ "pydantic>=2.7,<3.0",
21
+ "tomli; python_version<\"3.11\"",
22
+ ]
23
+
24
+ classifiers = [
25
+ "Development Status :: 4 - Beta",
26
+ "Intended Audience :: Developers",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.10",
29
+ "Programming Language :: Python :: 3.11",
30
+ "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: 3.13",
32
+ "Programming Language :: Python :: 3.14",
33
+ "Typing :: Typed",
34
+ ]
35
+
36
+ [project.scripts]
37
+ onepin = "onepin._cli.main:app"
38
+
39
+ [project.urls]
40
+ Documentation = "https://docs.onepin.ai"
41
+ Source = "https://github.com/podonos/onepin-python"
42
+ Issues = "https://github.com/podonos/onepin-python/issues"
43
+ Changelog = "https://github.com/podonos/onepin-python/blob/main/CHANGELOG.md"
44
+
45
+ [dependency-groups]
46
+ dev = [
47
+ "pytest>=8",
48
+ "pytest-asyncio",
49
+ "pytest-cov",
50
+ "respx>=0.22",
51
+ "ruff>=0.6",
52
+ "diff-cover>=8",
53
+ "build",
54
+ "twine",
55
+ "trove-classifiers",
56
+ "check-wheel-contents",
57
+ ]
58
+
59
+ [tool.hatch.build.targets.wheel]
60
+ packages = ["src/onepin"]
61
+
62
+ [tool.hatch.build.targets.wheel.force-include]
63
+ "src/onepin/py.typed" = "onepin/py.typed"
64
+ "src/onepin/_cli/py.typed" = "onepin/_cli/py.typed"
65
+
66
+ [tool.ruff]
67
+ line-length = 120
68
+ target-version = "py310"
69
+ extend-exclude = [
70
+ # Fern-generated SDK is not subject to project style rules. Ruff's exclude
71
+ # is path-prefix only, so CI explicitly runs `ruff check src/onepin/_cli`
72
+ # to lint the hand-rolled CLI subpackage that lives under the same root.
73
+ "src/onepin",
74
+ ]
75
+
76
+ [tool.pytest.ini_options]
77
+ asyncio_mode = "auto"
78
+ addopts = "-q --strict-markers"
79
+ # Restrict collection to top-level tests/ — Fern-generated SDK ships its own
80
+ # tests under src/onepin/tests/ with markers we don't register.
81
+ testpaths = ["tests"]
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3
+ "packages": {
4
+ ".": {
5
+ "release-type": "python",
6
+ "package-name": "onepin",
7
+ "bump-minor-pre-major": true,
8
+ "include-v-in-tag": true,
9
+ "include-component-in-tag": false
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # Restore py.typed PEP 561 markers after Fern overwrites src/onepin/.
3
+ # Run this after every `fern generate` invocation.
4
+ set -euo pipefail
5
+ touch src/onepin/py.typed
6
+ touch src/onepin/_cli/py.typed
7
+ echo "Restored py.typed markers after Fern regen."
@@ -0,0 +1,14 @@
1
+ {
2
+ "cliVersion": "5.38.0",
3
+ "generatorName": "fernapi/fern-python-sdk",
4
+ "generatorVersion": "latest",
5
+ "generatorConfig": {
6
+ "client_class_name": "OnePinClient",
7
+ "package_name": "onepin",
8
+ "flat_layout": false
9
+ },
10
+ "originGitCommit": "babfb180c9f10bd3e41e7f774d958819ad52e34e",
11
+ "originGitCommitIsDirty": false,
12
+ "invokedBy": "ci",
13
+ "ciProvider": "github"
14
+ }