Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.12.3] - 2026-08-11

### Fixed

- Match hyphenated free-tier wording and universal catalog claims in every
readable wheel surface, and replace the remaining packaged docstrings with
current-account and runtime-response terminology.

## [1.12.2] - 2026-08-11

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ Ready to build with these examples?
## 📖 More Resources

- **[Complete API Documentation](https://docs.oilpriceapi.com)** - Full REST API reference
- **[Available Commodities](https://docs.oilpriceapi.com/commodities)** - List of all supported commodities
- **[Available Commodities](https://docs.oilpriceapi.com/commodities)** - Query the current commodity catalog
- **[GitHub Repository](https://github.com/oilpriceapi/python-sdk)** - Source code and issues
- **[Support](mailto:support@oilpriceapi.com)** - Get help from our team

Expand Down
4 changes: 2 additions & 2 deletions docs/DATAFRAMES.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ It accepts the same `per_page` range and automatically fetches every page.

## Current prices

Calling `client.prices.to_dataframe()` with no commodity returns all current
prices and automatically follows the API's pagination headers:
Calling `client.prices.to_dataframe()` with no commodity returns the current
price records available to the account and follows the API's pagination headers:

```python
df = client.prices.to_dataframe(per_page=250)
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ prices = client.prices.get_multiple([
])
```

**[View all available commodities →](https://docs.oilpriceapi.com/commodities)**
**[View the current commodity catalog →](https://docs.oilpriceapi.com/commodities)**

### Historical Data

Expand Down
2 changes: 1 addition & 1 deletion oilpriceapi/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ async def get_multiple(
return prices

async def get_all(self) -> List[Price]:
"""Get all available prices."""
"""Get price records available to the current account."""
response = await self.client.request(method="GET", path="/v1/prices/all")

if isinstance(response, dict) and "data" in response:
Expand Down
4 changes: 2 additions & 2 deletions oilpriceapi/resources/bunker_fuels.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ def __init__(self, client):
self.client = client

def all(self) -> List[Dict[str, Any]]:
"""Get all bunker fuel prices.
"""Get the available bunker fuel price records.

Returns:
List of bunker fuel prices across all ports
List of bunker fuel price records returned by the API

Example:
>>> bunker_prices = client.bunker_fuels.all()
Expand Down
2 changes: 1 addition & 1 deletion oilpriceapi/resources/commodities.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(self, client):
self.client = client

def list(self) -> List[Dict[str, Any]]:
"""Get list of all available commodities.
"""Get commodities available to the current account.

Returns:
List of commodity objects with code, name, and metadata
Expand Down
6 changes: 3 additions & 3 deletions oilpriceapi/resources/data_quality.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def summary(self) -> Dict[str, Any]:
"""Get data quality summary.

Returns:
Summary of data quality metrics across all commodities
Summary of data quality metrics returned by the API

Example:
>>> summary = client.data_quality.summary()
Expand All @@ -41,10 +41,10 @@ def summary(self) -> Dict[str, Any]:
return response

def reports(self) -> List[Dict[str, Any]]:
"""Get all data quality reports.
"""Get the available data quality reports.

Returns:
List of data quality reports for all commodities
List of data quality reports returned by the API

Example:
>>> reports = client.data_quality.reports()
Expand Down
10 changes: 5 additions & 5 deletions oilpriceapi/resources/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
Demo Resource

Public, no-authentication demo endpoints (``/v1/demo/*``). These power the
"time to first call" experience: a developer can fetch real free-tier prices
and the full commodity catalog without an API key.
"time to first call" experience: a developer can fetch the current demo price
set and catalog metadata without an API key.

The demo endpoints ignore authentication entirely, so :class:`DemoResource`
works both as an attribute of an authenticated client (``client.demo``) and
Expand Down Expand Up @@ -68,11 +68,11 @@ def _get(self, path: str) -> Dict[str, Any]:
return data

def prices(self, codes: Optional[List[str]] = None) -> Dict[str, Any]:
"""Get latest demo prices for free-tier commodities.
"""Get the latest price records currently exposed by the demo endpoint.

Args:
codes: Optional list of commodity codes to request. When omitted,
the API returns all free-tier commodities.
the API returns its current demo set.

Returns:
The ``data`` payload: ``{"prices": [...], "meta": {...}, "examples": {...}}``.
Expand All @@ -85,7 +85,7 @@ def prices(self, codes: Optional[List[str]] = None) -> Dict[str, Any]:
return data

def commodities(self) -> Dict[str, Any]:
"""Get the full demo commodity catalog grouped by category.
"""Get current demo commodity metadata grouped by category.

Returns:
The ``data`` payload: ``{"commodities": {category: [...]}, "meta": {...}}``.
Expand Down
8 changes: 4 additions & 4 deletions oilpriceapi/resources/prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,16 @@ def get_multiple(
return prices

def get_all(self, per_page: int = 100) -> List[Price]:
"""Get current prices for all available commodities.
"""Get current price records available to the account.

Auto-paginates using X-Has-Next response headers until all records
are retrieved.
Auto-paginates using X-Has-Next response headers until the API reports
no additional records.

Args:
per_page: Number of records per page (default 100, matches API default)

Returns:
List of Price objects for all commodities
List of Price objects returned for the current account

Example:
>>> all_prices = client.prices.get_all()
Expand Down
2 changes: 1 addition & 1 deletion oilpriceapi/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
Used in __init__.py, client.py, and async_client.py.
"""

__version__ = "1.12.2"
__version__ = "1.12.3"
SDK_VERSION = __version__
SDK_NAME = "oilpriceapi-python"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "oilpriceapi"
version = "1.12.2"
version = "1.12.3"
description = "Official Python SDK for source-timestamped OilPriceAPI energy data"
authors = [
{name = "OilPriceAPI", email = "support@oilpriceapi.com"}
Expand Down
6 changes: 3 additions & 3 deletions scripts/clean-wheel-smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
set -euo pipefail

root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
wheel="$(find "$root_dir/dist" -maxdepth 1 -name '*.whl' -print -quit)"
expected_version="$(
python -c '
import pathlib
Expand All @@ -16,9 +15,10 @@ if match is None:
print(match.group(1))
' "$root_dir/pyproject.toml"
)"
wheel="$root_dir/dist/oilpriceapi-${expected_version}-py3-none-any.whl"

if [[ -z "$wheel" ]]; then
echo "no wheel found under dist/" >&2
if [[ ! -f "$wheel" ]]; then
echo "exact wheel not found: $wheel" >&2
exit 1
fi

Expand Down
10 changes: 9 additions & 1 deletion scripts/validate_storefront_claims.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,18 @@
re.IGNORECASE,
),
),
(
"universal catalog",
re.compile(
r"\ball\s+(?:(?:available|latest|bunker|fuel|current|supported|free[- ]tier)\s+){0,4}"
r"(?:prices|commodities)\b|\bfull\s+(?:demo\s+)?commodity\s+catalog(?:ue)?\b",
re.IGNORECASE,
),
),
(
"free-tier claim",
re.compile(
r"\bfree\s+tier\b|\bfree\s+api\s+key\b|"
r"\bfree[- ]tier\b|\bfree[- ]api[- ]key\b|"
r"\b(?:endpoint|access)\s+is\s+free\b|\bincluded\s+in\s+all\s+tiers\b",
re.IGNORECASE,
),
Expand Down
2 changes: 2 additions & 0 deletions tests/test_release_readiness.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def test_publish_gate_audits_and_installs_the_built_wheel() -> None:
assert "continue-on-error: true" not in workflow
assert "from oilpriceapi.version import SDK_VERSION" not in smoke
assert "--package-root" in smoke
assert 'oilpriceapi-${expected_version}-py3-none-any.whl' in smoke
assert "-name '*.whl' -print -quit" not in smoke


def test_packaging_configuration_remains_compatible_with_supported_python() -> None:
Expand Down
11 changes: 9 additions & 2 deletions tests/test_storefront_claims.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def test_rejects_claim_in_future_installed_package_data(tmp_path: Path) -> None:
(package / "version.py").write_text('__version__ = "9.9.9"\n')
(package / "py.typed").write_text("")
(package / "types.pyi").write_text(
'"""Endpoint is free and included in all tiers. Available on paid tiers. '
'"""Free-tier access includes the full commodity catalog and all latest prices. '
'Endpoint is free and included in all tiers. Available on paid tiers. '
'Monthly station query limit applies."""\n'
)
(package / "docs" / "catalog.json").write_text(
Expand Down Expand Up @@ -89,7 +90,9 @@ def test_rejects_claim_in_future_installed_package_data(tmp_path: Path) -> None:
assert "oilpriceapi/docs/catalog.json" in surfaces
assert not any("__pycache__" in surface for surface in surfaces)
assert any(
"oilpriceapi/types.pyi" in failure and "free-tier claim" in failure
"oilpriceapi/types.pyi" in failure
and "free-tier claim" in failure
and "matched 'Free-tier'" in failure
for failure in failures
)
assert any(
Expand All @@ -100,4 +103,8 @@ def test_rejects_claim_in_future_installed_package_data(tmp_path: Path) -> None:
"oilpriceapi/types.pyi" in failure and "fixed allowance" in failure
for failure in failures
)
assert any(
"oilpriceapi/types.pyi" in failure and "universal catalog" in failure
for failure in failures
)
assert any("oilpriceapi/docs/catalog.json" in failure for failure in failures)