Skip to content
theqiyas.cc
Problem Solver
cc · project · Open source

tap.az Python SDK

A typed Python client for tap.az. SMS code login, the category catalog with every property, ads, photos and the account's own ad list. Sync and async, never posts an ad twice.

$ pip install tapaz-python-sdk
Pydantic Python httpx

tap.az is the biggest classifieds site in Azerbaijan: flats, cars, phones, jobs, everything. This SDK lets a program post and manage ads there the way a person does on the website.

It is unofficial. It talks to the same GraphQL API, photo service and login service as the tap.az website, as one signed in account, with its own User-Agent and no proxies.

Sign in with an SMS code

tap.az signs in by phone only. The client asks for a 4 digit code, turns it into a session and gives you the cookie to keep, so the user does not need a new SMS on every run. Cloudflare cookies are dropped on the way in and out, and the session cookie is only ever sent to tap.az and its photo service.

The hard part: the form

Every tap.az category has its own form. An apartment wants rooms, area and a metro station. A car wants a make, a model and a year. Some fields only appear after another option is chosen.

The client loads the category and checks every value the way the tap.az form does before anything is sent: required properties, option ids, number ranges, fields that depend on other fields, and the rules for price, photos and title. Every problem comes back in one list. ads.validate() runs the same check without posting, which is handy while building a form of your own.

Because the same calls work for any category, the SDK is not only for real estate. Anything tap.az sells, it can post.

Managing ads

List ads by tab with cursors, read why one was rejected, update the text, price and photos, prolong it, and delete it with the reason tap.az asks for.

Never twice

When creating, updating, deleting or prolonging an ad times out, the client does not send it again. It raises OutcomeUnknownError so you look at the ad list first. Reads and photo uploads retry with backoff, since the worst a repeated upload can do is leave an unused photo. A Cloudflare challenge page raises BlockedError and is never solved.

Built with Python, httpx and Pydantic, sync and async, typed with mypy and covered by 44 tests. MIT licensed.