Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR for statistic endpoint #98

Merged
merged 7 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion web_app/api/user.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from fastapi import APIRouter, Request, HTTPException
from web_app.db.crud import UserDBConnector
from web_app.db.crud import PositionDBConnector, UserDBConnector
from web_app.api.serializers.transaction import UpdateUserContractRequest
from web_app.api.serializers.user import CheckUserResponse, UpdateUserContractResponse, GetUserContractAddressResponse

router = APIRouter() # Initialize the router

user_db = UserDBConnector()

position_db = PositionDBConnector()


@router.get("/api/get-user-contract", tags=["User Operations"], summary="Get user's contract status", response_description="Returns 0 if the user is None or if the contract is not deployed. Returns the transaction hash if the contract is deployed.")
async def get_user_contract(wallet_id: str) -> str:
Expand Down Expand Up @@ -86,3 +88,27 @@ async def get_user_contract_address(wallet_id: str) -> GetUserContractAddressRes
return {"contract_address": contract_address}
else:
return {"contract_address": None}


@router.get("/api/get_stats", tags=["Statistics"], summary="Get all user amounts and the number of unique users.")
async def get_stats():
"""
Returns all user amounts for open positions and the number of unique users.

### Returns:
- Dictionary containing:
- total_amounts: dict where keys are user IDs and values are total amounts
- unique_users: The count of unique users with open positions
"""
try:
# Fetch total amounts for each user where position status is OPENED
total_amounts = position_db.get_all_amounts_for_opened_positions()

# Get the number of unique users
unique_users_count = len(total_amounts)
djeck1432 marked this conversation as resolved.
Show resolved Hide resolved

# Return total amounts and unique users count
return {"total_amounts": total_amounts, "unique_users": unique_users_count}
djeck1432 marked this conversation as resolved.
Show resolved Hide resolved

except Exception as e:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which particular exception your are trying to catch?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still opened issue

raise HTTPException(status_code=500, detail="Error retrieving statistics.")
37 changes: 37 additions & 0 deletions web_app/db/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,40 @@ def open_position(self, position_id: uuid) -> Position | None:
position.status = Status.OPENED.value
self.write_to_db(position)
return position.status

def get_unique_users(self) -> list[str]:
"""
Fetches all unique users from the Position table.
:return: list of unique user ids
"""
with self.Session() as db :
try:
# Query for distinct user IDs from the Position table
unique_users = db.query(Position.user_id).distinct().all()
djeck1432 marked this conversation as resolved.
Show resolved Hide resolved
return [user[0] for user in unique_users] # Extract user_id from tuple
except SQLAlchemyError as e:
logger.error(f"Error fetching unique users: {str(e)}")
return []

def get_all_amounts_for_opened_positions(self) -> dict[str, float]:
"""
Fetches the total amount for all users where position status is 'OPENED'.

:return: A dictionary with user IDs as keys and the total amount as values.
"""
with self.Session() as db:
try:
# Query all positions with status OPENED and group by user_id
opened_positions = (
db.query(Position.user_id, db.func.sum(Position.amount).label('total_amount'))
.filter(Position.status == Status.OPENED.value)
.group_by(Position.user_id)
djeck1432 marked this conversation as resolved.
Show resolved Hide resolved
.all()
)

# Return a dictionary with user IDs and their respective total amounts
return {user_id: total_amount for user_id, total_amount in opened_positions}

except SQLAlchemyError as e:
logger.error(f"Error fetching amounts for opened positions: {str(e)}")
return {}
djeck1432 marked this conversation as resolved.
Show resolved Hide resolved