fix drugs with mL dosage

This commit is contained in:
ipu 2025-08-22 22:58:45 +03:00
parent 18639e914d
commit 13c78e1be0
2 changed files with 54 additions and 20 deletions

View file

@ -1,12 +1,14 @@
import json import json
import re
import httpx import httpx
from pydantic import BaseModel from pydantic import BaseModel
from sqlalchemy.exc import IntegrityError
from src.config import settings
from src.database import Drug, Session from src.database import Drug, Session
from src.drug_price_parser import DrugPriceParser, DrugPriceResponse from src.drug_price_parser import DrugPriceParser, DrugPriceResponse
from src.config import settings
from src.services.session_service import session_service from src.services.session_service import session_service
from sqlalchemy.exc import IntegrityError
class DrugFull(BaseModel): class DrugFull(BaseModel):
@ -16,6 +18,15 @@ class DrugFull(BaseModel):
unit_price: float unit_price: float
description: str | None = None description: str | None = None
def make_drug_full(drug: Drug):
return DrugFull(
name=drug.name,
dosage=drug.dosage,
dosage_unit=drug.dosage_unit,
unit_price=drug.unit_price,
description=drug.description,
)
async def convert_drug_result(drug: DrugPriceResponse) -> list[DrugFull]: async def convert_drug_result(drug: DrugPriceResponse) -> list[DrugFull]:
base_url = settings.TALESTORM_API_BASE_URL base_url = settings.TALESTORM_API_BASE_URL
@ -24,7 +35,7 @@ async def convert_drug_result(drug: DrugPriceResponse) -> list[DrugFull]:
client = httpx.AsyncClient( client = httpx.AsyncClient(
base_url=base_url, base_url=base_url,
headers={"X-API-Key": api_key}, headers={"X-API-Key": api_key},
timeout=httpx.Timeout(60.0, connect=10.0) # 30s total timeout, 10s connect timeout timeout=httpx.Timeout(60.0)
) )
session_id = await session_service.create_session(agent_id=settings.TALESTORM_DRUG_AGENT_ID) session_id = await session_service.create_session(agent_id=settings.TALESTORM_DRUG_AGENT_ID)
drug_json = drug.model_dump_json() drug_json = drug.model_dump_json()
@ -74,34 +85,55 @@ async def store_drug(drugs: list[DrugFull]):
pass pass
def parse_dosage_unit(dosage_unit: str):
m = re.match(r"^([a-zA-Z]+)\s*/\s*(\d*\.?\d*)\s*([a-zA-Z]+)$", dosage_unit, re.IGNORECASE)
if m:
x1 = m.group(1)
y = float(m.group(2))
x2 = m.group(3)
return x1, y, x2
return None, 1, None
def check_drug_dosage(d: DrugFull, dosage: float) -> DrugFull | None:
if d.dosage_unit == "mg" and dosage == d.dosage:
return d
if (d.dosage_unit == "mcg" and dosage * 1000 == d.dosage) or (d.dosage_unit == "g" and dosage / 1000 == d.dosage):
return d
x1, y, x2 = parse_dosage_unit(d.dosage_unit)
if x1 is not None and ((x1 == "mg" and dosage == d.dosage) or (x1 == "mcg" and dosage * 1000 == d.dosage) or (x1 == "g" and dosage / 1000 == d.dosage)):
d.unit_price *= y
return d
return None
async def fetch_drug_with_dosage(drug_name: str, dosage: float) -> DrugFull | None: async def fetch_drug_with_dosage(drug_name: str, dosage: float) -> DrugFull | None:
try: try:
with Session() as session: with Session() as session:
drug = session.query(Drug).filter(Drug.name == drug_name, Drug.dosage == dosage).first() drugs = session.query(Drug).filter(Drug.name == drug_name).all()
if drug:
return DrugFull.model_validate(drug)
drug = session.query(Drug).filter(Drug.name == drug_name).first() for d in [make_drug_full(df) for df in drugs]:
if drug: drug_full = check_drug_dosage(d, dosage)
return DrugFull.model_validate(drug) if drug_full is not None:
except: return drug_full
except Exception as e:
pass pass
drugs = await get_drug(drug_name) drugs = await get_drug(drug_name)
print(f"Drug {drug_name} found {drugs}")
try: try:
await store_drug(drugs) await store_drug(drugs)
except Exception as e: except Exception as e:
print(f"Error storing drug {drug_name}: {e}") print(f"Error storing drug {drug_name}: {e}")
pass pass
drug = None
for c_drug in drugs: for c_drug in drugs:
if c_drug.dosage == dosage: drug_full = check_drug_dosage(c_drug, dosage)
drug = c_drug if drug_full:
return drug_full
if drug:
return DrugFull.model_validate(drug)
raise Exception(f"Drug {drug_name} with dosage {dosage} not found") raise Exception(f"Drug {drug_name} with dosage {dosage} not found")

View file

@ -354,9 +354,10 @@ class EstimationService:
if medication.applicant != applicant_id: if medication.applicant != applicant_id:
continue continue
try: try:
drug_name = medication.name drug_name = medication.name.lower()
drug_url = search_drug(drug_name) drug_url = search_drug(drug_name)
drug_dosage = float(medication.dosage) drug_dosage = float(medication.dosage)
print(f"{drug_name} | {drug_url} | {drug_dosage}")
drug_price = await fetch_drug_with_dosage(drug_url, drug_dosage) drug_price = await fetch_drug_with_dosage(drug_url, drug_dosage)
if medication.frequency in ["Once daily", "At bedtime"]: if medication.frequency in ["Once daily", "At bedtime"]:
@ -378,6 +379,7 @@ class EstimationService:
rx_spend += drug_price.unit_price * month_times rx_spend += drug_price.unit_price * month_times
except Exception as e: except Exception as e:
raise e
print(f"Error calculating rx spend for {medication.name}: {e}") print(f"Error calculating rx spend for {medication.name}: {e}")
pass pass
return rx_spend return rx_spend