diff --git a/engineapi/alembic/versions/71e888082a6d_leaderboard_metadata.py b/engineapi/alembic/versions/71e888082a6d_leaderboard_metadata.py index 43ef9d0c..37ad0604 100644 --- a/engineapi/alembic/versions/71e888082a6d_leaderboard_metadata.py +++ b/engineapi/alembic/versions/71e888082a6d_leaderboard_metadata.py @@ -38,7 +38,7 @@ def upgrade(): sa.Column( "columns_names", postgresql.JSONB(astext_type=sa.Text()), - nullable=False, + nullable=True, server_default="{}", ), ) diff --git a/engineapi/engineapi/actions.py b/engineapi/engineapi/actions.py index e845cc39..a1bef295 100644 --- a/engineapi/engineapi/actions.py +++ b/engineapi/engineapi/actions.py @@ -22,7 +22,7 @@ from .data import ( LeaderboardConfigUpdate, LeaderboardConfig, LeaderboardPosition, - LeaderboardUnformattedPosition, + ColumnsNames, ) from .contracts import Dropper_interface, ERC20_interface, Terminus_interface from .models import ( @@ -1296,7 +1296,7 @@ def get_leaderboard_score( def get_leaderboard_positions( db_session: Session, - leaderboard_id, + leaderboard_id: uuid.UUID, limit: int, offset: int, version_number: Optional[int] = None, @@ -1511,14 +1511,14 @@ def create_leaderboard( token: Optional[Union[uuid.UUID, str]] = None, wallet_connect: bool = False, blockchain_ids: List[int] = [], - columns_names: Optional[Dict[str, str]] = {}, + columns_names: ColumnsNames = None, ) -> Leaderboard: """ Create a leaderboard """ - if len(columns_names) > 0: - columns_names = get_default_columns_names(columns_names) + if columns_names is not None: + columns_names = columns_names.dict() if not token: token = uuid.UUID(MOONSTREAM_ADMIN_ACCESS_TOKEN) @@ -1593,7 +1593,8 @@ def update_leaderboard( description: Optional[str], wallet_connect: Optional[bool], blockchain_ids: Optional[List[int]], - columns_names: Optional[Dict[str, str]], + columns_names: Optional[ColumnsNames], + delete_names, ) -> Leaderboard: """ Update a leaderboard @@ -1615,8 +1616,15 @@ def update_leaderboard( leaderboard.blockchain_ids = blockchain_ids if columns_names is not None: - columns_names = get_default_columns_names(columns_names) - leaderboard.columns_names = columns_names + if leaderboard.columns_names is not None: + current_columns_names = ColumnsNames(**leaderboard.columns_names) + + for key, value in columns_names.dict(exclude_none=True).items(): + setattr(current_columns_names, key, value) + else: + current_columns_names = columns_names + + leaderboard.columns_names = current_columns_names.dict() db_session.commit() diff --git a/engineapi/engineapi/data.py b/engineapi/engineapi/data.py index 30bcb639..99fadbec 100644 --- a/engineapi/engineapi/data.py +++ b/engineapi/engineapi/data.py @@ -342,16 +342,6 @@ class Score(BaseModel): points_data: Dict[str, Any] -class LeaderboardUnformattedPosition(BaseModel): - column_1: str = Field(serialization_alias="address") - column_2: int = Field(serialization_alias="rank") - column_3: int = Field(serialization_alias="score") - column_4: Dict[str, Any] = Field(serialization_alias="points_data") - - class Config: - orm_mode = True - - class LeaderboardPosition(BaseModel): address: str rank: int @@ -375,6 +365,14 @@ class LeaderboardScore(BaseModel): points_data: Dict[str, Any] +class ColumnsNames(BaseModel): + rank: Optional[str] = None + address: Optional[str] = None + score: Optional[str] = None + points_data: Optional[str] = None + points_data_fields: Dict[str, str] = Field(default_factory=dict) + + class Leaderboard(BaseModel): id: UUID title: str @@ -382,7 +380,7 @@ class Leaderboard(BaseModel): resource_id: Optional[UUID] = None wallet_connect: bool = False blockchain_ids: List[int] = Field(default_factory=list) - columns_names: Dict[str, str] = Field(default_factory=dict) + columns_names: ColumnsNames = Field(default_factory=ColumnsNames) created_at: datetime updated_at: datetime @@ -400,7 +398,7 @@ class LeaderboardCreateRequest(BaseModel): description: Optional[str] = None wallet_connect: bool = False blockchain_ids: List[int] = Field(default_factory=list) - columns_names: Dict[str, str] = Field(default_factory=dict) + columns_names: Optional[ColumnsNames] = None class LeaderboardCreatedResponse(BaseModel): @@ -410,7 +408,7 @@ class LeaderboardCreatedResponse(BaseModel): resource_id: Optional[UUID] = None wallet_connect: bool = False blockchain_ids: List[int] = Field(default_factory=list) - columns_names: Dict[str, str] = Field(default_factory=dict) + columns_names: Optional[ColumnsNames] = None created_at: datetime updated_at: datetime @@ -425,7 +423,7 @@ class LeaderboardUpdatedResponse(BaseModel): resource_id: Optional[UUID] = None wallet_connect: bool = False blockchain_ids: List[int] = Field(default_factory=list) - columns_names: Dict[str, str] = Field(default_factory=dict) + columns_names: Optional[ColumnsNames] = None created_at: datetime updated_at: datetime @@ -438,7 +436,7 @@ class LeaderboardUpdateRequest(BaseModel): description: Optional[str] = None wallet_connect: bool = False blockchain_ids: List[int] = Field(default_factory=list) - columns_names: Dict[str, str] = Field(default_factory=dict) + columns_names: Optional[ColumnsNames] = None class LeaderboardDeletedResponse(BaseModel): @@ -448,7 +446,7 @@ class LeaderboardDeletedResponse(BaseModel): resource_id: Optional[UUID] = None wallet_connect: bool = False blockchain_ids: List[int] = Field(default_factory=list) - columns_names: Dict[str, str] = Field(default_factory=dict) + columns_names: Optional[ColumnsNames] = None created_at: datetime updated_at: datetime diff --git a/engineapi/engineapi/models.py b/engineapi/engineapi/models.py index b03b7e33..febb5679 100644 --- a/engineapi/engineapi/models.py +++ b/engineapi/engineapi/models.py @@ -350,7 +350,7 @@ class Leaderboard(Base): # type: ignore blockchain_ids = Column(ARRAY(Integer), nullable=False, default=[]) wallet_connect = Column(Boolean, default=False, nullable=False) - columns_names = Column(JSONB, nullable=False, default={}) + columns_names = Column(JSONB, nullable=True, default={}) created_at = Column( DateTime(timezone=True), server_default=utcnow(), nullable=False ) diff --git a/engineapi/engineapi/routes/leaderboard.py b/engineapi/engineapi/routes/leaderboard.py index 2107a994..9861044c 100644 --- a/engineapi/engineapi/routes/leaderboard.py +++ b/engineapi/engineapi/routes/leaderboard.py @@ -90,16 +90,12 @@ app.add_middleware( @app.get( "", - response_model=Union[ - List[data.LeaderboardPosition], List[data.LeaderboardUnformattedPosition] - ], + response_model=List[data.LeaderboardPosition], tags=["Public Endpoints"], ) @app.get( "/", - response_model=Union[ - List[data.LeaderboardPosition], List[data.LeaderboardUnformattedPosition] - ], + response_model=List[data.LeaderboardPosition], tags=["Public Endpoints"], ) async def leaderboard( @@ -126,29 +122,18 @@ async def leaderboard( raise EngineHTTPException(status_code=500, detail="Internal server error") leaderboard_positions = actions.get_leaderboard_positions( - db_session, leaderboard_id, limit, offset, version + db_session, leaderboard.id, limit, offset, version ) - if len(leaderboard.columns_names) > 0: - result = [ - data.LeaderboardUnformattedPosition( - column_1=position[1], - column_2=position[2], - column_3=position[4], - column_4=position[3], - ) - for position in leaderboard_positions - ] - else: - result = [ - data.LeaderboardPosition( - address=position.address, - score=position.score, - rank=position.rank, - points_data=position.points_data, - ) - for position in leaderboard_positions - ] + result = [ + data.LeaderboardPosition( + address=position.address, + score=position.score, + rank=position.rank, + points_data=position.points_data, + ) + for position in leaderboard_positions + ] return result @@ -198,15 +183,15 @@ async def create_leaderboard( # Add resource to the leaderboard return data.LeaderboardCreatedResponse( - id=created_leaderboard.id, # type: ignore - title=created_leaderboard.title, # type: ignore - description=created_leaderboard.description, # type: ignore - resource_id=created_leaderboard.resource_id, # type: ignore - wallet_connect=created_leaderboard.wallet_connect, # type: ignore - blockchain_ids=created_leaderboard.blockchain_ids, # type: ignore - columns_names=created_leaderboard.columns_names, # type: ignore - created_at=created_leaderboard.created_at, # type: ignore - updated_at=created_leaderboard.updated_at, # type: ignore + id=created_leaderboard.id, + title=created_leaderboard.title, + description=created_leaderboard.description, + resource_id=created_leaderboard.resource_id, + wallet_connect=created_leaderboard.wallet_connect, + blockchain_ids=created_leaderboard.blockchain_ids, + columns_names=created_leaderboard.columns_names, + created_at=created_leaderboard.created_at, + updated_at=created_leaderboard.updated_at, ) @@ -266,15 +251,15 @@ async def update_leaderboard( raise EngineHTTPException(status_code=500, detail="Internal server error") return data.LeaderboardUpdatedResponse( - id=updated_leaderboard.id, # type: ignore - title=updated_leaderboard.title, # type: ignore - description=updated_leaderboard.description, # type: ignore - resource_id=updated_leaderboard.resource_id, # type: ignore - wallet_connect=updated_leaderboard.wallet_connect, # type: ignore - blockchain_ids=updated_leaderboard.blockchain_ids, # type: ignore - columns_names=updated_leaderboard.columns_names, # type: ignore - created_at=updated_leaderboard.created_at, # type: ignore - updated_at=updated_leaderboard.updated_at, # type: ignore + id=updated_leaderboard.id, + title=updated_leaderboard.title, + description=updated_leaderboard.description, + resource_id=updated_leaderboard.resource_id, + wallet_connect=updated_leaderboard.wallet_connect, + blockchain_ids=updated_leaderboard.blockchain_ids, + columns_names=updated_leaderboard.columns_names, + created_at=updated_leaderboard.created_at, + updated_at=updated_leaderboard.updated_at, ) @@ -329,15 +314,15 @@ async def delete_leaderboard( raise EngineHTTPException(status_code=500, detail="Internal server error") return data.LeaderboardDeletedResponse( - id=deleted_leaderboard.id, # type: ignore - title=deleted_leaderboard.title, # type: ignore - description=deleted_leaderboard.description, # type: ignore - resource_id=deleted_leaderboard.resource_id, # type: ignore - wallet_connect=deleted_leaderboard.wallet_connect, # type: ignore - blockchain_ids=deleted_leaderboard.blockchain_ids, # type: ignore - columns_names=deleted_leaderboard.columns_names, # type: ignore - created_at=deleted_leaderboard.created_at, # type: ignore - updated_at=deleted_leaderboard.updated_at, # type: ignore + id=deleted_leaderboard.id, + title=deleted_leaderboard.title, + description=deleted_leaderboard.description, + resource_id=deleted_leaderboard.resource_id, + wallet_connect=deleted_leaderboard.wallet_connect, + blockchain_ids=deleted_leaderboard.blockchain_ids, + columns_names=deleted_leaderboard.columns_names, + created_at=deleted_leaderboard.created_at, + updated_at=deleted_leaderboard.updated_at, ) @@ -370,15 +355,15 @@ async def get_leaderboards( results = [ data.Leaderboard( - id=leaderboard.id, # type: ignore - title=leaderboard.title, # type: ignore - description=leaderboard.description, # type: ignore - resource_id=leaderboard.resource_id, # type: ignore - wallet_connect=leaderboard.wallet_connect, # type: ignore - blockchain_ids=leaderboard.blockchain_ids, # type: ignore - columns_names=leaderboard.columns_names, # type: ignore - created_at=leaderboard.created_at, # type: ignore - updated_at=leaderboard.updated_at, # type: ignore + id=leaderboard.id, + title=leaderboard.title, + description=leaderboard.description, + resource_id=leaderboard.resource_id, + wallet_connect=leaderboard.wallet_connect, + blockchain_ids=leaderboard.blockchain_ids, + columns_names=leaderboard.columns_names, + created_at=leaderboard.created_at, + updated_at=leaderboard.updated_at, ) for leaderboard in leaderboards ] @@ -539,9 +524,7 @@ async def quartiles( @app.get( "/position", - response_model=Union[ - List[data.LeaderboardPosition], List[data.LeaderboardUnformattedPosition] - ], + response_model=List[data.LeaderboardPosition], tags=["Public Endpoints"], ) async def position( @@ -555,7 +538,7 @@ async def position( ), version: Optional[int] = Query(None, description="Version of the leaderboard."), db_session: Session = Depends(db.yield_db_session), -) -> Union[List[data.LeaderboardPosition], List[data.LeaderboardUnformattedPosition]]: +) -> List[data.LeaderboardPosition]: """ Returns the leaderboard posotion for the given address. With given window size. @@ -586,36 +569,22 @@ async def position( version, ) - if len(leaderboard.columns_names) > 0: - results = [ - data.LeaderboardUnformattedPosition( - column_1=position.address, - column_2=position.rank, - column_3=position.score, - column_4=position.points_data, - ) - for position in positions - ] - - else: - results = [ - data.LeaderboardPosition( - address=position.address, - score=position.score, - rank=position.rank, - points_data=position.points_data, - ) - for position in positions - ] + results = [ + data.LeaderboardPosition( + address=position.address, + score=position.score, + rank=position.rank, + points_data=position.points_data, + ) + for position in positions + ] return results @app.get( "/rank", - response_model=Union[ - List[data.LeaderboardPosition], List[data.LeaderboardUnformattedPosition] - ], + response_model=List[data.LeaderboardPosition], tags=["Public Endpoints"], ) async def rank( @@ -625,7 +594,7 @@ async def rank( offset: Optional[int] = Query(None), version: Optional[int] = Query(None, description="Version of the leaderboard."), db_session: Session = Depends(db.yield_db_session), -) -> Union[List[data.LeaderboardPosition], List[data.LeaderboardUnformattedPosition]]: +) -> List[data.LeaderboardPosition]: """ Returns the leaderboard scores for the given rank. """ @@ -651,26 +620,15 @@ async def rank( version_number=version, ) - if len(leaderboard.columns_names) > 0: - results = [ - data.LeaderboardUnformattedPosition( - column_1=position.address, - column_2=position.rank, - column_3=position.score, - column_4=position.points_data, - ) - for position in leaderboard_rank - ] - else: - results = [ - data.LeaderboardPosition( - address=position.address, - score=position.score, - rank=position.rank, - points_data=position.points_data, - ) - for position in leaderboard_rank - ] + results = [ + data.LeaderboardPosition( + address=position.address, + score=position.score, + rank=position.rank, + points_data=position.points_data, + ) + for position in leaderboard_rank + ] return results