Skip to content

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: the veriportali cookie 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 as dataflow, istab, database, press, or report; relative URLs are absolutized and SDMX dataflow IDs extracted. Unknown theme IDs raise with the full id = name catalog, as tuikr does.
  • SDMX — get_data returns the tidy long frame tuikr produces: trimmed strings, invariant dimensions dropped, {DIM}_label columns inserted only when labels differ from codes, obsTime/obsValue last, obsValue as float. start, end, key, detail, and dimension_at_observation are all exposed.
  • get_data_structure — public, unlike in tuikr: returns the frozen DataflowStructure (dimensions in key order, code→label maps, time dimension) so a narrower key can be built when key="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 normalized YYYY-MM monthly dates and a slugified value column), and geo_map (NUTS-2/3, LAU-1, and settlement-point boundaries). geo_data auto-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 geo extra — geo_map(geometry=True) needs geopandas and says so clearly when it is missing; geometry=False works on a core install and never imports it.
  • Typed exception hierarchy — TuikError, TuikHTTPError, TuikPortalError, TuikSDMXError, and TuikValidationError (also a ValueError). Argument validation runs before any network I/O.
  • Typing — fully annotated, py.typed shipped, mypy --strict clean.
  • 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 geo extra; 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 behind get_data and get_data_structure) answers anonymous requests with 401 Unauthorized as of 2026-08-10; those calls raise TuikSDMXError explaining that access, not the request, is the problem. Access may be network-dependent. The statistical and geographic portals are unaffected.
  • geo_data supports 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 — the geo_data() split, the labels=False fast path, the public get_data_structure(), and the get_ prefixes — are documented with their reasons in DESIGN.md §4.2.
  • sdmx1 parses the SDMX structure message; the generic data message is parsed with lxml, because sdmx1 cannot read one without a DSD.