feat: OSCBR token support, Cosmos out of the active chain, quota-safe OSCBR backfill (dry-run selection), provider env passthrough; 1.3.3 (Hub only)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-26 10:04:51 -03:00
co-authored by Claude Sonnet 5
parent ac1ecccc50
commit 1e4a31ea88
24 changed files with 299 additions and 29 deletions
+7 -3
View File
@@ -235,15 +235,17 @@ class Oscbr(Provider):
base = "https://gtin.rscsistemas.com.br"
def __init__(self, client=None, token=None, user=None, password=None):
super().__init__(client, token)
super().__init__(client, token) # token = a ready Bearer token (OSCBR_TOKEN); preferred over storing the login
self._user, self._password = user, password
self._bearer, self._bearer_until = None, 0.0
@property
def configured(self) -> bool:
return bool(self._user and self._password)
return bool(self._token or (self._user and self._password))
def _auth(self) -> str:
if self._token:
return self._token
if self._bearer and time.time() < self._bearer_until:
return self._bearer
try:
@@ -322,7 +324,9 @@ class Kodebar(Provider):
def build_providers(settings, client: httpx.Client | None = None) -> list[Provider]:
"""Fixed order chosen from the benchmark (docs/product_enrichment.md): Cosmos then OSCBR (fiscal-capable) first when configured, then UPCitemdb, then the Open *Facts family (food, general products, beauty; identity only). Paid providers do not exist here."""
providers: list[Provider] = [Cosmos(client, getattr(settings, "cosmos_token", None)), Oscbr(client, None, getattr(settings, "oscbr_user", None), getattr(settings, "oscbr_password", None)), Kodebar(client, getattr(settings, "kodebar_api_key", None)), UpcItemDb(client), OpenFoodFacts(client), OpenProductsFacts(client), OpenBeautyFacts(client)]
providers: list[Provider] = [Oscbr(client, getattr(settings, "oscbr_token", None), getattr(settings, "oscbr_user", None), getattr(settings, "oscbr_password", None)), Kodebar(client, getattr(settings, "kodebar_api_key", None)), UpcItemDb(client), OpenFoodFacts(client), OpenProductsFacts(client), OpenBeautyFacts(client)]
if getattr(settings, "cosmos_enabled", False): # Cosmos is OFF by default (account unavailable); only an explicit COSMOS_ENABLED=1 puts it back in the chain
providers.insert(0, Cosmos(client, getattr(settings, "cosmos_token", None)))
if any(p.paid for p in providers) and not getattr(settings, "allow_paid_providers", False):
raise RuntimeError("paid providers are not allowed (ALLOW_PAID_PROVIDERS=false)")
return providers