kepler-insights 1.0.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.
@@ -0,0 +1,75 @@
1
+ # --- Secrets (NEVER commit) ---
2
+ .env
3
+ .env.*
4
+ !.env.example
5
+ *.pem
6
+ *.p8
7
+ *.p12
8
+ *.key
9
+ secrets.json
10
+ credentials.json
11
+
12
+ # --- AWS / Lambda build artifacts ---
13
+ zips/
14
+ **/package/
15
+ *.zip
16
+
17
+ # --- Python ---
18
+ __pycache__/
19
+ *.py[cod]
20
+ *.egg-info/
21
+ .pytest_cache/
22
+ .mypy_cache/
23
+ .ruff_cache/
24
+ .venv/
25
+ venv/
26
+ env/
27
+
28
+ # --- Node ---
29
+ node_modules/
30
+ npm-debug.log*
31
+ yarn-error.log*
32
+
33
+ # --- Netlify ---
34
+ .netlify/
35
+
36
+ # --- macOS ---
37
+ .DS_Store
38
+ .AppleDouble
39
+ .LSOverride
40
+
41
+ # --- Editors ---
42
+ .vscode/
43
+ .idea/
44
+ *.swp
45
+ *.swo
46
+ *~
47
+
48
+ # --- Logs / scratch ---
49
+ *.log
50
+ /tmp/
51
+ scratch/
52
+
53
+ # --- Ki_dev: keep website/ + api_site/ + docs/ + sdk-python/ + sdk-typescript/ in git, everything else (admin, outreach, PDFs) backed up separately ---
54
+ Ki_dev/*
55
+ !Ki_dev/website/
56
+ !Ki_dev/api_site/
57
+ !Ki_dev/docs/
58
+ !Ki_dev/sdk-python/
59
+ !Ki_dev/sdk-typescript/
60
+
61
+ # Python SDK build artifacts
62
+ Ki_dev/sdk-python/dist/
63
+ Ki_dev/sdk-python/build/
64
+ Ki_dev/sdk-python/*.egg-info/
65
+ Ki_dev/sdk-python/.pytest_cache/
66
+ Ki_dev/sdk-python/.venv/
67
+
68
+ # TypeScript SDK build artifacts
69
+ Ki_dev/sdk-typescript/node_modules/
70
+ Ki_dev/sdk-typescript/dist/
71
+ Ki_dev/sdk-typescript/.turbo/
72
+ Ki_dev/sdk-typescript/coverage/
73
+
74
+ # --- Claude Code worktrees ---
75
+ .claude/worktrees/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kepler Insights
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.
@@ -0,0 +1,153 @@
1
+ Metadata-Version: 2.4
2
+ Name: kepler-insights
3
+ Version: 1.0.0
4
+ Summary: Official Python SDK for the Kepler Insights API — curated company-scoring intelligence over a 67-signal engine.
5
+ Project-URL: Homepage, https://api.keplerinsights.us
6
+ Project-URL: Documentation, https://docs.keplerinsights.us
7
+ Project-URL: Support, https://console.keplerinsights.us
8
+ Author-email: Kepler Insights <noah@keplerinsights.us>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: api-client,company-intelligence,kepler,scoring,vc
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Financial and Insurance Industry
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: httpx<1.0,>=0.27
26
+ Requires-Dist: pydantic<3.0,>=2.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: build>=1.0; extra == 'dev'
29
+ Requires-Dist: pytest>=8.0; extra == 'dev'
30
+ Requires-Dist: respx>=0.21; extra == 'dev'
31
+ Requires-Dist: ruff>=0.5; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # Kepler Insights — Python SDK
35
+
36
+ Official Python SDK for the [Kepler Insights API](https://api.keplerinsights.us) — curated company-scoring intelligence over a 67-signal engine.
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ pip install kepler-insights
42
+ ```
43
+
44
+ Requires Python 3.10+. Depends on [httpx](https://www.python-httpx.org/) and [pydantic v2](https://docs.pydantic.dev/latest/).
45
+
46
+ ## Quickstart
47
+
48
+ ```python
49
+ from kepler_insights import Kepler
50
+
51
+ with Kepler(api_key="ki_live_...") as client:
52
+ score = client.score("stripe.com")
53
+ print(f"{score.domain}: {score.ki_rating} ({score.composite_score:.1f})")
54
+ print(f" team: {score.buckets.team_structure:.1f}")
55
+ print(f" market: {score.buckets.market_position:.1f}")
56
+ ```
57
+
58
+ Sandbox keys (`ki_test_...`) accept only the 4 canned domains — `acme.test`, `unicorn.test`, `struggling.test`, `cohort.test`. See the [Sandbox guide](https://docs.keplerinsights.us/sandbox).
59
+
60
+ ## API surface
61
+
62
+ | Method | Endpoint | Returns |
63
+ |---|---|---|
64
+ | `client.score(domain)` | POST `/v1/score` | `Score` |
65
+ | `client.get_score(domain)` | GET `/v1/score/{domain}` | `Score` |
66
+ | `client.start_score(domain)` | POST `/v1/score?wait=false` | `Job` (Growth+) |
67
+ | `client.get_job(job_id)` | GET `/v1/jobs/{job_id}` | `JobResponse` |
68
+ | `client.history(domain, limit=, cursor=)` | GET `/v1/score/{domain}/history` | `HistoryPage` |
69
+ | `client.iter_history(domain, max_records=)` | (auto-paginates) | iterator of `HistoryRecord` |
70
+ | `client.cohort(domain)` | GET `/v1/company/{domain}/cohort` | `Cohort` |
71
+ | `client.confidence(domain)` | GET `/v1/company/{domain}/confidence` | `Confidence` |
72
+ | `client.distribution()` | GET `/v1/distribution` | `Distribution` |
73
+ | `client.movers(window)` | GET `/v1/movers` | `Movers` |
74
+ | `client.signals()` | GET `/v1/signals` | `SignalsManifest` |
75
+ | `client.usage()` | GET `/v1/usage` | `Usage` |
76
+
77
+ ## Async cold scoring
78
+
79
+ Cold scoring takes 30–60 seconds. On Growth and above, you can start a job and poll without holding an HTTP connection open:
80
+
81
+ ```python
82
+ job = client.start_score("stripe.com") # returns immediately
83
+ score = job.wait(timeout=180) # blocks until complete; raises on timeout
84
+ ```
85
+
86
+ If the API short-circuits to a cached-fresh response (no cold work needed), `start_score` returns a `Job` already in the `complete` state — `wait()` returns instantly. This mirrors Stripe's `payment_intent` "no action needed" pattern.
87
+
88
+ ## Error handling
89
+
90
+ Every error inherits from `KeplerError`. Branch on the specific subclass or the stable `error.code` string:
91
+
92
+ ```python
93
+ from kepler_insights import (
94
+ Kepler,
95
+ AuthError,
96
+ ColdBudgetExhausted,
97
+ FreeTierSandboxOnly,
98
+ NotFound,
99
+ RateLimitError,
100
+ ScoringTimeout,
101
+ )
102
+
103
+ try:
104
+ score = client.score("stripe.com")
105
+ except FreeTierSandboxOnly:
106
+ print("Upgrade to Starter for live scoring.")
107
+ except ColdBudgetExhausted as e:
108
+ print(f"Monthly cap hit. Resets in {e.retry_after}s. Upgrade for more.")
109
+ except RateLimitError as e:
110
+ print(f"Rate limited. Retry in {e.retry_after}s.")
111
+ except ScoringTimeout:
112
+ print("Cold scoring exceeded sync budget — use start_score() for async.")
113
+ except NotFound:
114
+ print("Never scored. Trigger one with score(domain).")
115
+ except AuthError:
116
+ print("Invalid or revoked API key.")
117
+ ```
118
+
119
+ The SDK auto-retries on 5xx and network errors with exponential backoff (3 attempts by default). It never retries 4xx — those are caller errors.
120
+
121
+ ## Configuration
122
+
123
+ ```python
124
+ client = Kepler(
125
+ api_key="ki_live_...",
126
+ base_url="https://api.keplerinsights.us", # override only for testing
127
+ timeout=70.0, # per-request timeout (s)
128
+ retries=3, # 5xx retry attempts
129
+ )
130
+ ```
131
+
132
+ For custom transports (proxies, mTLS, etc.) inject your own `httpx.Client`:
133
+
134
+ ```python
135
+ import httpx
136
+ custom = httpx.Client(timeout=120, transport=httpx.HTTPTransport(retries=0))
137
+ client = Kepler(api_key="ki_live_...", http_client=custom)
138
+ ```
139
+
140
+ ## Development
141
+
142
+ ```bash
143
+ git clone <repo>
144
+ cd Ki_dev/sdk-python
145
+ python3 -m venv .venv
146
+ source .venv/bin/activate
147
+ pip install -e ".[dev]"
148
+ pytest
149
+ ```
150
+
151
+ ## License
152
+
153
+ MIT. The API itself is proprietary; the SDK wrapper is MIT-licensed so you can vendor it freely.
@@ -0,0 +1,128 @@
1
+ # Publishing `kepler-insights` to PyPI
2
+
3
+ Run this checklist at the **coordinated API launch event** (same window as Mintlify, Instatus, Stripe SKU creation, and the `api.keplerinsights.us` DNS flip). All code is pre-shipped (F1, 2026-05-12) — this checklist just publishes.
4
+
5
+ ## 0. Prereqs
6
+
7
+ - A PyPI account on the Kepler Insights org (https://pypi.org). Reserve the `kepler-insights` name well before launch event by uploading version 0.0.1 placeholder, or check it's still available.
8
+ - A TestPyPI account (https://test.pypi.org) for the dry run.
9
+ - A PyPI API token scoped to `kepler-insights` (Account settings → API tokens → "scope to project").
10
+ - A TestPyPI API token (separate token, separate account).
11
+ - Python 3.11+ locally with `build` and `twine` available.
12
+
13
+ ## 1. Pre-flight checks
14
+
15
+ ```bash
16
+ cd Ki_dev/sdk-python
17
+
18
+ # Clean state
19
+ rm -rf dist/ build/ *.egg-info src/*.egg-info
20
+
21
+ # Run tests
22
+ python3.13 -m venv .venv
23
+ source .venv/bin/activate
24
+ pip install --upgrade pip
25
+ pip install -e ".[dev]"
26
+ pytest # expect 33 passing
27
+
28
+ # Lint
29
+ ruff check src tests
30
+
31
+ # Confirm version is what you want to publish
32
+ grep '__version__' src/kepler_insights/_version.py # expect 1.0.0
33
+ ```
34
+
35
+ ## 2. Build artifacts
36
+
37
+ ```bash
38
+ python -m build
39
+ ls -la dist/
40
+ # expect:
41
+ # kepler_insights-1.0.0-py3-none-any.whl
42
+ # kepler_insights-1.0.0.tar.gz
43
+ ```
44
+
45
+ Inspect the sdist contents before uploading:
46
+ ```bash
47
+ tar -tzf dist/kepler_insights-1.0.0.tar.gz | head -30
48
+ ```
49
+
50
+ Should include `src/kepler_insights/*.py`, `pyproject.toml`, `README.md`, `LICENSE`. Should NOT include `.venv/`, `.pytest_cache/`, `tests/` (by hatchling default).
51
+
52
+ ## 3. Upload to TestPyPI first
53
+
54
+ ```bash
55
+ pip install --upgrade twine
56
+ twine upload --repository testpypi dist/*
57
+ # username: __token__
58
+ # password: <TestPyPI API token starting `pypi-...`>
59
+ ```
60
+
61
+ Verify in a clean venv that the install works:
62
+
63
+ ```bash
64
+ deactivate
65
+ rm -rf /tmp/sdk-verify && python3.13 -m venv /tmp/sdk-verify
66
+ /tmp/sdk-verify/bin/pip install --index-url https://test.pypi.org/simple/ \
67
+ --extra-index-url https://pypi.org/simple/ \
68
+ kepler-insights
69
+ /tmp/sdk-verify/bin/python -c "from kepler_insights import Kepler; print(Kepler)"
70
+ ```
71
+
72
+ The `--extra-index-url` to real PyPI is required because TestPyPI doesn't host httpx/pydantic.
73
+
74
+ ## 4. Upload to production PyPI
75
+
76
+ ```bash
77
+ source .venv/bin/activate
78
+ twine upload dist/*
79
+ # username: __token__
80
+ # password: <PyPI production API token>
81
+ ```
82
+
83
+ ## 5. Post-publish verification
84
+
85
+ ```bash
86
+ # Fresh venv, no override
87
+ rm -rf /tmp/sdk-prod-verify && python3.13 -m venv /tmp/sdk-prod-verify
88
+ /tmp/sdk-prod-verify/bin/pip install kepler-insights
89
+ /tmp/sdk-prod-verify/bin/python -c "
90
+ from kepler_insights import Kepler, __version__
91
+ print('version:', __version__)
92
+ print('Kepler client class:', Kepler)
93
+ "
94
+
95
+ # Page check
96
+ open https://pypi.org/project/kepler-insights/
97
+ # expect: project page shows version 1.0.0, links to api.keplerinsights.us,
98
+ # README rendered cleanly
99
+ ```
100
+
101
+ ## 6. Update downstream
102
+
103
+ - [ ] Update [Ki_dev/docs/quickstart.mdx](../docs/quickstart.mdx) install instruction if needed.
104
+ - [ ] Update [Ki_dev/api_site/index.html](../api_site/index.html) "Install the SDK" hero with the `pip install kepler-insights` snippet.
105
+ - [ ] Announce in the launch blast email.
106
+
107
+ ## Rollback / yank
108
+
109
+ If a release is broken:
110
+
111
+ ```bash
112
+ # Yank the version (still installable by explicit pin, but no longer the default)
113
+ twine yank kepler-insights 1.0.0
114
+ ```
115
+
116
+ Yank is reversible. Don't `twine delete` — once deleted, the version number can never be reused.
117
+
118
+ For a hotfix release: bump `_version.py` to `1.0.1`, re-test, re-build, re-upload. PyPI doesn't allow re-uploading a version that already exists.
119
+
120
+ ## Versioning policy
121
+
122
+ Semantic versioning. The OpenAPI spec at `Ki_dev/docs/openapi.yaml` is the source of truth for breaking-change detection:
123
+
124
+ - **Patch (1.0.x)** — bug fixes, no public-surface changes
125
+ - **Minor (1.x.0)** — additive: new methods, new fields on response models (Pydantic `extra="allow"` keeps old code working)
126
+ - **Major (x.0.0)** — removal or rename of a public method / model field
127
+
128
+ If the API ships a v2, this SDK ships a `2.0.0` adding a `KeplerV2` client class alongside `Kepler` (which keeps targeting v1 endpoints) — same pattern as `openai.OpenAI` vs `openai.AzureOpenAI`. Don't break v1 callers when v2 lands.
@@ -0,0 +1,120 @@
1
+ # Kepler Insights — Python SDK
2
+
3
+ Official Python SDK for the [Kepler Insights API](https://api.keplerinsights.us) — curated company-scoring intelligence over a 67-signal engine.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install kepler-insights
9
+ ```
10
+
11
+ Requires Python 3.10+. Depends on [httpx](https://www.python-httpx.org/) and [pydantic v2](https://docs.pydantic.dev/latest/).
12
+
13
+ ## Quickstart
14
+
15
+ ```python
16
+ from kepler_insights import Kepler
17
+
18
+ with Kepler(api_key="ki_live_...") as client:
19
+ score = client.score("stripe.com")
20
+ print(f"{score.domain}: {score.ki_rating} ({score.composite_score:.1f})")
21
+ print(f" team: {score.buckets.team_structure:.1f}")
22
+ print(f" market: {score.buckets.market_position:.1f}")
23
+ ```
24
+
25
+ Sandbox keys (`ki_test_...`) accept only the 4 canned domains — `acme.test`, `unicorn.test`, `struggling.test`, `cohort.test`. See the [Sandbox guide](https://docs.keplerinsights.us/sandbox).
26
+
27
+ ## API surface
28
+
29
+ | Method | Endpoint | Returns |
30
+ |---|---|---|
31
+ | `client.score(domain)` | POST `/v1/score` | `Score` |
32
+ | `client.get_score(domain)` | GET `/v1/score/{domain}` | `Score` |
33
+ | `client.start_score(domain)` | POST `/v1/score?wait=false` | `Job` (Growth+) |
34
+ | `client.get_job(job_id)` | GET `/v1/jobs/{job_id}` | `JobResponse` |
35
+ | `client.history(domain, limit=, cursor=)` | GET `/v1/score/{domain}/history` | `HistoryPage` |
36
+ | `client.iter_history(domain, max_records=)` | (auto-paginates) | iterator of `HistoryRecord` |
37
+ | `client.cohort(domain)` | GET `/v1/company/{domain}/cohort` | `Cohort` |
38
+ | `client.confidence(domain)` | GET `/v1/company/{domain}/confidence` | `Confidence` |
39
+ | `client.distribution()` | GET `/v1/distribution` | `Distribution` |
40
+ | `client.movers(window)` | GET `/v1/movers` | `Movers` |
41
+ | `client.signals()` | GET `/v1/signals` | `SignalsManifest` |
42
+ | `client.usage()` | GET `/v1/usage` | `Usage` |
43
+
44
+ ## Async cold scoring
45
+
46
+ Cold scoring takes 30–60 seconds. On Growth and above, you can start a job and poll without holding an HTTP connection open:
47
+
48
+ ```python
49
+ job = client.start_score("stripe.com") # returns immediately
50
+ score = job.wait(timeout=180) # blocks until complete; raises on timeout
51
+ ```
52
+
53
+ If the API short-circuits to a cached-fresh response (no cold work needed), `start_score` returns a `Job` already in the `complete` state — `wait()` returns instantly. This mirrors Stripe's `payment_intent` "no action needed" pattern.
54
+
55
+ ## Error handling
56
+
57
+ Every error inherits from `KeplerError`. Branch on the specific subclass or the stable `error.code` string:
58
+
59
+ ```python
60
+ from kepler_insights import (
61
+ Kepler,
62
+ AuthError,
63
+ ColdBudgetExhausted,
64
+ FreeTierSandboxOnly,
65
+ NotFound,
66
+ RateLimitError,
67
+ ScoringTimeout,
68
+ )
69
+
70
+ try:
71
+ score = client.score("stripe.com")
72
+ except FreeTierSandboxOnly:
73
+ print("Upgrade to Starter for live scoring.")
74
+ except ColdBudgetExhausted as e:
75
+ print(f"Monthly cap hit. Resets in {e.retry_after}s. Upgrade for more.")
76
+ except RateLimitError as e:
77
+ print(f"Rate limited. Retry in {e.retry_after}s.")
78
+ except ScoringTimeout:
79
+ print("Cold scoring exceeded sync budget — use start_score() for async.")
80
+ except NotFound:
81
+ print("Never scored. Trigger one with score(domain).")
82
+ except AuthError:
83
+ print("Invalid or revoked API key.")
84
+ ```
85
+
86
+ The SDK auto-retries on 5xx and network errors with exponential backoff (3 attempts by default). It never retries 4xx — those are caller errors.
87
+
88
+ ## Configuration
89
+
90
+ ```python
91
+ client = Kepler(
92
+ api_key="ki_live_...",
93
+ base_url="https://api.keplerinsights.us", # override only for testing
94
+ timeout=70.0, # per-request timeout (s)
95
+ retries=3, # 5xx retry attempts
96
+ )
97
+ ```
98
+
99
+ For custom transports (proxies, mTLS, etc.) inject your own `httpx.Client`:
100
+
101
+ ```python
102
+ import httpx
103
+ custom = httpx.Client(timeout=120, transport=httpx.HTTPTransport(retries=0))
104
+ client = Kepler(api_key="ki_live_...", http_client=custom)
105
+ ```
106
+
107
+ ## Development
108
+
109
+ ```bash
110
+ git clone <repo>
111
+ cd Ki_dev/sdk-python
112
+ python3 -m venv .venv
113
+ source .venv/bin/activate
114
+ pip install -e ".[dev]"
115
+ pytest
116
+ ```
117
+
118
+ ## License
119
+
120
+ MIT. The API itself is proprietary; the SDK wrapper is MIT-licensed so you can vendor it freely.
@@ -0,0 +1,63 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.18"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "kepler-insights"
7
+ dynamic = ["version"]
8
+ description = "Official Python SDK for the Kepler Insights API — curated company-scoring intelligence over a 67-signal engine."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [{ name = "Kepler Insights", email = "noah@keplerinsights.us" }]
13
+ requires-python = ">=3.10"
14
+ keywords = ["kepler", "scoring", "company-intelligence", "vc", "api-client"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Intended Audience :: Financial and Insurance Industry",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: Software Development :: Libraries :: Python Modules",
27
+ "Typing :: Typed",
28
+ ]
29
+ dependencies = [
30
+ "httpx>=0.27,<1.0",
31
+ "pydantic>=2.0,<3.0",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://api.keplerinsights.us"
36
+ Documentation = "https://docs.keplerinsights.us"
37
+ Support = "https://console.keplerinsights.us"
38
+
39
+ [project.optional-dependencies]
40
+ dev = [
41
+ "pytest>=8.0",
42
+ "respx>=0.21",
43
+ "ruff>=0.5",
44
+ "build>=1.0",
45
+ ]
46
+
47
+ [tool.hatch.version]
48
+ path = "src/kepler_insights/_version.py"
49
+
50
+ [tool.hatch.build.targets.wheel]
51
+ packages = ["src/kepler_insights"]
52
+
53
+ [tool.pytest.ini_options]
54
+ testpaths = ["tests"]
55
+ addopts = "-ra --strict-markers"
56
+ pythonpath = ["src"]
57
+
58
+ [tool.ruff]
59
+ line-length = 100
60
+ target-version = "py310"
61
+
62
+ [tool.ruff.lint]
63
+ select = ["E", "F", "I", "B", "UP"]
@@ -0,0 +1,54 @@
1
+ """Kepler Insights API — official Python SDK.
2
+
3
+ Quickstart
4
+ ----------
5
+
6
+ >>> from kepler_insights import Kepler
7
+ >>> with Kepler(api_key="ki_live_...") as client:
8
+ ... score = client.score("stripe.com")
9
+ ... print(score.ki_rating, score.composite_score)
10
+
11
+ See https://docs.keplerinsights.us for the full guide.
12
+ """
13
+
14
+ from ._version import __version__
15
+ from .client import Kepler, Job
16
+ from . import errors, models
17
+
18
+ # Common error classes re-exported at the top level for ergonomic imports:
19
+ # from kepler_insights import KeplerError, RateLimitError, ColdBudgetExhausted
20
+ from .errors import (
21
+ KeplerError,
22
+ AuthError,
23
+ FreeTierSandboxOnly,
24
+ Forbidden,
25
+ NotFound,
26
+ ValidationError,
27
+ RateLimitError,
28
+ ColdBudgetExhausted,
29
+ ServerError,
30
+ ScoringTimeout,
31
+ JobTimeout,
32
+ JobFailed,
33
+ )
34
+
35
+ __all__ = [
36
+ "__version__",
37
+ "Kepler",
38
+ "Job",
39
+ "errors",
40
+ "models",
41
+ # Error classes
42
+ "KeplerError",
43
+ "AuthError",
44
+ "FreeTierSandboxOnly",
45
+ "Forbidden",
46
+ "NotFound",
47
+ "ValidationError",
48
+ "RateLimitError",
49
+ "ColdBudgetExhausted",
50
+ "ServerError",
51
+ "ScoringTimeout",
52
+ "JobTimeout",
53
+ "JobFailed",
54
+ ]