Python SDK
The official Qudra SDK for Python 3.9+. Built on httpx, with typed dataclasses and constant-time webhook verification.
Install
pip install qudra
# or
poetry add qudraQuick start
from qudra import Client
qudra = Client(api_key="qk_live_…") # or sandbox=True
job = qudra.jobs.create(
title="Senior Backend Engineer",
description="Build the Qudra matching pipeline.",
city="Riyadh",
employment_type="full_time",
salary_min=18000,
salary_max=30000,
currency="SAR",
)
print(job["qudra_url"])Configuration
Client(
api_key="qk_live_…", # required
sandbox=False, # optional
base_url="https://api.qudrah.io/v1", # optional override
timeout=30.0, # seconds
)Jobs
# Create
job = qudra.jobs.create(title="…", city="Riyadh", employment_type="full_time",
salary_min=15000, salary_max=22000)
# List (auto-pagination)
for job in qudra.jobs.list(status="active"):
print(job["id"], job["title"])
# Retrieve / Update / Delete
job = qudra.jobs.retrieve("job_01HXY…")
qudra.jobs.update("job_01HXY…", status="paused")
qudra.jobs.delete("job_01HXY…")
# Bulk
result = qudra.jobs.bulk_create(jobs=[
{"title": "Backend", "city": "Riyadh", "employment_type": "full_time", "salary_min": 15000, "salary_max": 22000},
{"title": "Frontend", "city": "Jeddah", "employment_type": "full_time", "salary_min": 14000, "salary_max": 20000},
])
print(len(result["created"]), "jobs created")Webhooks
# Register
wh = qudra.webhooks.register(
url="https://your-app.example.com/webhooks/qudra",
events=["job.created", "job.matched"],
)
print("Save this secret:", wh["secret"])
# Verify in a Flask handler
from flask import Flask, request, abort
app = Flask(__name__)
@app.post("/webhooks/qudra")
def handle_qudra():
raw = request.get_data()
if not qudra.webhooks.verify(raw, request.headers["X-Qudra-Signature"], WEBHOOK_SECRET):
abort(401)
event = request.get_json()
# …handle event…
return "", 200qudra.webhooks.verify uses hmac.compare_digest internally for constant-time comparison.
Error handling
from qudra import Client, QudraError
try:
qudra.jobs.create(title="", city="Riyadh")
except QudraError as e:
print(e.code) # 'partner.validation_error'
print(e.message) # English
print(e.message_ar) # Arabic
print(e.fields) # {'title': 'must be a non-empty string'}
print(e.request_id) # 'req_01HXY…'Async usage
For high-throughput pipelines, use the async client:
import asyncio
from qudra import AsyncClient
async def main():
async with AsyncClient(api_key="qk_live_…") as qudra:
job = await qudra.jobs.create(title="…", city="Riyadh", employment_type="full_time",
salary_min=15000, salary_max=22000)
print(job["id"])
asyncio.run(main())