|
26 | 26 | Forecast, |
27 | 27 | Grant, |
28 | 28 | GsaElibraryContract, |
| 29 | + ITDashboardInvestment, |
29 | 30 | Location, |
30 | 31 | Notice, |
31 | 32 | Opportunity, |
@@ -1336,6 +1337,112 @@ def get_gsa_elibrary_contract( |
1336 | 1337 | data, shape, GsaElibraryContract, flat, flat_lists, joiner=joiner |
1337 | 1338 | ) |
1338 | 1339 |
|
| 1340 | + # ============================================================================ |
| 1341 | + # IT Dashboard Investments |
| 1342 | + # ============================================================================ |
| 1343 | + |
| 1344 | + def list_itdashboard_investments( |
| 1345 | + self, |
| 1346 | + page: int = 1, |
| 1347 | + limit: int = 25, |
| 1348 | + shape: str | None = None, |
| 1349 | + flat: bool = False, |
| 1350 | + flat_lists: bool = False, |
| 1351 | + joiner: str = ".", |
| 1352 | + search: str | None = None, |
| 1353 | + agency_code: int | None = None, |
| 1354 | + agency_name: str | None = None, |
| 1355 | + type_of_investment: str | None = None, |
| 1356 | + updated_time_after: str | date | datetime | None = None, |
| 1357 | + updated_time_before: str | date | datetime | None = None, |
| 1358 | + cio_rating: int | None = None, |
| 1359 | + cio_rating_max: int | None = None, |
| 1360 | + performance_risk: bool | None = None, |
| 1361 | + ) -> PaginatedResponse: |
| 1362 | + """List federal IT investments from the IT Dashboard (`/api/itdashboard/`). |
| 1363 | +
|
| 1364 | + Filters are tier-gated by the API: |
| 1365 | +
|
| 1366 | + - **Free**: ``search`` (full-text across UII, title, description, agency, bureau) |
| 1367 | + - **Pro**: ``agency_code``, ``type_of_investment``, |
| 1368 | + ``updated_time_after`` / ``updated_time_before`` |
| 1369 | + - **Business+**: ``agency_name`` (text), ``cio_rating``, |
| 1370 | + ``cio_rating_max``, ``performance_risk`` |
| 1371 | +
|
| 1372 | + Hitting a gated filter on a lower tier returns a 403 with upgrade info. |
| 1373 | +
|
| 1374 | + CIO ratings: 1=High Risk, 2=Moderately High, 3=Medium, 4=Moderately Low, 5=Low. |
| 1375 | + ``performance_risk=True`` returns investments with at least one NOT MET metric. |
| 1376 | + """ |
| 1377 | + params: dict[str, Any] = {"page": page, "limit": min(limit, 100)} |
| 1378 | + if shape is None: |
| 1379 | + shape = ShapeConfig.ITDASHBOARD_INVESTMENTS_MINIMAL |
| 1380 | + if shape: |
| 1381 | + params["shape"] = shape |
| 1382 | + if flat: |
| 1383 | + params["flat"] = "true" |
| 1384 | + if joiner: |
| 1385 | + params["joiner"] = joiner |
| 1386 | + if flat_lists: |
| 1387 | + params["flat_lists"] = "true" |
| 1388 | + for k, val in ( |
| 1389 | + ("search", search), |
| 1390 | + ("agency_code", agency_code), |
| 1391 | + ("agency_name", agency_name), |
| 1392 | + ("type_of_investment", type_of_investment), |
| 1393 | + ("updated_time_after", updated_time_after), |
| 1394 | + ("updated_time_before", updated_time_before), |
| 1395 | + ("cio_rating", cio_rating), |
| 1396 | + ("cio_rating_max", cio_rating_max), |
| 1397 | + ("performance_risk", performance_risk), |
| 1398 | + ): |
| 1399 | + if val is None: |
| 1400 | + continue |
| 1401 | + if isinstance(val, bool): |
| 1402 | + params[k] = "true" if val else "false" |
| 1403 | + elif isinstance(val, (date, datetime)): |
| 1404 | + params[k] = val.isoformat() |
| 1405 | + else: |
| 1406 | + params[k] = val |
| 1407 | + data = self._get("/api/itdashboard/", params) |
| 1408 | + results = [ |
| 1409 | + self._parse_response_with_shape( |
| 1410 | + obj, shape, ITDashboardInvestment, flat, flat_lists, joiner=joiner |
| 1411 | + ) |
| 1412 | + for obj in data.get("results", []) |
| 1413 | + ] |
| 1414 | + return PaginatedResponse( |
| 1415 | + count=data.get("count", 0), |
| 1416 | + next=data.get("next"), |
| 1417 | + previous=data.get("previous"), |
| 1418 | + results=results, |
| 1419 | + ) |
| 1420 | + |
| 1421 | + def get_itdashboard_investment( |
| 1422 | + self, |
| 1423 | + uii: str, |
| 1424 | + shape: str | None = None, |
| 1425 | + flat: bool = False, |
| 1426 | + flat_lists: bool = False, |
| 1427 | + joiner: str = ".", |
| 1428 | + ) -> Any: |
| 1429 | + """Get a single IT Dashboard investment by UII (`/api/itdashboard/{uii}/`).""" |
| 1430 | + params: dict[str, Any] = {} |
| 1431 | + if shape is None: |
| 1432 | + shape = ShapeConfig.ITDASHBOARD_INVESTMENTS_COMPREHENSIVE |
| 1433 | + if shape: |
| 1434 | + params["shape"] = shape |
| 1435 | + if flat: |
| 1436 | + params["flat"] = "true" |
| 1437 | + if joiner: |
| 1438 | + params["joiner"] = joiner |
| 1439 | + if flat_lists: |
| 1440 | + params["flat_lists"] = "true" |
| 1441 | + data = self._get(f"/api/itdashboard/{uii}/", params) |
| 1442 | + return self._parse_response_with_shape( |
| 1443 | + data, shape, ITDashboardInvestment, flat, flat_lists, joiner=joiner |
| 1444 | + ) |
| 1445 | + |
1339 | 1446 | # ============================================================================ |
1340 | 1447 | # Vehicles (Awards) |
1341 | 1448 | # ============================================================================ |
|
0 commit comments