Skip to main content

The official Python SDK for the JobsPipe API - search live job postings and detect website tech stacks.

Project description

JobsPipe Python SDK

PyPI version Python versions License: MIT

The official Python library for the JobsPipe API.

Every job posting, one API. Search millions of live jobs from 30+ sources (LinkedIn, Y Combinator, company career pages, and more), normalized into one clean schema — plus website tech-stack detection.

  • Synchronous and asynchronous clients
  • Fully typed responses (pydantic models, ships py.typed)
  • Automatic retries with Retry-After support
  • Transparent offset pagination (client.jobs.iter(...))
  • A typed exception hierarchy you can branch on

Installation

pip install jobspipe

Requires Python 3.8+.

Authentication

Get an API key from your JobsPipe dashboard (it starts with jp_live_). Pass it directly or set the JOBSPIPE_API_KEY environment variable — the client reads it automatically.

export JOBSPIPE_API_KEY="jp_live_..."

Quickstart

from jobspipe import Jobspipe

client = Jobspipe()  # reads JOBSPIPE_API_KEY, or Jobspipe(api_key="jp_live_...")

results = client.jobs.search(
    description_or=["python", "django"],
    job_country_code_or=["US"],
    remote=True,
    posted_at_max_age_days=7,
    limit=25,
    include_total_results=True,
)

print(f"{results.metadata.total_results} matches")
for job in results.data:
    print(f"{job.job_title} @ {job.company} ({job.country_code}) — {job.url}")

Detect a website's tech stack

scan = client.stack.scan("stripe.com")
print(f"{scan.domain} scanned at {scan.scanned_at} (HTTP {scan.http_status})")
for tech in scan.detected:
    print(f"  {tech.name:20} {tech.confidence:>3.0f}%  {', '.join(tech.categories)}")

Pagination

client.jobs.iter(...) walks every page for you and yields individual jobs. It stops automatically when there are no more results, or when max_results is reached.

for job in client.jobs.iter(
    description_or=["rust"],
    remote=True,
    page_size=100,
    max_results=500,
):
    print(job.job_title, "-", job.company)

Prefer manual control? search() accepts offset/page and the response exposes metadata.next_cursor (which is None on the last page).

Async

Every method has an async counterpart on AsyncJobspipe:

import asyncio
from jobspipe import AsyncJobspipe

async def main():
    async with AsyncJobspipe() as client:
        results = await client.jobs.search(remote=True, limit=10)
        async for job in client.jobs.iter(description_or=["go"], max_results=50):
            print(job.job_title)

asyncio.run(main())

Error handling

All errors derive from jobspipe.JobspipeError. HTTP errors are APIStatusError subclasses carrying the status code, request id, and parsed body.

from jobspipe import (
    Jobspipe,
    AuthenticationError,
    PaymentRequiredError,
    RateLimitError,
    APIStatusError,
    APIConnectionError,
)

client = Jobspipe()
try:
    client.jobs.search(limit=10)
except AuthenticationError:
    print("Bad or missing API key")
except PaymentRequiredError:
    print("Monthly quota exceeded — upgrade your plan")
except RateLimitError as e:
    print(f"Rate limited; retry after {e.retry_after}s")
except APIStatusError as e:
    print(f"API error {e.status_code}: {e.message} (request {e.request_id})")
except APIConnectionError:
    print("Could not reach the API")
Exception When
BadRequestError 400 — malformed request / invalid domain
AuthenticationError 401 — missing or invalid API key
PaymentRequiredError 402 — monthly quota exceeded
NotFoundError 404 — resource not found
RateLimitError 429 — too many requests (.retry_after)
InternalServerError 5xx — server error / gateway timeout
APITimeoutError request timed out
APIConnectionError network failure

Retries & timeouts

Transient failures (429, 408, 409, 5xx, and network errors) are retried automatically with exponential backoff, honoring the server's Retry-After header. Configure per-client:

import httpx
from jobspipe import Jobspipe

client = Jobspipe(
    max_retries=4,                              # default 2
    timeout=httpx.Timeout(30.0, connect=5.0),   # default 60s
)

Configuration

Parameter Default Env var
api_key JOBSPIPE_API_KEY
base_url https://api.jobspipe.dev JOBSPIPE_BASE_URL
timeout 60s (10s connect)
max_retries 2
default_headers
http_client new httpx.Client

The response models allow extra fields, so new attributes added by the API are preserved (accessible via attribute or model_extra) without an SDK upgrade. Likewise, search() forwards any unknown keyword argument as a filter.

Development

pip install -e ".[dev]"
ruff check .
mypy src
pytest

The test suite mocks HTTP with respx — no network or API key required. Set JOBSPIPE_API_KEY to additionally run the live smoke test.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jobspipe-0.1.0.tar.gz (11.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jobspipe-0.1.0-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file jobspipe-0.1.0.tar.gz.

File metadata

  • Download URL: jobspipe-0.1.0.tar.gz
  • Upload date:
  • Size: 11.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for jobspipe-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0a561bad31bec5857a0f188d42ca0b9eadee56ea54f0adc8ea0842d717d3449a
MD5 b1372cf4e2056cefa7878091a7891986
BLAKE2b-256 848788e8bd8e722a9f5d40c1ca2a6387afda0c662faa495e711eea67a764edd4

See more details on using hashes here.

File details

Details for the file jobspipe-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: jobspipe-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for jobspipe-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fa0fab33f6ea6450cae1c57036f6e9055705a48ad837bc1f50b0a79b071316f7
MD5 d3fc0894aaa14839fceee71dc6763d48
BLAKE2b-256 d2b13fc7ddc033d5048f6c6d86e95eed24385b67becd389bc13ed04791d04244

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page