chore: redefined and connected pricers (#29)

This commit is contained in:
Daniel Alves Rösel
2025-11-29 17:44:51 +01:00
committed by GitHub
parent dd33f83e10
commit 2ed9057105
6 changed files with 212 additions and 40 deletions

View File

@@ -57,8 +57,9 @@ def get_price(mode: Literal['hotel', 'airline'], productId: str, sessionId: Opti
def __init__(self, backend_url: str):
SupabaseProvider.__init__(self)
BackendAPIProvider.__init__(self, backend_url=backend_url)
context = PipelineContext(
provider=Provider(backend_url=os.getenv("BACKEND_API_URL")),
provider=Provider(backend_url=os.getenv("BACKEND_URL")),
store_mode=mode
)
@@ -66,7 +67,6 @@ def get_price(mode: Literal['hotel', 'airline'], productId: str, sessionId: Opti
elasticity_df = registry.get_elasticity('latest')
if pricing_model is None or elasticity_df is None:
# fallback to base price if no model available
return PriceResponse(
productId=productId,
price=base_price,
@@ -75,7 +75,6 @@ def get_price(mode: Literal['hotel', 'airline'], productId: str, sessionId: Opti
elasticity=None
)
# build full state space for all products in catalog
products = context.products
if products.empty:
raise HTTPException(500, "No products available in catalog")
@@ -94,28 +93,66 @@ def get_price(mode: Literal['hotel', 'airline'], productId: str, sessionId: Opti
how='left'
).fillna({'elasticity': 0.0})
# use fitted pricer's mean_demand if available, else default to 10.0
# compute demand: use pricer's mean_demand if available, else default
demand_values = (pricing_model.mean_demand
if hasattr(pricing_model, 'mean_demand') and pricing_model.mean_demand is not None
else np.ones(len(merged)) * 10.0)
# build state space with session features if sessionId provided
session_features = pd.DataFrame()
if sessionId:
try:
# fetch recent session interactions from backend
from procesing.steps.session import ExtractSessionFeaturesStep
import requests
from datetime import datetime, timedelta
t_end = datetime.utcnow()
t_start = t_end - timedelta(hours=1)
backend_url = os.getenv("BACKEND_URL")
print(backend_url)
resp = requests.get(
f"{os.getenv('BACKEND_URL')}/api/kafka/dump", # TODO: THIS IS SHIT, must fix this
params={'topic': 'user-interactions', 't_start': t_start.isoformat(), 't_end': t_end.isoformat()},
timeout=2
)
if resp.ok:
msgs = resp.json().get('messages', [])
interactions_df = pd.DataFrame(msgs)
if not interactions_df.empty and 'sessionId' in interactions_df.columns:
session_interactions = interactions_df[interactions_df['sessionId'] == sessionId]
if not session_interactions.empty:
extractor = ExtractSessionFeaturesStep(context=context)
session_features_df = extractor.transform(session_interactions)
if not session_features_df.empty:
session_features = session_features_df.drop(columns=['sessionId'])
except Exception as e:
print(f"[session-features-error] {e}")
# continue without session features
state = StateSpace(
demand=demand_values,
prices=merged['base_price'].values,
session_features=pd.DataFrame()
session_features=session_features,
product_ids=merged['productId'].values,
elasticity=merged['elasticity'].values,
metadata={'sessionId': sessionId, 'experimentId': experimentId}
)
oracle = PredictPricesStep(context=context)
prices_df = oracle.transform((pricing_model, state))
# extract price for requested product
product_price_row = prices_df[prices_df['productId'] == productId]
if product_price_row.empty:
raise HTTPException(404, f"No pricing available for product {productId}")
optimal_price = float(product_price_row['predicted_price'].iloc[0])
# extract elasticity if available
product_elasticity_row = elasticity_df[elasticity_df['productId'] == productId]
product_elasticity = (float(product_elasticity_row['elasticity'].iloc[0])
if not product_elasticity_row.empty else None)