kopia lustrzana https://github.com/bugout-dev/moonstream
Fix if in get latest version.
Fix join. Add version parameter to all public endpoints.pull/966/head
rodzic
0eb6c3e2b9
commit
de2afed559
|
@ -11,7 +11,7 @@ from hexbytes import HexBytes
|
|||
import requests # type: ignore
|
||||
from sqlalchemy.dialects.postgresql import insert
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import func, text, or_, Subquery
|
||||
from sqlalchemy import func, text, or_, and_, Subquery
|
||||
from sqlalchemy.engine import Row
|
||||
from web3 import Web3
|
||||
from web3.types import ChecksumAddress
|
||||
|
@ -970,7 +970,7 @@ def leaderboard_version_filter(
|
|||
version_number: Optional[int] = None,
|
||||
) -> Union[Subquery, int]:
|
||||
# Subquery to get the latest version number for the given leaderboard
|
||||
if not version_number:
|
||||
if version_number is None:
|
||||
latest_version = (
|
||||
db_session.query(func.max(LeaderboardVersion.version_number)).filter(
|
||||
LeaderboardVersion.leaderboard_id == leaderboard_id,
|
||||
|
@ -983,16 +983,38 @@ def leaderboard_version_filter(
|
|||
return latest_version
|
||||
|
||||
|
||||
def get_leaderboard_total_count(db_session: Session, leaderboard_id) -> int:
|
||||
def get_leaderboard_total_count(
|
||||
db_session: Session, leaderboard_id, version_number: Optional[int] = None
|
||||
) -> int:
|
||||
"""
|
||||
Get the total number of claimants in the leaderboard
|
||||
Get the total number of position in the leaderboard
|
||||
"""
|
||||
return (
|
||||
db_session.query(LeaderboardScores)
|
||||
.filter(LeaderboardScores.leaderboard_id == leaderboard_id)
|
||||
.count()
|
||||
|
||||
latest_version = leaderboard_version_filter(
|
||||
db_session=db_session,
|
||||
leaderboard_id=leaderboard_id,
|
||||
version_number=version_number,
|
||||
)
|
||||
|
||||
total_count = (
|
||||
db_session.query(func.count(LeaderboardScores.id))
|
||||
.join(
|
||||
LeaderboardVersion,
|
||||
and_(
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
LeaderboardVersion.version_number
|
||||
== LeaderboardScores.leaderboard_version_number,
|
||||
),
|
||||
)
|
||||
.filter(
|
||||
LeaderboardVersion.published == True,
|
||||
LeaderboardVersion.version_number == latest_version,
|
||||
)
|
||||
.filter(LeaderboardScores.leaderboard_id == leaderboard_id)
|
||||
).scalar()
|
||||
|
||||
return total_count
|
||||
|
||||
|
||||
def get_leaderboard_info(
|
||||
db_session: Session, leaderboard_id: uuid.UUID, version_number: Optional[int] = None
|
||||
|
@ -1006,6 +1028,7 @@ def get_leaderboard_info(
|
|||
leaderboard_id=leaderboard_id,
|
||||
version_number=version_number,
|
||||
)
|
||||
|
||||
leaderboard = (
|
||||
db_session.query(
|
||||
Leaderboard.id,
|
||||
|
@ -1021,7 +1044,11 @@ def get_leaderboard_info(
|
|||
)
|
||||
.join(
|
||||
LeaderboardVersion,
|
||||
LeaderboardVersion.leaderboard_id == Leaderboard.id,
|
||||
and_(
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
LeaderboardVersion.version_number
|
||||
== LeaderboardScores.leaderboard_version_number,
|
||||
),
|
||||
isouter=True,
|
||||
)
|
||||
.filter(
|
||||
|
@ -1030,8 +1057,7 @@ def get_leaderboard_info(
|
|||
)
|
||||
.filter(Leaderboard.id == leaderboard_id)
|
||||
.group_by(Leaderboard.id, Leaderboard.title, Leaderboard.description)
|
||||
.one()
|
||||
)
|
||||
).one()
|
||||
|
||||
return leaderboard
|
||||
|
||||
|
@ -1146,7 +1172,11 @@ def get_position(
|
|||
)
|
||||
.join(
|
||||
LeaderboardVersion,
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
and_(
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
LeaderboardVersion.version_number
|
||||
== LeaderboardScores.leaderboard_version_number,
|
||||
),
|
||||
)
|
||||
.filter(
|
||||
LeaderboardVersion.published == True,
|
||||
|
@ -1222,7 +1252,11 @@ def get_leaderboard_positions(
|
|||
)
|
||||
.join(
|
||||
LeaderboardVersion,
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
and_(
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
LeaderboardVersion.version_number
|
||||
== LeaderboardScores.leaderboard_version_number,
|
||||
),
|
||||
)
|
||||
.filter(LeaderboardScores.leaderboard_id == leaderboard_id)
|
||||
.filter(LeaderboardVersion.published == True)
|
||||
|
@ -1260,7 +1294,11 @@ def get_qurtiles(
|
|||
)
|
||||
.join(
|
||||
LeaderboardVersion,
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
and_(
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
LeaderboardVersion.version_number
|
||||
== LeaderboardScores.leaderboard_version_number,
|
||||
),
|
||||
)
|
||||
.filter(
|
||||
LeaderboardVersion.published == True,
|
||||
|
@ -1314,7 +1352,11 @@ def get_ranks(
|
|||
)
|
||||
.join(
|
||||
LeaderboardVersion,
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
and_(
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
LeaderboardVersion.version_number
|
||||
== LeaderboardScores.leaderboard_version_number,
|
||||
),
|
||||
)
|
||||
.filter(
|
||||
LeaderboardVersion.published == True,
|
||||
|
@ -1361,7 +1403,11 @@ def get_rank(
|
|||
)
|
||||
.join(
|
||||
LeaderboardVersion,
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
and_(
|
||||
LeaderboardVersion.leaderboard_id == LeaderboardScores.leaderboard_id,
|
||||
LeaderboardVersion.version_number
|
||||
== LeaderboardScores.leaderboard_version_number,
|
||||
),
|
||||
)
|
||||
.filter(
|
||||
LeaderboardVersion.published == True,
|
||||
|
@ -1546,7 +1592,11 @@ def add_scores(
|
|||
insert_statement = insert(LeaderboardScores).values(leaderboard_scores)
|
||||
|
||||
result_stmt = insert_statement.on_conflict_do_update(
|
||||
index_elements=[LeaderboardScores.address, LeaderboardScores.leaderboard_id],
|
||||
index_elements=[
|
||||
LeaderboardScores.address,
|
||||
LeaderboardScores.leaderboard_id,
|
||||
LeaderboardScores.leaderboard_version_number,
|
||||
],
|
||||
set_=dict(
|
||||
score=insert_statement.excluded.score,
|
||||
points_data=insert_statement.excluded.points_data,
|
||||
|
|
|
@ -452,5 +452,5 @@ class LeaderboardVersion(BaseModel):
|
|||
updated_at: datetime
|
||||
|
||||
|
||||
class LeaderboardVersionUpdateRequest(BaseModel):
|
||||
class LeaderboardVersionRequest(BaseModel):
|
||||
publish: bool
|
||||
|
|
|
@ -355,6 +355,7 @@ async def get_leaderboards(
|
|||
)
|
||||
async def count_addresses(
|
||||
leaderboard_id: UUID = Query(..., description="Leaderboard ID"),
|
||||
version: Optional[int] = Query(None, description="Version of the leaderboard."),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
) -> data.CountAddressesResponse:
|
||||
"""
|
||||
|
@ -373,7 +374,7 @@ async def count_addresses(
|
|||
logger.error(f"Error while getting leaderboard: {e}")
|
||||
raise EngineHTTPException(status_code=500, detail="Internal server error")
|
||||
|
||||
count = actions.get_leaderboard_total_count(db_session, leaderboard_id)
|
||||
count = actions.get_leaderboard_total_count(db_session, leaderboard_id, version)
|
||||
|
||||
return data.CountAddressesResponse(count=count)
|
||||
|
||||
|
@ -384,12 +385,13 @@ async def count_addresses(
|
|||
async def leadeboard_info(
|
||||
leaderboard_id: UUID = Query(..., description="Leaderboard ID"),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
version: Optional[int] = Query(None, description="Version of the leaderboard."),
|
||||
) -> data.LeaderboardInfoResponse:
|
||||
"""
|
||||
Returns leaderboard info.
|
||||
"""
|
||||
try:
|
||||
leaderboard = actions.get_leaderboard_info(db_session, leaderboard_id)
|
||||
leaderboard = actions.get_leaderboard_info(db_session, leaderboard_id, version)
|
||||
except NoResultFound as e:
|
||||
raise EngineHTTPException(
|
||||
status_code=404,
|
||||
|
@ -443,6 +445,7 @@ async def get_scores_changes(
|
|||
async def quartiles(
|
||||
leaderboard_id: UUID = Query(..., description="Leaderboard ID"),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
version: Optional[int] = Query(None, description="Version of the leaderboard."),
|
||||
) -> data.QuartilesResponse:
|
||||
"""
|
||||
Returns the quartiles of the leaderboard.
|
||||
|
@ -460,7 +463,7 @@ async def quartiles(
|
|||
raise EngineHTTPException(status_code=500, detail="Internal server error")
|
||||
|
||||
try:
|
||||
q1, q2, q3 = actions.get_qurtiles(db_session, leaderboard_id)
|
||||
q1, q2, q3 = actions.get_qurtiles(db_session, leaderboard_id, version)
|
||||
|
||||
except actions.LeaderboardIsEmpty:
|
||||
raise EngineHTTPException(status_code=204, detail="Leaderboard is empty.")
|
||||
|
@ -489,6 +492,7 @@ async def position(
|
|||
normalize_addresses: bool = Query(
|
||||
True, description="Normalize addresses to checksum."
|
||||
),
|
||||
version: Optional[int] = Query(None, description="Version of the leaderboard."),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
) -> List[data.LeaderboardPosition]:
|
||||
"""
|
||||
|
@ -512,7 +516,13 @@ async def position(
|
|||
address = Web3.toChecksumAddress(address)
|
||||
|
||||
positions = actions.get_position(
|
||||
db_session, leaderboard_id, address, window_size, limit, offset
|
||||
db_session,
|
||||
leaderboard_id,
|
||||
address,
|
||||
window_size,
|
||||
limit,
|
||||
offset,
|
||||
version,
|
||||
)
|
||||
|
||||
results = [
|
||||
|
@ -536,6 +546,7 @@ async def rank(
|
|||
rank: int = Query(1, description="Rank to get."),
|
||||
limit: Optional[int] = Query(None),
|
||||
offset: Optional[int] = Query(None),
|
||||
version: Optional[int] = Query(None, description="Version of the leaderboard."),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
) -> List[data.LeaderboardPosition]:
|
||||
"""
|
||||
|
@ -555,7 +566,12 @@ async def rank(
|
|||
raise EngineHTTPException(status_code=500, detail="Internal server error")
|
||||
|
||||
leaderboard_rank = actions.get_rank(
|
||||
db_session, leaderboard_id, rank, limit=limit, offset=offset
|
||||
db_session,
|
||||
leaderboard_id,
|
||||
rank,
|
||||
limit=limit,
|
||||
offset=offset,
|
||||
version_number=version,
|
||||
)
|
||||
results = [
|
||||
data.LeaderboardPosition(
|
||||
|
@ -572,6 +588,7 @@ async def rank(
|
|||
@app.get("/ranks", response_model=List[data.RanksResponse], tags=["Public Endpoints"])
|
||||
async def ranks(
|
||||
leaderboard_id: UUID = Query(..., description="Leaderboard ID"),
|
||||
version: Optional[int] = Query(None, description="Version of the leaderboard."),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
) -> List[data.RanksResponse]:
|
||||
"""
|
||||
|
@ -590,7 +607,7 @@ async def ranks(
|
|||
logger.error(f"Error while getting leaderboard: {e}")
|
||||
raise EngineHTTPException(status_code=500, detail="Internal server error")
|
||||
|
||||
ranks = actions.get_ranks(db_session, leaderboard_id)
|
||||
ranks = actions.get_ranks(db_session, leaderboard_id, version)
|
||||
results = [
|
||||
data.RanksResponse(
|
||||
score=rank.score,
|
||||
|
@ -1038,8 +1055,11 @@ async def leaderboard_version_handler(
|
|||
async def create_leaderboard_version(
|
||||
request: Request,
|
||||
leaderboard_id: UUID = Path(..., description="Leaderboard ID"),
|
||||
version: int = Query(..., description="Version of the leaderboard."),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
request_body: data.LeaderboardVersionRequest = Body(
|
||||
...,
|
||||
description="JSON object specifying whether to publish or unpublish version.",
|
||||
),
|
||||
Authorization: str = AuthHeader,
|
||||
) -> data.LeaderboardVersion:
|
||||
"""
|
||||
|
@ -1064,23 +1084,22 @@ async def create_leaderboard_version(
|
|||
)
|
||||
|
||||
try:
|
||||
leaderboard_version = actions.create_leaderboard_version(
|
||||
new_version = actions.create_leaderboard_version(
|
||||
db_session=db_session,
|
||||
leaderboard_id=leaderboard_id,
|
||||
version=version,
|
||||
)
|
||||
except BugoutResponseException as e:
|
||||
raise EngineHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except actions.LeaderboardConfigNotFound as e:
|
||||
raise EngineHTTPException(
|
||||
status_code=404,
|
||||
detail="Leaderboard config not found.",
|
||||
publish=request_body.publish,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error while creating leaderboard version: {e}")
|
||||
raise EngineHTTPException(status_code=500, detail="Internal server error")
|
||||
|
||||
return leaderboard_version
|
||||
return data.LeaderboardVersion(
|
||||
leaderboard_id=new_version.leaderboard_id,
|
||||
version=new_version.version_number,
|
||||
published=new_version.published,
|
||||
created_at=new_version.created_at,
|
||||
updated_at=new_version.updated_at,
|
||||
)
|
||||
|
||||
|
||||
@app.put(
|
||||
|
@ -1092,7 +1111,7 @@ async def update_leaderboard_version_handler(
|
|||
request: Request,
|
||||
leaderboard_id: UUID = Path(..., description="Leaderboard ID"),
|
||||
version: int = Path(..., description="Version of the leaderboard."),
|
||||
request_body: data.LeaderboardVersionUpdateRequest = Body(
|
||||
request_body: data.LeaderboardVersionRequest = Body(
|
||||
...,
|
||||
description="JSON object specifying whether to publish or unpublish version.",
|
||||
),
|
||||
|
|
Ładowanie…
Reference in New Issue