feat: refactor project
This commit is contained in:
@@ -45,10 +45,13 @@ settings = Settings()
|
||||
def load_sql(name: str) -> str:
|
||||
"""Load a SQL template from the sql/ directory and inject schema/table names."""
|
||||
raw = (SQL_DIR / name).read_text()
|
||||
return raw.format(
|
||||
listings_schema=settings.LISTINGS_SCHEMA,
|
||||
listings_table=settings.LISTINGS_TABLE,
|
||||
elo_schema=settings.ELO_SCHEMA,
|
||||
images_schema=settings.IMAGES_SCHEMA,
|
||||
images_table=settings.IMAGES_TABLE,
|
||||
)
|
||||
replacements = {
|
||||
"listings_schema": settings.LISTINGS_SCHEMA,
|
||||
"listings_table": settings.LISTINGS_TABLE,
|
||||
"elo_schema": settings.ELO_SCHEMA,
|
||||
"images_schema": settings.IMAGES_SCHEMA,
|
||||
"images_table": settings.IMAGES_TABLE,
|
||||
}
|
||||
for key, value in replacements.items():
|
||||
raw = raw.replace("{{ " + key + " }}", value)
|
||||
return raw
|
||||
|
||||
@@ -27,4 +27,4 @@ app.include_router(rankings.router, prefix="/api", tags=["rankings"])
|
||||
|
||||
@app.get("/api/health")
|
||||
def health():
|
||||
return {"status": "ok"}
|
||||
return {"status": "ok"}
|
||||
|
||||
@@ -19,9 +19,7 @@ class EloRating(Base):
|
||||
wins = Column(Integer, nullable=False, default=0)
|
||||
losses = Column(Integer, nullable=False, default=0)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(
|
||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
|
||||
class Comparison(Base):
|
||||
@@ -39,6 +37,3 @@ class Comparison(Base):
|
||||
elo_a_after = Column(Float, nullable=False)
|
||||
elo_b_after = Column(Float, nullable=False)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Shared query helpers for listing data."""
|
||||
|
||||
from app.config import load_sql, settings
|
||||
from app.config import load_sql
|
||||
from app.schemas import ListingResponse
|
||||
|
||||
LISTING_SELECT = load_sql("listing_select.sql")
|
||||
|
||||
@@ -21,10 +21,7 @@ from app.schemas import (
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
SAMPLE_JOIN = (
|
||||
f" inner join {settings.ELO_SCHEMA}.sample_listings as s"
|
||||
f" on l.global_id = s.global_id"
|
||||
)
|
||||
SAMPLE_JOIN = f" inner join {settings.ELO_SCHEMA}.sample_listings as s on l.global_id = s.global_id"
|
||||
|
||||
|
||||
@router.get("/matchup", response_model=MatchupResponse)
|
||||
@@ -48,15 +45,13 @@ def get_matchup(
|
||||
)
|
||||
|
||||
recent = db.execute(text(load_sql("recent_pairs.sql")))
|
||||
recent_pairs = {
|
||||
frozenset([r.listing_a_id, r.listing_b_id]) for r in recent
|
||||
}
|
||||
recent_pairs = {frozenset([r.listing_a_id, r.listing_b_id]) for r in recent}
|
||||
|
||||
weights = [1.0 / (l.comparison_count + 1) ** 1.5 for l in listings]
|
||||
weights = [1.0 / (x.comparison_count + 1) ** 1.5 for x in listings]
|
||||
first = random.choices(listings, weights=weights, k=1)[0]
|
||||
|
||||
remaining = [l for l in listings if l.global_id != first.global_id]
|
||||
remaining_weights = [1.0 / (l.comparison_count + 1) ** 1.5 for l in remaining]
|
||||
remaining = [x for x in listings if x.global_id != first.global_id]
|
||||
remaining_weights = [1.0 / (x.comparison_count + 1) ** 1.5 for x in remaining]
|
||||
|
||||
second = remaining[0]
|
||||
for _ in range(20):
|
||||
@@ -159,8 +154,7 @@ def get_stats(db: Session = Depends(get_db)):
|
||||
|
||||
dist_rows = db.execute(text(load_sql("elo_distribution.sql")))
|
||||
elo_distribution = [
|
||||
{"bucket": f"{int(r.bucket)}-{int(r.bucket) + 49}", "count": r.count}
|
||||
for r in dist_rows
|
||||
{"bucket": f"{int(r.bucket)}-{int(r.bucket) + 49}", "count": r.count} for r in dist_rows
|
||||
]
|
||||
|
||||
recent_rows = db.execute(text(load_sql("history.sql")), {"limit": 10})
|
||||
|
||||
@@ -11,10 +11,7 @@ from app.schemas import RankingResponse
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
SAMPLE_JOIN = (
|
||||
f" inner join {settings.ELO_SCHEMA}.sample_listings as s"
|
||||
f" on l.global_id = s.global_id"
|
||||
)
|
||||
SAMPLE_JOIN = f" inner join {settings.ELO_SCHEMA}.sample_listings as s on l.global_id = s.global_id"
|
||||
|
||||
|
||||
@router.get("/rankings", response_model=list[RankingResponse])
|
||||
@@ -37,6 +34,5 @@ def get_rankings(
|
||||
listings = [row_to_listing(row) for row in result]
|
||||
|
||||
return [
|
||||
RankingResponse(rank=offset + i + 1, listing=listing)
|
||||
for i, listing in enumerate(listings)
|
||||
RankingResponse(rank=offset + i + 1, listing=listing) for i, listing in enumerate(listings)
|
||||
]
|
||||
|
||||
@@ -1 +1 @@
|
||||
select count(*) from {elo_schema}.comparisons
|
||||
select count(*) from {{ elo_schema }}.comparisons
|
||||
|
||||
@@ -1 +1 @@
|
||||
select count(*) from {listings_schema}.{listings_table}
|
||||
select count(*) from {{ listings_schema }}.{{ listings_table }}
|
||||
|
||||
@@ -1 +1 @@
|
||||
select count(*) from {elo_schema}.ratings
|
||||
select count(*) from {{ elo_schema }}.ratings
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
select
|
||||
avg(elo_rating),
|
||||
max(elo_rating),
|
||||
min(elo_rating)
|
||||
from {elo_schema}.ratings
|
||||
avg(elo_rating) as avg_elo,
|
||||
max(elo_rating) as max_elo,
|
||||
min(elo_rating) as min_elo
|
||||
from {{ elo_schema }}.ratings
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
select
|
||||
floor(elo_rating / 50) * 50 as bucket,
|
||||
count(*) as count
|
||||
from {elo_schema}.ratings
|
||||
from {{ elo_schema }}.ratings
|
||||
group by bucket
|
||||
order by bucket
|
||||
|
||||
@@ -3,12 +3,12 @@ select
|
||||
a.title as listing_a_title,
|
||||
b.title as listing_b_title,
|
||||
w.title as winner_title
|
||||
from {elo_schema}.comparisons as c
|
||||
left join {listings_schema}.{listings_table} as a
|
||||
from {{ elo_schema }}.comparisons as c
|
||||
left join {{ listings_schema }}.{{ listings_table }} as a
|
||||
on c.listing_a_id = a.global_id
|
||||
left join {listings_schema}.{listings_table} as b
|
||||
left join {{ listings_schema }}.{{ listings_table }} as b
|
||||
on c.listing_b_id = b.global_id
|
||||
left join {listings_schema}.{listings_table} as w
|
||||
left join {{ listings_schema }}.{{ listings_table }} as w
|
||||
on c.winner_id = w.global_id
|
||||
order by c.created_at desc
|
||||
limit :limit
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
select
|
||||
raw_json -> 'photo_urls' as photo_urls
|
||||
from {images_schema}.{images_table}
|
||||
select raw_json -> 'photo_urls' as photo_urls
|
||||
from {{ images_schema }}.{{ images_table }}
|
||||
where global_id = :gid
|
||||
|
||||
@@ -35,6 +35,6 @@ select
|
||||
coalesce(r.comparison_count, 0) as comparison_count,
|
||||
coalesce(r.wins, 0) as wins,
|
||||
coalesce(r.losses, 0) as losses
|
||||
from {listings_schema}.{listings_table} as l
|
||||
left join {elo_schema}.ratings as r
|
||||
from {{ listings_schema }}.{{ listings_table }} as l
|
||||
left join {{ elo_schema }}.ratings as r
|
||||
on l.global_id = r.global_id
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
select
|
||||
listing_a_id,
|
||||
listing_b_id
|
||||
from {elo_schema}.comparisons
|
||||
from {{ elo_schema }}.comparisons
|
||||
order by created_at desc
|
||||
limit 20
|
||||
|
||||
Reference in New Issue
Block a user