|
| 1 | +import asyncio |
1 | 2 | from typing import List |
2 | 3 | from datetime import date, timedelta |
3 | | -from collections import defaultdict |
| 4 | +from collections import defaultdict, Counter |
4 | 5 | import logging |
5 | 6 | import numpy as np |
6 | 7 |
|
7 | | -from fastapi import APIRouter, Query |
| 8 | +from fastapi import APIRouter, Depends, Query, HTTPException, status as status_codes |
| 9 | +from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials |
8 | 10 |
|
9 | 11 | from ..data_models import ( |
10 | 12 | DateRangeCount, |
|
13 | 15 | QueueStatus, |
14 | 16 | Histogram, |
15 | 17 | ProjectStatus, |
| 18 | + UserStatistics, |
16 | 19 | ) |
17 | | -from .. import db |
| 20 | +from .. import db, oauth |
| 21 | + |
18 | 22 | from ..globals import STANDARD_QUEUES |
19 | 23 |
|
20 | 24 |
|
21 | 25 | logger = logging.getLogger("simqueue") |
22 | 26 |
|
23 | 27 | router = APIRouter() |
| 28 | +auth = HTTPBearer() |
24 | 29 |
|
25 | 30 |
|
26 | 31 | def normalize_start_end(start: date = None, end: date = None): |
@@ -293,3 +298,29 @@ async def resource_usage(start: date = None, end: date = None, interval: int = 7 |
293 | 298 | results.append(new_obj) |
294 | 299 |
|
295 | 300 | return results |
| 301 | + |
| 302 | + |
| 303 | +@router.get("/statistics/per-user", response_model=List[UserStatistics]) |
| 304 | +async def resource_usage( |
| 305 | + start: date = None, end: date = None, token: HTTPAuthorizationCredentials = Depends(auth) |
| 306 | +): |
| 307 | + """ |
| 308 | + Statistics at the level of individual users (only accessible by platform administrators) |
| 309 | + """ |
| 310 | + user = await asyncio.create_task(oauth.User.from_token(token.credentials)) |
| 311 | + if not user.is_admin: |
| 312 | + raise HTTPException( |
| 313 | + status_code=status_codes.HTTP_403_FORBIDDEN, |
| 314 | + detail="Only admins can access per-user statistics", |
| 315 | + ) |
| 316 | + jobs = await db.query_jobs( |
| 317 | + status=["finished", "error"], |
| 318 | + date_range_start=start, |
| 319 | + date_range_end=end, |
| 320 | + size=100000, |
| 321 | + fields=["user_id"], |
| 322 | + ) |
| 323 | + jobs_per_user = Counter(job["user_id"] for job in jobs) |
| 324 | + return [ |
| 325 | + UserStatistics(user=user_name, jobs=count) for user_name, count in jobs_per_user.items() |
| 326 | + ] |
0 commit comments