Changelog¶
All notable changes to this project are documented here.
The format follows Keep a Changelog, and
this project adheres to Semantic Versioning.
The public API is unstable until 1.0.
Unreleased¶
0.1.0 — 2026-08-10¶
First release. A faithful Python rewrite of the R package emraher/tuikr, covering all three public TUIK services.
Added¶
TuikClient— one reusable session for all three services: theveriportalicookie session dance, retries with exponential backoff on connect errors, timeouts and 5xx (never on 4xx), a TTL cache for the theme tree and the geographic catalog, configurable language, timeout, and User-Agent. Usable as a context manager.- Module-level façade —
pytuik.get_themes()and friends delegate to a lazily created, thread-safe default client;set_default_client()reconfigures it process-wide. - Statistical portal —
get_themes,get_resources,get_tables,get_databases. Resource leaves are classified asdataflow,istab,database,press, orreport; relative URLs are absolutized and SDMX dataflow IDs extracted. Unknown theme IDs raise with the fullid = namecatalog, astuikrdoes. - SDMX —
get_datareturns the tidy long frametuikrproduces: trimmed strings, invariant dimensions dropped,{DIM}_labelcolumns inserted only when labels differ from codes,obsTime/obsValuelast,obsValueas float.start,end,key,detail, anddimension_at_observationare all exposed. get_data_structure— public, unlike intuikr: returns the frozenDataflowStructure(dimensions in key order, code→label maps, time dimension) so a narrower key can be built whenkey="ALL"is rejected.labels=False— skips the structure request entirely, halving the requests needed for bulk pulls.drop_invariant=False— opts out of dropping single-valued dimensions.- Geographic portal —
geo_variables(indicator catalog),geo_data(long-form values with normalizedYYYY-MMmonthly dates and a slugified value column), andgeo_map(NUTS-2/3, LAU-1, and settlement-point boundaries).geo_dataauto-selects the level when a series has exactly one. - GeoJSON repair — TUIK ships
"type": ["FeatureCollection"], which is invalid GeoJSON; it is repaired on the parsed document (and on each feature) before geopandas sees it. - Optional
geoextra —geo_map(geometry=True)needs geopandas and says so clearly when it is missing;geometry=Falseworks on a core install and never imports it. - Typed exception hierarchy —
TuikError,TuikHTTPError,TuikPortalError,TuikSDMXError, andTuikValidationError(also aValueError). Argument validation runs before any network I/O. - Typing — fully annotated,
py.typedshipped,mypy --strictclean. - Docs — mkdocs-material site with statistical and geographic quickstarts and a generated API reference.
- CI — ruff, mypy, and pytest across Python 3.10/3.13 on Linux, macOS, and
Windows, with and without the
geoextra; a weekly live contract-test job as an upstream-drift alarm; tagged releases published to PyPI via trusted publishing.
Known issues¶
nsiws.tuik.gov.tr(the SDMX service behindget_dataandget_data_structure) answers anonymous requests with401 Unauthorizedas of 2026-08-10; those calls raiseTuikSDMXErrorexplaining that access, not the request, is the problem. Access may be network-dependent. The statistical and geographic portals are unaffected.geo_datasupports levels 2/3/4 only; a few indicators also advertise level 5, which has no boundary file to join against.
Notes¶
- Deliberate deviations from
tuikr— thegeo_data()split, thelabels=Falsefast path, the publicget_data_structure(), and theget_prefixes — are documented with their reasons inDESIGN.md§4.2. sdmx1parses the SDMX structure message; the generic data message is parsed withlxml, becausesdmx1cannot read one without a DSD.