Coverage for /usr/lib/python3.10/site-packages/hyd/backend/project/api/v1.py: 51%
61 statements
« prev ^ index » next coverage.py v7.0.3, created at 2023-01-05 15:47 +0000
« prev ^ index » next coverage.py v7.0.3, created at 2023-01-05 15:47 +0000
1import shutil
2from pathlib import Path
3from typing import Union
5from fastapi import APIRouter, Depends, HTTPException, Security, status
6from sqlalchemy.orm import Session
8from hyd.backend.db import get_db
9from hyd.backend.exc import (
10 HTTPException_UNKNOWN_PROJECT,
11 NameStrError,
12 UnknownProjectError,
13)
14from hyd.backend.project.models import (
15 API_V1_CREATE__POST,
16 API_V1_DELETE__DELETE,
17 API_V1_GET__GET,
18 API_V1_LIST__GET,
19 ProjectEntry,
20 ProjectResponseSchema,
21)
22from hyd.backend.project.service import (
23 create_project,
24 delete_project_by_ref,
25 read_project,
26 read_projects,
27)
28from hyd.backend.security import Scopes
29from hyd.backend.tag.models import TagEntry
30from hyd.backend.user.authentication import authenticate_user
31from hyd.backend.user.models import UserEntry
32from hyd.backend.util.const import HEADERS, PATH_PROJECTS
33from hyd.backend.util.logger import HydLogger
34from hyd.backend.util.models import NameStr, PrimaryKey
35from hyd.backend.version.api.v1 import version_rm_mount_and_files
36from hyd.backend.version.models import VersionEntry
38LOGGER = HydLogger("ProjectAPI")
40v1_router = APIRouter(tags=["project"])
42####################################################################################################
43#### HTTP Exceptions
44####################################################################################################
46HTTPException_PROJECT_NAME_NOT_AVAILABLE = HTTPException(
47 status_code=status.HTTP_400_BAD_REQUEST,
48 detail="Project name not available!",
49 headers=HEADERS,
50)
52####################################################################################################
53#### Scope: PROJECT
54####################################################################################################
57@v1_router.post("/create", responses=API_V1_CREATE__POST)
58async def _create(
59 name: NameStr,
60 db: Session = Depends(get_db),
61 user_entry: UserEntry = Security(authenticate_user, scopes=[Scopes.PROJECT]),
62):
63 try:
64 project_entry = create_project(name=name, db=db)
65 except NameStrError:
66 raise HTTPException_PROJECT_NAME_NOT_AVAILABLE
68 LOGGER.info(
69 "{token_id: %d, user_id: %d, username: %s, project_id: %d, project_name: %s}",
70 user_entry.session_token_entry.id,
71 user_entry.id,
72 user_entry.username,
73 project_entry.id,
74 name,
75 )
76 return _project_entry_to_response_schema(project_entry)
79@v1_router.get("/list", responses=API_V1_LIST__GET)
80async def _list(
81 db: Session = Depends(get_db),
82 user_entry: UserEntry = Security(authenticate_user, scopes=[Scopes.PROJECT]),
83):
84 project_entries = read_projects(db=db)
85 return [_project_entry_to_response_schema(project_entry) for project_entry in project_entries]
88@v1_router.get("/get", responses=API_V1_GET__GET)
89async def _get(
90 project_id: Union[int, str],
91 db: Session = Depends(get_db),
92 user_entry: UserEntry = Security(authenticate_user, scopes=[Scopes.PROJECT]),
93):
94 user_entry.check_token_project_permission(project_id=project_id)
96 try:
97 project_entry = read_project(project_id=project_id, db=db)
98 except UnknownProjectError:
99 raise HTTPException_UNKNOWN_PROJECT
101 return _project_entry_to_response_schema(project_entry)
104@v1_router.delete("/delete", responses=API_V1_DELETE__DELETE)
105async def _delete(
106 project_id: PrimaryKey,
107 db: Session = Depends(get_db),
108 user_entry: UserEntry = Security(authenticate_user, scopes=[Scopes.PROJECT]),
109):
110 user_entry.check_token_project_permission(project_id=project_id)
112 try:
113 project_entry = read_project(project_id=project_id, db=db)
114 except UnknownProjectError:
115 raise HTTPException_UNKNOWN_PROJECT
117 for version_entry in project_entry.version_entries:
118 version_rm_mount_and_files(version_entry=version_entry, db=db)
120 shutil.rmtree(_path_to_project(project_id))
122 LOGGER.info(
123 "{token_id: %d, user_id: %d, username: %s, project_id: %d, project_name: %s}",
124 user_entry.session_token_entry.id,
125 user_entry.id,
126 user_entry.username,
127 project_entry.id,
128 project_entry.name,
129 )
131 response = _project_entry_to_response_schema(project_entry)
132 delete_project_by_ref(project_entry=project_entry, db=db)
133 return response
136####################################################################################################
137#### Util
138####################################################################################################
141def _path_to_project(project_id: PrimaryKey) -> Path:
142 return PATH_PROJECTS / str(project_id)
145def _project_entry_to_response_schema(project_entry: ProjectEntry) -> ProjectResponseSchema:
146 version_entries: list[VersionEntry] = project_entry.version_entries
147 tag_entries: list[TagEntry] = project_entry.tag_entries
149 return ProjectResponseSchema(
150 id=project_entry.id,
151 name=project_entry.name,
152 created_at=project_entry.created_at,
153 versions=[version_entry.version for version_entry in version_entries],
154 tags=[tag_entry.tag for tag_entry in tag_entries],
155 )