Skip to content

Commit ec0af07

Browse files
committed
Add resource usage endpoint to get usage for a given user
1 parent cf89619 commit ec0af07

2 files changed

Lines changed: 93 additions & 6 deletions

File tree

components/renku_data_services/resource_usage/api.spec.yaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,54 @@ paths:
4848
tags:
4949
- resource-usage
5050

51+
/resource_pools/{resource_pool_id}/admin_usage:
52+
get:
53+
summary: |
54+
Get usage and limits of the supplied pool. If a `start_date`
55+
is not given, the usage of the current week is returned. This
56+
endpoint is only available to admins and it allows to specify
57+
a user_id query parameter to check usages for any user.
58+
parameters:
59+
- in: path
60+
name: resource_pool_id
61+
required: true
62+
schema:
63+
type: integer
64+
- in: query
65+
name: start_date
66+
required: false
67+
schema:
68+
type: string
69+
format: date
70+
- in: query
71+
name: end_date
72+
required: false
73+
schema:
74+
type: string
75+
format: date
76+
- in: query
77+
name: user_id
78+
required: false
79+
schema:
80+
type: string
81+
responses:
82+
"200":
83+
description: "Return the pool limits and current usage."
84+
content:
85+
"application/json":
86+
schema:
87+
$ref: "#/components/schemas/ResourcePoolUsage"
88+
"404":
89+
description: "The resource pool doesn't exist."
90+
content:
91+
"application/json":
92+
schema:
93+
$ref: "#/components/schemas/ErrorResponse"
94+
default:
95+
$ref: "#/components/responses/Error"
96+
tags:
97+
- resource-usage
98+
5199
/resource_pools/{resource_pool_id}/limits:
52100
get:
53101
summary: "Get resource pool limits"

components/renku_data_services/resource_usage/blueprints.py

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,18 @@ async def _delete(_: Request, user: base_models.APIUser, resource_pool_id: int,
135135

136136
return "/resource_pools/<resource_pool_id>/classes/<class_id>/cost", ["DELETE"], _delete
137137

138+
def _extract_date(self, req: Request, name: str) -> date | None:
139+
datestr = req.args.get(name)
140+
return datetime.strptime(datestr, "%Y-%m-%d") if datestr is not None else None
141+
138142
def get_pool_usage(self) -> BlueprintFactoryResponse:
139143
"""Get usage of a pool."""
140144

141-
def extract_date(req: Request, name: str) -> date | None:
142-
datestr = req.args.get(name)
143-
return datetime.strptime(datestr, "%Y-%m-%d") if datestr is not None else None
144-
145145
@authenticate(self.authenticator)
146146
@validate_db_ids
147147
async def _get(req: Request, user: base_models.APIUser, resource_pool_id: int) -> HTTPResponse:
148-
start_date = extract_date(req, "start_date")
149-
end_date = extract_date(req, "end_date")
148+
start_date = self._extract_date(req, "start_date")
149+
end_date = self._extract_date(req, "end_date")
150150
result: model.ResourcePoolUsage | None = None
151151
if start_date:
152152
result = await self.rr_svc.get_for_date(resource_pool_id, user.id or "", start_date, end_date)
@@ -174,3 +174,42 @@ async def _get(req: Request, user: base_models.APIUser, resource_pool_id: int) -
174174
raise errors.MissingResourceError()
175175

176176
return "/resource_pools/<resource_pool_id>/usage", ["GET"], _get
177+
178+
def get_admin_pool_usage(self) -> BlueprintFactoryResponse:
179+
"""Get usage of a pool."""
180+
181+
@authenticate(self.authenticator)
182+
@only_admins
183+
@validate_db_ids
184+
async def _get(req: Request, user: base_models.APIUser, resource_pool_id: int) -> HTTPResponse:
185+
start_date = self._extract_date(req, "start_date")
186+
end_date = self._extract_date(req, "end_date")
187+
user_id = req.args.get("user_id")
188+
uid = str(user_id) if user_id else user.id or ""
189+
result: model.ResourcePoolUsage | None = None
190+
if start_date:
191+
result = await self.rr_svc.get_for_date(resource_pool_id, uid, start_date, end_date)
192+
else:
193+
result = await self.rr_svc.get_running_week(resource_pool_id, uid)
194+
if result:
195+
output = apispec.ResourcePoolUsage(
196+
total_usage=apispec.ResourceUsageSummary(
197+
runtime=result.total_usage.runtime_hours, cost=result.total_usage.cost.value
198+
),
199+
pool_limits=apispec.ResourcePoolLimits(
200+
pool_id=result.pool_limits.pool_id,
201+
total_limit=result.pool_limits.total_limit.value,
202+
user_limit=result.pool_limits.user_limit.value,
203+
),
204+
user_usage=apispec.ResourceUsageSummary(
205+
runtime=result.user_usage.runtime_hours, cost=result.user_usage.cost.value
206+
),
207+
)
208+
return validated_json(
209+
apispec.ResourcePoolUsage,
210+
output,
211+
)
212+
else:
213+
raise errors.MissingResourceError()
214+
215+
return "/resource_pools/<resource_pool_id>/admin_usage", ["GET"], _get

0 commit comments

Comments
 (0)