hirebase 0.1.1__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 (55) hide show
  1. hirebase-0.1.1/LICENSE +8 -0
  2. hirebase-0.1.1/PKG-INFO +289 -0
  3. hirebase-0.1.1/README.md +250 -0
  4. hirebase-0.1.1/pyproject.toml +74 -0
  5. hirebase-0.1.1/setup.cfg +4 -0
  6. hirebase-0.1.1/src/hirebase/__init__.py +102 -0
  7. hirebase-0.1.1/src/hirebase/_files.py +53 -0
  8. hirebase-0.1.1/src/hirebase/_ops.py +377 -0
  9. hirebase-0.1.1/src/hirebase/_version.py +1 -0
  10. hirebase-0.1.1/src/hirebase/client.py +227 -0
  11. hirebase-0.1.1/src/hirebase/config.py +72 -0
  12. hirebase-0.1.1/src/hirebase/exceptions.py +123 -0
  13. hirebase-0.1.1/src/hirebase/models/__init__.py +50 -0
  14. hirebase-0.1.1/src/hirebase/models/base.py +45 -0
  15. hirebase-0.1.1/src/hirebase/models/common.py +47 -0
  16. hirebase-0.1.1/src/hirebase/models/companies.py +176 -0
  17. hirebase-0.1.1/src/hirebase/models/insights.py +84 -0
  18. hirebase-0.1.1/src/hirebase/models/jobs.py +202 -0
  19. hirebase-0.1.1/src/hirebase/models/neural.py +179 -0
  20. hirebase-0.1.1/src/hirebase/models/resumes.py +47 -0
  21. hirebase-0.1.1/src/hirebase/models/tasks.py +69 -0
  22. hirebase-0.1.1/src/hirebase/py.typed +0 -0
  23. hirebase-0.1.1/src/hirebase/resources/__init__.py +18 -0
  24. hirebase-0.1.1/src/hirebase/resources/companies.py +180 -0
  25. hirebase-0.1.1/src/hirebase/resources/jobs.py +233 -0
  26. hirebase-0.1.1/src/hirebase/resources/resumes.py +123 -0
  27. hirebase-0.1.1/src/hirebase/resources/tasks.py +99 -0
  28. hirebase-0.1.1/src/hirebase/streaming.py +147 -0
  29. hirebase-0.1.1/src/hirebase.egg-info/PKG-INFO +289 -0
  30. hirebase-0.1.1/src/hirebase.egg-info/SOURCES.txt +53 -0
  31. hirebase-0.1.1/src/hirebase.egg-info/dependency_links.txt +1 -0
  32. hirebase-0.1.1/src/hirebase.egg-info/entry_points.txt +2 -0
  33. hirebase-0.1.1/src/hirebase.egg-info/requires.txt +18 -0
  34. hirebase-0.1.1/src/hirebase.egg-info/top_level.txt +2 -0
  35. hirebase-0.1.1/src/hirebase_cli/__init__.py +3 -0
  36. hirebase-0.1.1/src/hirebase_cli/client.py +476 -0
  37. hirebase-0.1.1/src/hirebase_cli/commands/__init__.py +10 -0
  38. hirebase-0.1.1/src/hirebase_cli/commands/blog.py +357 -0
  39. hirebase-0.1.1/src/hirebase_cli/commands/companies.py +222 -0
  40. hirebase-0.1.1/src/hirebase_cli/commands/health.py +39 -0
  41. hirebase-0.1.1/src/hirebase_cli/commands/insights.py +363 -0
  42. hirebase-0.1.1/src/hirebase_cli/commands/jobs.py +355 -0
  43. hirebase-0.1.1/src/hirebase_cli/commands/scraper.py +126 -0
  44. hirebase-0.1.1/src/hirebase_cli/config.py +54 -0
  45. hirebase-0.1.1/src/hirebase_cli/formatters.py +707 -0
  46. hirebase-0.1.1/src/hirebase_cli/main.py +142 -0
  47. hirebase-0.1.1/src/hirebase_cli/models.py +223 -0
  48. hirebase-0.1.1/tests/test_client_mock.py +155 -0
  49. hirebase-0.1.1/tests/test_integration.py +76 -0
  50. hirebase-0.1.1/tests/test_neural.py +88 -0
  51. hirebase-0.1.1/tests/test_parsing.py +100 -0
  52. hirebase-0.1.1/tests/test_query.py +67 -0
  53. hirebase-0.1.1/tests/test_resume_model.py +27 -0
  54. hirebase-0.1.1/tests/test_resumes_mock.py +81 -0
  55. hirebase-0.1.1/tests/test_streaming.py +42 -0
