diff --git a/CHANGELOG.md b/CHANGELOG.md index db8764d..4a68882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,38 @@ All notable changes to the OilPriceAPI Python SDK will be documented in this file. +## [1.13.0] - 2026-08-23 + +### Fixed + +- **`get_multiple()` now batches — up to 20 codes per request instead of one + request per code.** The REST API accepts 20 commodity codes in a single + request that counts **once** against quota, so the method whose purpose is + fetching several prices previously cost up to **20x more quota than writing + the call by hand**. Through it the free plan was 50 code-reads a day; through + the raw API it is 1,000. +- The same fix is applied to `AsyncPricesResource.get_multiple()`, which was + worse: `asyncio.gather` fanned out one request **per code** concurrently, + which could also trip the 60-per-60-second rate limit on a long list. Chunks + are still gathered concurrently, so 25 codes cost 2 requests rather than 25. + +### Changed + +- **Your quota consumption will drop.** This is in your favour and requires no + code change, but it is a behaviour change: a `get_multiple()` call that + previously consumed N requests now consumes `ceil(N / 20)`. +- The per-code failure contract is unchanged. Because the API rejects the whole + request when any code in it is unknown, a failed batch is retried per code — + for that chunk only — so `return_failures=True` still reports exactly which + code was at fault. + +### Documentation + +- Polling examples now default to an interval that fits the free plan + (30 minutes), with a plan/interval table and the measured update cadence of + the underlying data. Nothing we publish moves faster than about every + 2.5 minutes, so a shorter timer returns the same number. + ## [1.12.8] - 2026-08-12 ### Fixed diff --git a/oilpriceapi/version.py b/oilpriceapi/version.py index 3e3d79c..f5d9dd8 100644 --- a/oilpriceapi/version.py +++ b/oilpriceapi/version.py @@ -5,6 +5,6 @@ Used in __init__.py, client.py, and async_client.py. """ -__version__ = "1.12.8" +__version__ = "1.13.0" SDK_VERSION = __version__ SDK_NAME = "oilpriceapi-python" diff --git a/pyproject.toml b/pyproject.toml index 5e2b118..62fa9cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" [project] name = "oilpriceapi" -version = "1.12.8" +version = "1.13.0" description = "Official Python SDK for source-timestamped OilPriceAPI energy data" authors = [ {name = "OilPriceAPI", email = "support@oilpriceapi.com"} diff --git a/tests/test_release_readiness.py b/tests/test_release_readiness.py index dd12ef9..e1aa1ba 100644 --- a/tests/test_release_readiness.py +++ b/tests/test_release_readiness.py @@ -170,7 +170,13 @@ def test_package_version_helper_reads_the_project_version() -> None: capture_output=True, text=True, ) - assert result.stdout.strip() == "1.12.8" + # Read the expected value from pyproject rather than hard-coding it. The + # helper's job is "does it report the PROJECT version", not "is the version + # 1.12.8" — pinning the literal made this test fail on every release for a + # reason unrelated to what it guards. + pyproject = (ROOT / "pyproject.toml").read_text() + expected = re.search(r'^version = "([^"]+)"', pyproject, re.M).group(1) + assert result.stdout.strip() == expected def test_every_workflow_pins_actions_and_hardens_each_checkout_step() -> None: