Skip to content

Commit faf9437

Browse files
karlwaldmanclaude
andcommitted
docs: embedder-segment quick start + fix weekly-health workflow (#44)
README: add 'Beyond Oil — Gas, LNG, Carbon & Fuels' right after the first quick-start example — EU_CARBON_EUR spot, ttf-gas futures curve, RTM bunker port prices — naming the maritime-compliance (EU ETS/FuelEU), fleet/logistics, LNG/European-gas and CBAM audiences. All calls verified against the real resource signatures (prices.get, futures.latest slug helpers, bunker_fuels.port with 3-letter port codes per the API route constraint). weekly-health.yml repair (failed every scheduled run through 2026-06-01, then GitHub disabled the schedule for inactivity): - historical failure: 'pytest: error: unrecognized arguments: --timeout=60' (pytest-timeout missing; since added to [dev] by #29) - add --no-cov: marker-filtered runs can never meet the global --cov-fail-under=50 addopts gate (same reason live-tests.yml uses it) - shell-level [ -z "$OILPRICEAPI_KEY" ] guard with ::warning:: — the OILPRICEAPI_TEST_KEY secret currently resolves EMPTY at runtime - conftests: fall back to os.environ for OILPRICEAPI_KEY (they only read a .env file, so CI could never use the secret) and make the contract conftest's dotenv import optional (python-dotenv isn't a dev dependency, collection crashed without it) Verified locally: unit suite 303 passed / 10 skipped; both exact CI commands exit 0 with no key (18/22 skipped); workflow YAML parses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent b699a65 commit faf9437

4 files changed

Lines changed: 55 additions & 9 deletions

File tree

.github/workflows/weekly-health.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,24 @@ jobs:
2525
python -m pip install --upgrade pip
2626
pip install -e '.[dev]'
2727
28+
# OILPRICEAPI_TEST_KEY currently resolves empty at runtime (see PR).
29+
# Guard at the shell level so the job passes loudly (::warning::) instead
30+
# of failing or silently skipping every test.
2831
- name: Run integration tests
29-
run: pytest tests/ -m 'integration' -v --timeout=60
32+
run: |
33+
if [ -z "$OILPRICEAPI_KEY" ]; then
34+
echo "::warning::OILPRICEAPI_TEST_KEY secret is empty/unset - live integration tests skipped"
35+
exit 0
36+
fi
37+
pytest tests/ -m 'integration' -v --no-cov --timeout=60
3038
3139
- name: Run contract tests
32-
run: pytest tests/ -m 'contract' -v --timeout=60
40+
run: |
41+
if [ -z "$OILPRICEAPI_KEY" ]; then
42+
echo "::warning::OILPRICEAPI_TEST_KEY secret is empty/unset - contract tests skipped"
43+
exit 0
44+
fi
45+
pytest tests/ -m 'contract' -v --no-cov --timeout=60
3346
3447
- name: Check for dependency vulnerabilities
3548
run: |

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,28 @@ for price in prices:
4848
print(f"{price.commodity}: ${price.value:.2f}")
4949
```
5050

51+
### Beyond Oil — Gas, LNG, Carbon & Fuels
52+
53+
The same client covers EU ETS carbon, European gas (TTF), LNG (JKM), and marine/road/aviation fuels — for maritime compliance (EU ETS / FuelEU Maritime), fleet & logistics fuel costing, LNG and European gas analytics, and CBAM reporting.
54+
55+
```python
56+
# EU ETS carbon allowances (EUAs) — spot price in EUR
57+
eua = client.prices.get("EU_CARBON_EUR")
58+
print(f"EU carbon: €{eua.value:.2f}") # €XX.XX per tonne CO2
59+
60+
# Dutch TTF natural gas — futures curve via slug helpers
61+
# (other slugs: "lng-jkm", "eua-carbon", "uk-carbon", "natural-gas")
62+
ttf = client.futures.latest("ttf-gas")
63+
print(ttf["front_month"]["last_price"]) # front-month, €XX.XX/MWh
64+
65+
# Marine bunker fuels (VLSFO / MGO / IFO380) at a specific port
66+
rotterdam = client.bunker_fuels.port("RTM") # 3-letter port codes: SIN, RTM, FUJ, ...
67+
for fuel in rotterdam["prices"]:
68+
print(f"{fuel['grade']}: ${fuel['price']}/{fuel['unit']}") # VLSFO: $XXX.XX/MT
69+
```
70+
71+
Spot codes for these markets also work with `client.prices.get()` / `get_multiple()`: `DUTCH_TTF_EUR`, `JKM_LNG_USD`, `VLSFO_USD`, `JET_FUEL_USD`, `DIESEL_USD`, `NATURAL_GAS_USD`. (Futures and bunker endpoints require a plan with futures data — spot prices work on every tier.)
72+
5173
### Historical Data with Pandas
5274

5375
```python

tests/contract/conftest.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55
import os
66
import pytest
77
from pathlib import Path
8-
from dotenv import dotenv_values
8+
try:
9+
from dotenv import dotenv_values
10+
except ImportError:
11+
# python-dotenv is optional (not in the [dev] extra). In CI the API key
12+
# comes from the environment, so don't make the contract suite
13+
# uncollectable when dotenv isn't installed.
14+
def dotenv_values(_path): # type: ignore[misc]
15+
return {}
916
from oilpriceapi import OilPriceAPI
1017

1118
# Load .env file from project root
@@ -16,15 +23,17 @@
1623
env_vars = dotenv_values(env_path)
1724

1825
# Get API credentials
19-
API_KEY = env_vars.get('OILPRICEAPI_KEY')
20-
BASE_URL = env_vars.get('OILPRICEAPI_BASE_URL', 'https://api.oilpriceapi.com')
26+
# Prefer .env for local dev, fall back to the environment for CI
27+
# (weekly-health.yml sets OILPRICEAPI_KEY from the OILPRICEAPI_TEST_KEY secret).
28+
API_KEY = env_vars.get('OILPRICEAPI_KEY') or os.environ.get('OILPRICEAPI_KEY')
29+
BASE_URL = env_vars.get('OILPRICEAPI_BASE_URL') or os.environ.get('OILPRICEAPI_BASE_URL', 'https://api.oilpriceapi.com')
2130

2231

2332
@pytest.fixture(scope="session")
2433
def api_key():
2534
"""Provide API key for tests."""
2635
if not API_KEY:
27-
pytest.skip("OILPRICEAPI_KEY not found in .env file")
36+
pytest.skip("OILPRICEAPI_KEY not found in .env file or environment")
2837
return API_KEY
2938

3039

tests/integration/conftest.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ def dotenv_values(_path): # type: ignore[misc]
2626
env_vars = dotenv_values(env_path)
2727

2828
# Get API credentials
29-
API_KEY = env_vars.get('OILPRICEAPI_KEY')
30-
BASE_URL = env_vars.get('OILPRICEAPI_BASE_URL', 'https://api.oilpriceapi.com')
29+
# Prefer .env for local dev, fall back to the environment for CI
30+
# (weekly-health.yml sets OILPRICEAPI_KEY from the OILPRICEAPI_TEST_KEY secret).
31+
API_KEY = env_vars.get('OILPRICEAPI_KEY') or os.environ.get('OILPRICEAPI_KEY')
32+
BASE_URL = env_vars.get('OILPRICEAPI_BASE_URL') or os.environ.get('OILPRICEAPI_BASE_URL', 'https://api.oilpriceapi.com')
3133

3234
# CI shares a single 1-request/second API key across repositories, so live
3335
# tests can collide and get HTTP 429 (RateLimitError) through no fault of the
@@ -52,7 +54,7 @@ def _throttle_live_calls():
5254
def api_key():
5355
"""Provide API key for tests."""
5456
if not API_KEY:
55-
pytest.skip("OILPRICEAPI_KEY not found in .env file")
57+
pytest.skip("OILPRICEAPI_KEY not found in .env file or environment")
5658
return API_KEY
5759

5860

0 commit comments

Comments
 (0)