|
18 | 18 | from sqlalchemy.exc import IntegrityError |
19 | 19 | from sqlalchemy.orm.exc import ObjectDeletedError |
20 | 20 |
|
| 21 | +from .schemas_v2 import BatchErrorSchema, ProjectSchema as ProjectSchemaV2 |
21 | 22 | from ..app import db |
22 | 23 | from ..auth import auth_required |
23 | 24 | from ..auth.models import User |
24 | 25 | from .errors import ( |
25 | 26 | AnotherUploadRunning, |
| 27 | + BatchLimitError, |
26 | 28 | BigChunkError, |
27 | 29 | DataSyncError, |
28 | 30 | DiffDownloadError, |
|
43 | 45 | project_version_created, |
44 | 46 | push_finished, |
45 | 47 | ) |
46 | | -from .permissions import ProjectPermissions, require_project_by_uuid, projects_query |
| 48 | +from .permissions import ( |
| 49 | + ProjectPermissions, |
| 50 | + check_project_permissions, |
| 51 | + require_project_by_uuid, |
| 52 | + projects_query, |
| 53 | +) |
47 | 54 | from .public_api_controller import catch_sync_failure |
48 | 55 | from .schemas import ( |
49 | 56 | ProjectMemberSchema, |
@@ -529,3 +536,40 @@ def list_workspace_projects(workspace_id, page, per_page, order_params=None, q=N |
529 | 536 |
|
530 | 537 | data = ProjectSchemaV2(many=True).dump(result) |
531 | 538 | return jsonify(projects=data, count=total, page=page, per_page=per_page), 200 |
| 539 | + |
| 540 | + |
| 541 | +def list_batch_projects(body): |
| 542 | + """List projects by given list of UUIDs. Limit to 100 projects per request. |
| 543 | +
|
| 544 | + :param ids: List of project UUIDs |
| 545 | + :type ids: List[str] |
| 546 | + :rtype: Dict[str: List[Project]] |
| 547 | + """ |
| 548 | + ids = list(dict.fromkeys(body.get("ids", []))) |
| 549 | + # remove duplicates while preserving the order |
| 550 | + max_batch = current_app.config.get("MAX_BATCH_SIZE", 100) |
| 551 | + if len(ids) > max_batch: |
| 552 | + return BatchLimitError().response(400) |
| 553 | + |
| 554 | + projects = current_app.project_handler.get_projects_by_uuids(ids) |
| 555 | + by_id = {str(project.id): project for project in projects} |
| 556 | + |
| 557 | + filtered_projects = [] |
| 558 | + for uuid in ids: |
| 559 | + project = by_id.get(uuid) |
| 560 | + |
| 561 | + if not project: |
| 562 | + filtered_projects.append( |
| 563 | + BatchErrorSchema().dump({"id": uuid, "error": 404}) |
| 564 | + ) |
| 565 | + continue |
| 566 | + |
| 567 | + err = check_project_permissions(project, ProjectPermissions.Read) |
| 568 | + if err is not None: |
| 569 | + filtered_projects.append( |
| 570 | + BatchErrorSchema().dump({"id": uuid, "error": err}) |
| 571 | + ) |
| 572 | + else: |
| 573 | + filtered_projects.append(ProjectSchemaV2().dump(project)) |
| 574 | + |
| 575 | + return jsonify(projects=filtered_projects), 200 |
0 commit comments