hirebase-0.1.1/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ Copyright 2026 Hirebase LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+
@@ -0,0 +1,289 @@
1
+ Metadata-Version: 2.4
2
+ Name: hirebase
3
+ Version: 0.1.1
4
+ Summary: Official Python SDK for the Hirebase API (jobs & company data)
5
+ Author-email: Hirebase <spencer@hirebase.org>
6
+ License: MIT
7
+ Project-URL: Homepage, https://hirebase.org
8
+ Project-URL: Documentation, https://docs.hirebase.org
9
+ Project-URL: Repository, https://github.com/hirebase/hirebase-python-sdk
10
+ Keywords: hirebase,jobs,hiring,api,sdk,company data
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: requests>=2.28.0
24
+ Requires-Dist: httpx>=0.25.0
25
+ Requires-Dist: pydantic>=2.0.0
26
+ Requires-Dist: python-dotenv>=1.0.0
27
+ Provides-Extra: streaming
28
+ Requires-Dist: ijson>=3.2.0; extra == "streaming"
29
+ Provides-Extra: cli
30
+ Requires-Dist: typer>=0.9.0; extra == "cli"
31
+ Requires-Dist: rich>=13.0.0; extra == "cli"
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
34
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
35
+ Requires-Dist: ijson>=3.2.0; extra == "dev"
36
+ Requires-Dist: typer>=0.9.0; extra == "dev"
37
+ Requires-Dist: rich>=13.0.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ <div align="left" style="margin-bottom: 16px;">
41
+ <img src="https://www.hirebase.org/hirebase-logo-text.svg" alt="Hirebase Logo" width="160" style="vertical-align: middle; margin-bottom: 8px;" />
42
+ <div style="margin-top: 12px; display: flex; gap: 12px;">
43
+ <a href="https://www.hirebase.org/" style="text-decoration:none;">
44
+ <img src="https://img.shields.io/badge/Website-hirebase.org-blue?style=for-the-badge&logo=Google%20chrome&logoColor=white" alt="Website" />
45
+ </a>
46
+ <a href="https://app.hirebase.org/login" style="text-decoration:none;">
47
+ <img src="https://img.shields.io/badge/Login-Login-green?style=for-the-badge&logo=google&logoColor=white" alt="Login" />
48
+ </a>
49
+ <a href="https://app.hirebase.org/signup" style="text-decoration:none;">
50
+ <img src="https://img.shields.io/badge/Sign%20Up-Create%20Account-purple?style=for-the-badge&logo=addthis&logoColor=white" alt="Sign Up" />
51
+ </a>
52
+ </div>
53
+ </div>
54
+ <div>
55
+ <span style="font-size:2.4rem;font-weight:600;">hirebase-python-sdk</span>
56
+ </div>
57
+ A lean, typed Python client for the [Hirebase API](https://docs.hirebase.org/) —
58
+ search jobs and companies, run market insights, and export job data at scale.
59
+
60
+ - **Sync and async** clients (`hirebase.Client` / `hirebase.AsyncClient`).
61
+ - **Typed by default** — responses come back as Pydantic models; pass
62
+ `return_type=dict` anywhere for raw dicts.
63
+ - **Streaming exports** — kick off an export, poll it, download it, and stream
64
+ millions of jobs without loading them into memory.
65
+ - **Self-contained** — the SDK ships its own types and depends only on
66
+ `requests`, `httpx`, and `pydantic`.
67
+
68
+ > **Guides:** [Getting started](./docs/README.md) ·
69
+ > [Jobs](./docs/jobs.md) · [Companies](./docs/companies.md) ·
70
+ > [Resumes](./docs/resumes.md) · [Tasks](./docs/tasks.md) · [Errors](./docs/errors.md) ·
71
+ > [Examples](./examples/README.md)
72
+
73
+ ## Installation
74
+
75
+ ```bash
76
+ pip install hirebase
77
+
78
+ # Optional extras
79
+ pip install "hirebase[streaming]" # ijson, for streaming JSON-array exports
80
+ pip install "hirebase[cli]" # the bundled `hirebase` command-line tool
81
+ ```
82
+
83
+ ## Authentication
84
+
85
+ Pass your API key directly, or set it via the environment:
86
+
87
+ ```python
88
+ import hirebase
89
+ client = hirebase.Client(api_key="sk_live_...")
90
+ ```
91
+
92
+ ```bash
93
+ export HIREBASE_API_KEY="sk_live_..."
94
+ export HIREBASE_BASE_URL="https://api.hirebase.org" # optional, this is the default
95
+ ```
96
+
97
+ Resolution order for every setting is **argument → environment variable →
98
+ default**. The base URL defaults to `https://api.hirebase.org`.
99
+
100
+ ## Quickstart
101
+
102
+ ```python
103
+ import hirebase
104
+
105
+ client = hirebase.Client(api_key="sk_live_...")
106
+
107
+ # Search jobs — results are typed and iterable
108
+ result = client.jobs.search({
109
+ "job_titles": ["Software Engineer", "Product Engineer"],
110
+ "locations": [{"city": "San Francisco", "region": "California",
111
+ "country": "United States"}],
112
+ "limit": 20,
113
+ })
114
+
115
+ print(result.total_count, "matches")
116
+ for job in result:
117
+ print(job.job_title, "@", job.company_name, "—", job.salary_range)
118
+ ```
119
+
120
+ Booleans are accepted natively (`visa=True`), and `locations` is a friendly
121
+ alias for the API's `geo_locations`. Unknown filter keys are passed through
122
+ untouched, so new API features work before the SDK is updated.
123
+
124
+ ### Async
125
+
126
+ ```python
127
+ import asyncio, hirebase
128
+
129
+ async def main():
130
+ async with hirebase.AsyncClient(api_key="sk_live_...") as client:
131
+ result = await client.jobs.search({"job_titles": ["Engineer"]})
132
+ for job in result:
133
+ print(job.job_title)
134
+
135
+ asyncio.run(main())
136
+ ```
137
+
138
+ Every method has the same signature on both clients — the async versions are
139
+ awaitable.
140
+
141
+ ## Jobs
142
+
143
+ ```python
144
+ # Search
145
+ result = client.jobs.search(query, page=1, limit=20)
146
+
147
+ # Fetch one job
148
+ job = client.jobs.get("6958cfd211e2763c3491ef8b")
149
+
150
+ # Market insights for a cohort (same filter shape as search)
151
+ insights = client.jobs.insights({"job_titles": ["Data Scientist"]})
152
+ print(insights.headline.median_salary, insights.salary.p90)
153
+ ```
154
+
155
+ ### Typed inputs
156
+
157
+ You can pass a plain `dict` or build a typed query:
158
+
159
+ ```python
160
+ from hirebase import JobQuery, SalaryRange
161
+
162
+ query = JobQuery(
163
+ job_titles=["Backend Engineer"],
164
+ salary=SalaryRange(min=150_000, currency="USD"),
165
+ location_types=["Remote"],
166
+ visa=True,
167
+ )
168
+ result = client.jobs.search(query)
169
+ ```
170
+
171
+ ## Exporting jobs (async task flow)
172
+
173
+ Exports are processed server-side and returned as a downloadable file.
174
+
175
+ ```python
176
+ query = {
177
+ "job_titles": ["Software Engineer", "Product Engineer", "Fullstack Engineer"],
178
+ "locations": [{"city": "San Francisco", "region": "California",
179
+ "country": "United States"}],
180
+ }
181
+
182
+ # 1. Start the export -> returns a Task
183
+ task = client.jobs.export(query, format="json") # or format="csv"
184
+
185
+ # 2. Poll until it finishes -> (success, result)
186
+ success, result = client.tasks.poll(task)
187
+ if not success:
188
+ raise RuntimeError(f"Export failed: {result.error}")
189
+
190
+ # 3. Download the file (streamed to disk)
191
+ client.stream_file(result["download_url"], file_path="./jobs.json")
192
+
193
+ # 4. Stream jobs from the file (typed by default; uses constant memory)
194
+ for job in client.jobs.stream_file("./jobs.json"):
195
+ print(job.job_title)
196
+
197
+ # ...or get raw dicts
198
+ for row in client.jobs.stream_file("./jobs.json", return_type=dict):
199
+ ...
200
+ ```
201
+
202
+ `poll()` accepts a `Task`, a task dict, or a task id, plus `interval`,
203
+ `timeout`, and an `on_progress` callback. The result dict contains
204
+ `download_url`, `file_size`, `record_count`, and `expiry_time`.
205
+
206
+ You can also stream **directly from the export URL** without saving to disk
207
+ (JSON Lines exports only):
208
+
209
+ ```python
210
+ for job in client.jobs.stream_url(result["download_url"]):
211
+ print(job.job_title)
212
+ ```
213
+
214
+ ## Companies
215
+
216
+ ```python
217
+ # Search
218
+ companies = client.companies.search({"company_name": "Stripe"})
219
+ for company in companies:
220
+ print(company.company_name, company.company_slug)
221
+
222
+ # Get a company by slug — optionally with its jobs and live insights
223
+ company = client.companies.get("stripe", return_jobs=True, return_insights=True)
224
+ print(company.description_summary)
225
+ print(company.insights_data.headline.total_count)
226
+
227
+ # Bound helpers (the object remembers its client)
228
+ insights = company.insights()
229
+ jobs = company.get_jobs(limit=10)
230
+
231
+ # Company-scoped insights directly
232
+ insights = client.companies.insights("stripe", query={"days_ago": 30})
233
+ ```
234
+
235
+ ## Typed vs. dict responses
236
+
237
+ Every method returns typed models by default. Pass `return_type=dict` to get
238
+ the raw API payload instead:
239
+
240
+ ```python
241
+ data = client.jobs.search(query, return_type=dict) # -> dict
242
+ job = client.jobs.get(job_id, return_type=dict) # -> dict
243
+ ```
244
+
245
+ ## Errors
246
+
247
+ All errors subclass `hirebase.HirebaseError`:
248
+
249
+ | Exception | Meaning |
250
+ |---|---|
251
+ | `ConfigurationError` | No API key / bad config |
252
+ | `AuthenticationError` | 401 — invalid API key |
253
+ | `PaymentRequiredError` | 402 — plan/credits required |
254
+ | `PermissionError_` | 403 — not allowed |
255
+ | `NotFoundError` | 404 |
256
+ | `RateLimitError` | 429 |
257
+ | `ServerError` | 5xx |
258
+ | `APIError` | any other non-2xx (`.status_code`, `.message`, `.body`) |
259
+ | `TaskFailed` / `TaskTimeout` | export task failed or timed out |
260
+
261
+ ```python
262
+ import hirebase
263
+
264
+ try:
265
+ client.jobs.search(query)
266
+ except hirebase.RateLimitError:
267
+ ...
268
+ except hirebase.APIError as e:
269
+ print(e.status_code, e.message)
270
+ ```
271
+
272
+ ## Development
273
+
274
+ ```bash
275
+ pip install -e ".[dev]"
276
+
277
+ # Offline unit tests (no network)
278
+ pytest
279
+
280
+ # Live integration tests against the real API
281
+ HIREBASE_API_KEY=sk_live_... pytest tests/test_integration.py -v
282
+ ```
283
+
284
+ > If your environment preloads conflicting pytest plugins, run with
285
+ > `PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest`.
286
+
287
+ ## License
288
+
289
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,250 @@
1
+ <div align="left" style="margin-bottom: 16px;">
2
+ <img src="https://www.hirebase.org/hirebase-logo-text.svg" alt="Hirebase Logo" width="160" style="vertical-align: middle; margin-bottom: 8px;" />
3
+ <div style="margin-top: 12px; display: flex; gap: 12px;">
4
+ <a href="https://www.hirebase.org/" style="text-decoration:none;">
5
+ <img src="https://img.shields.io/badge/Website-hirebase.org-blue?style=for-the-badge&logo=Google%20chrome&logoColor=white" alt="Website" />
6
+ </a>
7
+ <a href="https://app.hirebase.org/login" style="text-decoration:none;">
8
+ <img src="https://img.shields.io/badge/Login-Login-green?style=for-the-badge&logo=google&logoColor=white" alt="Login" />
9
+ </a>
10
+ <a href="https://app.hirebase.org/signup" style="text-decoration:none;">
11
+ <img src="https://img.shields.io/badge/Sign%20Up-Create%20Account-purple?style=for-the-badge&logo=addthis&logoColor=white" alt="Sign Up" />
12
+ </a>
13
+ </div>
14
+ </div>
15
+ <div>
16
+ <span style="font-size:2.4rem;font-weight:600;">hirebase-python-sdk</span>
17
+ </div>
18
+ A lean, typed Python client for the [Hirebase API](https://docs.hirebase.org/) —
19
+ search jobs and companies, run market insights, and export job data at scale.
20
+
21
+ - **Sync and async** clients (`hirebase.Client` / `hirebase.AsyncClient`).
22
+ - **Typed by default** — responses come back as Pydantic models; pass
23
+ `return_type=dict` anywhere for raw dicts.
24
+ - **Streaming exports** — kick off an export, poll it, download it, and stream
25
+ millions of jobs without loading them into memory.
26
+ - **Self-contained** — the SDK ships its own types and depends only on
27
+ `requests`, `httpx`, and `pydantic`.
28
+
29
+ > **Guides:** [Getting started](./docs/README.md) ·
30
+ > [Jobs](./docs/jobs.md) · [Companies](./docs/companies.md) ·
31
+ > [Resumes](./docs/resumes.md) · [Tasks](./docs/tasks.md) · [Errors](./docs/errors.md) ·
32
+ > [Examples](./examples/README.md)
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install hirebase
38
+
39
+ # Optional extras
40
+ pip install "hirebase[streaming]" # ijson, for streaming JSON-array exports
41
+ pip install "hirebase[cli]" # the bundled `hirebase` command-line tool
42
+ ```
43
+
44
+ ## Authentication
45
+
46
+ Pass your API key directly, or set it via the environment:
47
+
48
+ ```python
49
+ import hirebase
50
+ client = hirebase.Client(api_key="sk_live_...")
51
+ ```
52
+
53
+ ```bash
54
+ export HIREBASE_API_KEY="sk_live_..."
55
+ export HIREBASE_BASE_URL="https://api.hirebase.org" # optional, this is the default
56
+ ```
57
+
58
+ Resolution order for every setting is **argument → environment variable →
59
+ default**. The base URL defaults to `https://api.hirebase.org`.
60
+
61
+ ## Quickstart
62
+
63
+ ```python
64
+ import hirebase
65
+
66
+ client = hirebase.Client(api_key="sk_live_...")
67
+
68
+ # Search jobs — results are typed and iterable
69
+ result = client.jobs.search({
70
+ "job_titles": ["Software Engineer", "Product Engineer"],
71
+ "locations": [{"city": "San Francisco", "region": "California",
72
+ "country": "United States"}],
73
+ "limit": 20,
74
+ })
75
+
76
+ print(result.total_count, "matches")
77
+ for job in result:
78
+ print(job.job_title, "@", job.company_name, "—", job.salary_range)
79
+ ```
80
+
81
+ Booleans are accepted natively (`visa=True`), and `locations` is a friendly
82
+ alias for the API's `geo_locations`. Unknown filter keys are passed through
83
+ untouched, so new API features work before the SDK is updated.
84
+
85
+ ### Async
86
+
87
+ ```python
88
+ import asyncio, hirebase
89
+
90
+ async def main():
91
+ async with hirebase.AsyncClient(api_key="sk_live_...") as client:
92
+ result = await client.jobs.search({"job_titles": ["Engineer"]})
93
+ for job in result:
94
+ print(job.job_title)
95
+
96
+ asyncio.run(main())
97
+ ```
98
+
99
+ Every method has the same signature on both clients — the async versions are
100
+ awaitable.
101
+
102
+ ## Jobs
103
+
104
+ ```python
105
+ # Search
106
+ result = client.jobs.search(query, page=1, limit=20)
107
+
108
+ # Fetch one job
109
+ job = client.jobs.get("6958cfd211e2763c3491ef8b")
110
+
111
+ # Market insights for a cohort (same filter shape as search)
112
+ insights = client.jobs.insights({"job_titles": ["Data Scientist"]})
113
+ print(insights.headline.median_salary, insights.salary.p90)
114
+ ```
115
+
116
+ ### Typed inputs
117
+
118
+ You can pass a plain `dict` or build a typed query:
119
+
120
+ ```python
121
+ from hirebase import JobQuery, SalaryRange
122
+
123
+ query = JobQuery(
124
+ job_titles=["Backend Engineer"],
125
+ salary=SalaryRange(min=150_000, currency="USD"),
126
+ location_types=["Remote"],
127
+ visa=True,
128
+ )
129
+ result = client.jobs.search(query)
130
+ ```
131
+
132
+ ## Exporting jobs (async task flow)
133
+
134
+ Exports are processed server-side and returned as a downloadable file.
135
+
136
+ ```python
137
+ query = {
138
+ "job_titles": ["Software Engineer", "Product Engineer", "Fullstack Engineer"],
139
+ "locations": [{"city": "San Francisco", "region": "California",
140
+ "country": "United States"}],
141
+ }
142
+
143
+ # 1. Start the export -> returns a Task
144
+ task = client.jobs.export(query, format="json") # or format="csv"
145
+
146
+ # 2. Poll until it finishes -> (success, result)
147
+ success, result = client.tasks.poll(task)
148
+ if not success:
149
+ raise RuntimeError(f"Export failed: {result.error}")
150
+
151
+ # 3. Download the file (streamed to disk)
152
+ client.stream_file(result["download_url"], file_path="./jobs.json")
153
+
154
+ # 4. Stream jobs from the file (typed by default; uses constant memory)
155
+ for job in client.jobs.stream_file("./jobs.json"):
156
+ print(job.job_title)
157
+
158
+ # ...or get raw dicts
159
+ for row in client.jobs.stream_file("./jobs.json", return_type=dict):
160
+ ...
161
+ ```
162
+
163
+ `poll()` accepts a `Task`, a task dict, or a task id, plus `interval`,
164
+ `timeout`, and an `on_progress` callback. The result dict contains
165
+ `download_url`, `file_size`, `record_count`, and `expiry_time`.
166
+
167
+ You can also stream **directly from the export URL** without saving to disk
168
+ (JSON Lines exports only):
169
+
170
+ ```python
171
+ for job in client.jobs.stream_url(result["download_url"]):
172
+ print(job.job_title)
173
+ ```
174
+
175
+ ## Companies
176
+
177
+ ```python
178
+ # Search
179
+ companies = client.companies.search({"company_name": "Stripe"})
180
+ for company in companies:
181
+ print(company.company_name, company.company_slug)
182
+
183
+ # Get a company by slug — optionally with its jobs and live insights
184
+ company = client.companies.get("stripe", return_jobs=True, return_insights=True)
185
+ print(company.description_summary)
186
+ print(company.insights_data.headline.total_count)
187
+
188
+ # Bound helpers (the object remembers its client)
189
+ insights = company.insights()
190
+ jobs = company.get_jobs(limit=10)
191
+
192
+ # Company-scoped insights directly
193
+ insights = client.companies.insights("stripe", query={"days_ago": 30})
194
+ ```
195
+
196
+ ## Typed vs. dict responses
197
+
198
+ Every method returns typed models by default. Pass `return_type=dict` to get
199
+ the raw API payload instead:
200
+
201
+ ```python
202
+ data = client.jobs.search(query, return_type=dict) # -> dict
203
+ job = client.jobs.get(job_id, return_type=dict) # -> dict
204
+ ```
205
+
206
+ ## Errors
207
+
208
+ All errors subclass `hirebase.HirebaseError`:
209
+
210
+ | Exception | Meaning |
211
+ |---|---|
212
+ | `ConfigurationError` | No API key / bad config |
213
+ | `AuthenticationError` | 401 — invalid API key |
214
+ | `PaymentRequiredError` | 402 — plan/credits required |
215
+ | `PermissionError_` | 403 — not allowed |
216
+ | `NotFoundError` | 404 |
217
+ | `RateLimitError` | 429 |
218
+ | `ServerError` | 5xx |
219
+ | `APIError` | any other non-2xx (`.status_code`, `.message`, `.body`) |
220
+ | `TaskFailed` / `TaskTimeout` | export task failed or timed out |
221
+
222
+ ```python
223
+ import hirebase
224
+
225
+ try:
226
+ client.jobs.search(query)
227
+ except hirebase.RateLimitError:
228
+ ...
229
+ except hirebase.APIError as e:
230
+ print(e.status_code, e.message)
231
+ ```
232
+
233
+ ## Development
234
+
235
+ ```bash
236
+ pip install -e ".[dev]"
237
+
238
+ # Offline unit tests (no network)
239
+ pytest
240
+
241
+ # Live integration tests against the real API
242
+ HIREBASE_API_KEY=sk_live_... pytest tests/test_integration.py -v
243
+ ```
244
+
245
+ > If your environment preloads conflicting pytest plugins, run with
246
+ > `PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest`.
247
+
248
+ ## License
249
+
250
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,74 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "hirebase"
7
+ version = "0.1.1"
8
+ description = "Official Python SDK for the Hirebase API (jobs & company data)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "Hirebase", email = "spencer@hirebase.org"}
14
+ ]
15
+ keywords = ["hirebase", "jobs", "hiring", "api", "sdk", "company data"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ ]
27
+ # Core runtime deps. requests powers the sync client, httpx the async client;
28
+ # both are widely installed and kept as hard deps so both clients work out of
29
+ # the box. pydantic provides the typed models.
30
+ dependencies = [
31
+ "requests>=2.28.0",
32
+ "httpx>=0.25.0",
33
+ "pydantic>=2.0.0",
34
+ "python-dotenv>=1.0.0",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ # Streaming very large JSON-array exports memory-efficiently.
39
+ streaming = [
40
+ "ijson>=3.2.0",
41
+ ]
42
+ # The bundled command-line interface.
43
+ cli = [
44
+ "typer>=0.9.0",
45
+ "rich>=13.0.0",
46
+ ]
47
+ dev = [
48
+ "pytest>=7.0.0",
49
+ "pytest-asyncio>=0.21.0",
50
+ "ijson>=3.2.0",
51
+ "typer>=0.9.0",
52
+ "rich>=13.0.0",
53
+ ]
54
+
55
+ [project.scripts]
56
+ hirebase = "hirebase_cli.main:app"
57
+
58
+ [project.urls]
59
+ Homepage = "https://hirebase.org"
60
+ Documentation = "https://docs.hirebase.org"
61
+ Repository = "https://github.com/hirebase/hirebase-python-sdk"
62
+
63
+ [tool.pytest.ini_options]
64
+ testpaths = ["tests"]
65
+
66
+ [tool.setuptools.packages.find]
67
+ where = ["src"]
68
+ include = ["hirebase*", "hirebase_cli*"]
69
+
70
+ [tool.setuptools.package-dir]
71
+ "" = "src"
72
+
73
+ [tool.setuptools.package-data]
74
+ hirebase = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+