Skip to main content

Synchronous, typed HeadHunter (hh.uz / hh.ru) API client with safe token handling and Django integration.

Project description

hh-api-client

Synchronous, typed HeadHunter (hh.uz / hh.ru) API client with safe token handling and first‑class Django support.

Short overview (EN)

  • Lightweight client on top of requests (no async, no heavy deps).
  • Works with both raw OAuth2 access tokens and pluggable token providers.
  • Designed to integrate cleanly with Django models like OrganizationHHAccount.
  • Helpful high‑level methods for vacancies, resumes, negotiations, and employer metadata.

Кратко по‑русски (RU)
hh-api-client — это простой синхронный Python‑клиент для HeadHunter (hh.uz / hh.ru) на базе requests,
который безопасно работает с OAuth2‑токенами и легко встраивается в Django‑проекты.

Qisqacha tavsif (UZ)
hh-api-client — bu HeadHunter (hh.uz / hh.ru) bilan ishlash uchun requests asosida yozilgan oddiy va ishonchli Python kliеnti.
Django loyihalaringizda HH hisoblari va tokenlarini boshqarish uchun qulay.

Requirements

  • Python 3.9+
  • requests>=2.31.0 (installed automatically with pip install hh-api-client)
  • Optional: django>=3.2 if you want to use the Django integration pattern

Installation

pip install hh-api-client

From a Git repository (for example, the main GitHub repo):

pip install git+https://github.com/your-username/hh-api-client.git

For local development:

pip install -e .

Quick start

from hh_api_client import HHAPIClient

client = HHAPIClient(access_token="YOUR_HH_ACCESS_TOKEN")

employer = client.get_employer_info()
print(employer["id"], employer["name"])

With a token provider (recommended)

You can pass any object that implements:

  • get_valid_access_token() -> str
  • refresh_access_token() -> str

This matches your existing OrganizationHHAccount pattern.

from hh_api_client import HHAPIClient

client = HHAPIClient(organization_hh_account=my_hh_account_instance)

# Example: create vacancy
vacancy_data = {
    "name": "Python Developer",
    "description": "<p>We are looking for a Python developer...</p>",
    "area": {"id": "2759"},  # e.g. Tashkent
    "employment": {"id": "full"},
    "schedule": {"id": "fullDay"},
}

response = client.create_vacancy(vacancy_data)
print(response["id"])

Django integration example

Assuming you have a model like OrganizationHHAccount with methods:

  • get_valid_access_token()
  • refresh_access_token()

and you store it per organization:

from hh_api_client import HHAPIClient
from organization_app.models import OrganizationHHAccount


def get_hh_client_for_organization(organization) -> HHAPIClient:
    hh_account = OrganizationHHAccount.objects.get(organization=organization, archived=False)
    return HHAPIClient(organization_hh_account=hh_account)

Configuring base URL (hh.uz vs hh.ru)

By default this client uses the Uzbekistan API base URL https://api.hh.uz because that is a common production setup.

If you need to change it (for example to https://api.hh.ru), use HHAPIClientConfig:

from django.conf import settings
from hh_api_client import HHAPIClient, HHAPIClientConfig
from organization_app.models import OrganizationHHAccount


def get_hh_client_for_organization(organization) -> HHAPIClient:
    hh_account = OrganizationHHAccount.objects.get(organization=organization, archived=False)
    config = HHAPIClientConfig(base_url=getattr(settings, "HH_API_BASE_URL", "https://api.hh.uz"))
    return HHAPIClient(organization_hh_account=hh_account, config=config)

You can wire it to your existing settings:

# settings/base.py
HH_CLIENT_ID = env.str("HH_CLIENT_ID", default="")
HH_CLIENT_SECRET = env.str("HH_CLIENT_SECRET", default="")
HH_REDIRECT_URI = env.str("HH_REDIRECT_URI", default="")
HH_API_BASE_URL = "https://api.hh.uz"  # or api.hh.ru
HH_OAUTH_BASE_URL = "https://hh.uz"

Then your existing usage in signal handlers and DRF views can stay almost the same, just update the import:

from hh_api_client import HHAPIClient

Safety and error handling

  • No secrets (tokens) are ever logged.
  • Network errors raise requests.RequestException.
  • API-level errors raise hh_api_client.HHAPIError with a sanitized message.
  • Automatic token refresh is attempted once on 401 responses when a token provider is used.

Endpoints covered

High-level helpers currently implemented:

  • get_user_info()
  • get_employer_info()
  • get_managers()
  • get_default_manager_id()
  • get_employer_services()
  • get_publication_status()
  • test_connection()

Vacancies:

  • create_vacancy()
  • update_vacancy()
  • archive_vacancy()
  • publish_vacancy()
  • extend_vacancy()
  • get_vacancy()
  • get_vacancies()

Resumes:

  • search_resumes()
  • get_resume()

Negotiations:

  • get_negotiations()
  • get_vacancy_candidates()

Releasing (for maintainers)

This project is configured to publish using GitHub Actions and PyPI's OpenID Connect (OIDC) publisher.

  • A GitHub Actions workflow lives at .github/workflows/workflow.yml.
  • When you push a tag like v0.1.0 to the hh-api-client repository on GitHub, the workflow:
    • Builds the package with python -m build.
    • Publishes the distributions to TestPyPI (environment testpypi).
    • Then publishes the same build to PyPI (environment pypi).

To cut a new release:

  1. Bump the version in pyproject.toml.

  2. Commit and push to main.

  3. Create and push a tag, e.g.:

    git tag v0.1.2
    git push origin v0.1.2
    
  4. Wait for the GitHub Actions workflow to complete; the new version will appear on both TestPyPI and PyPI (assuming both publishers are configured).

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

hh_api_client-0.1.6.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

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

hh_api_client-0.1.6-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

Details for the file hh_api_client-0.1.6.tar.gz.

File metadata

  • Download URL: hh_api_client-0.1.6.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for hh_api_client-0.1.6.tar.gz
Algorithm Hash digest
SHA256 76b6ade6ff9700302a0716968337efdad4bec1e0688841196c9a4ca121583c31
MD5 c2f6538e17ba86c262e1ef3dc3f46073
BLAKE2b-256 050b7b3f136cfb7f42e6250c6a8af6532d1b9b86956b24d81f071d266b0f201d

See more details on using hashes here.

Provenance

The following attestation bundles were made for hh_api_client-0.1.6.tar.gz:

Publisher: workflow.yml on Firdavs0809/hh-api-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hh_api_client-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: hh_api_client-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 7.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for hh_api_client-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 db6eadebe49f3825f6a5c421a326b3eefade023966a6ffa32260e4ab1ee2b713
MD5 606975d0f04cc9aec36b5ba6900660ac
BLAKE2b-256 7435ba7ddb1ca708b200926e66d1d0eb5dce75ef3e3ab398c88f33be7234decb

See more details on using hashes here.

Provenance

The following attestation bundles were made for hh_api_client-0.1.6-py3-none-any.whl:

Publisher: workflow.yml on Firdavs0809/hh-api-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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