Coverage for /usr/lib/python3.10/site-packages/hyd/backend/tag/api/v1.py: 38%

74 statements  

« prev     ^ index     » next       coverage.py v7.0.3, created at 2023-02-06 00:31 +0000

1from fastapi import APIRouter, Depends, HTTPException, Security, status 

2from sqlalchemy.orm import Session 

3 

4import hyd.backend.project.service as project_service 

5import hyd.backend.version.service as version_service 

6from hyd.backend.db import get_db 

7from hyd.backend.exc import ( 

8 HTTPException_UNKNOWN_PROJECT, 

9 HTTPException_UNKNOWN_VERSION, 

10 PrimaryTagError, 

11 UnknownProjectError, 

12 UnknownTagError, 

13 UnknownVersionError, 

14) 

15from hyd.backend.mount_helper import MountHelper 

16from hyd.backend.security import Scopes 

17from hyd.backend.tag.models import ( 

18 API_V1_CREATE__POST, 

19 API_V1_DELETE__DELETE, 

20 API_V1_LIST__GET, 

21 API_V1_MOVE__PATCH, 

22 TagEntry, 

23 TagResponseSchema, 

24) 

25from hyd.backend.tag.service import ( 

26 create_tag_entry, 

27 delete_tag_entry_by_ref, 

28 read_tag_entry, 

29) 

30from hyd.backend.user.authentication import authenticate_user 

31from hyd.backend.user.models import UserEntry 

32from hyd.backend.util.const import HEADERS 

33from hyd.backend.util.logger import HydLogger 

34from hyd.backend.util.models import NameStr, PrimaryKey 

35 

36LOGGER = HydLogger("TagAPI") 

37 

38v1_router = APIRouter(tags=["tag"]) 

39 

40#################################################################################################### 

41#### HTTP Exceptions 

42#################################################################################################### 

43 

44HTTPException_PRIMARY_TAG = HTTPException( 

45 status_code=status.HTTP_400_BAD_REQUEST, 

46 detail="Only one primary tag allowed!", 

47 headers=HEADERS, 

48) 

49 

50HTTPException_UNKNOWN_TAG = HTTPException( 

51 status_code=status.HTTP_400_BAD_REQUEST, 

52 detail="Unknown tag!", 

53 headers=HEADERS, 

54) 

55 

56 

57#################################################################################################### 

58#### Scope: TAG 

59#################################################################################################### 

60 

61 

62@v1_router.post("/create", responses=API_V1_CREATE__POST) 

63async def _create( 

64 project_id: PrimaryKey, 

65 tag: NameStr, 

66 primary: bool = False, 

67 db: Session = Depends(get_db), 

68 user_entry: UserEntry = Security(authenticate_user, scopes=[Scopes.PROJECT]), 

69): 

70 try: 

71 tag_entry = create_tag_entry(project_id=project_id, tag=tag, primary=primary, db=db) 

72 except UnknownProjectError: 

73 raise HTTPException_UNKNOWN_PROJECT 

74 except PrimaryTagError: 

75 raise HTTPException_PRIMARY_TAG 

76 

77 project_entry = tag_entry.project_entry 

78 LOGGER.info( 

79 "{token_id: %d, user_id: %d, username: %s, project_id: %d, project_name: %s, tag: %s}", 

80 user_entry.session_token_entry.id, 

81 user_entry.id, 

82 user_entry.username, 

83 project_entry.id, 

84 project_entry.name, 

85 tag, 

86 ) 

87 return _tag_entry_to_response_schema(tag_entry) 

88 

89 

90@v1_router.get("/list", responses=API_V1_LIST__GET) 

91async def _list( 

92 project_id: PrimaryKey, 

93 db: Session = Depends(get_db), 

94 user_entry: UserEntry = Security(authenticate_user, scopes=[Scopes.PROJECT]), 

95): 

96 try: 

97 project_entry = project_service.read_project(project_id=project_id, db=db) 

98 except UnknownProjectError: 

99 raise HTTPException_UNKNOWN_PROJECT 

100 

101 return [_tag_entry_to_response_schema(tag_entry) for tag_entry in project_entry.tag_entries] 

102 

103 

104@v1_router.patch("/move", responses=API_V1_MOVE__PATCH) 

105async def _move( 

106 project_id: PrimaryKey, 

107 tag: NameStr, 

108 version: NameStr, 

109 db: Session = Depends(get_db), 

110 user_entry: UserEntry = Security(authenticate_user, scopes=[Scopes.PROJECT]), 

111): 

112 user_entry.check_token_project_permission(project_id=project_id) 

113 

114 try: 

115 tag_entry = read_tag_entry(project_id=project_id, tag=tag, db=db) 

116 except UnknownProjectError: 

117 raise HTTPException_UNKNOWN_PROJECT 

118 except UnknownTagError: 

119 raise HTTPException_UNKNOWN_TAG 

120 

121 # verify that the target version exists 

122 try: 

123 _ = version_service.read_version(project_id=project_id, version=version, db=db) 

124 except UnknownVersionError: 

125 raise HTTPException_UNKNOWN_VERSION 

126 

127 # rm old mount point if one exists 

128 if tag_entry.version is not None: 

129 MountHelper.unmount_tag(project_name=tag_entry.project_entry.name, tag=tag_entry.tag) 

130 

131 tag_entry.version = version 

132 db.commit() 

133 

134 MountHelper.mount_tag(tag_entry=tag_entry) 

135 

136 project_entry = tag_entry.project_entry 

137 LOGGER.info( 

138 "{token_id: %d, user_id: %d, username: %s, project_id: %d, project_name: %s, tag: %s, version: %s}", 

139 user_entry.session_token_entry.id, 

140 user_entry.id, 

141 user_entry.username, 

142 project_entry.id, 

143 project_entry.name, 

144 tag, 

145 version, 

146 ) 

147 return _tag_entry_to_response_schema(tag_entry) 

148 

149 

150@v1_router.delete("/delete", responses=API_V1_DELETE__DELETE) 

151async def _delete( 

152 project_id: PrimaryKey, 

153 tag: NameStr, 

154 db: Session = Depends(get_db), 

155 user_entry: UserEntry = Security(authenticate_user, scopes=[Scopes.PROJECT]), 

156): 

157 user_entry.check_token_project_permission(project_id=project_id) 

158 

159 try: 

160 tag_entry = read_tag_entry(project_id=project_id, tag=tag, db=db) 

161 except UnknownTagError: 

162 raise HTTPException_UNKNOWN_TAG 

163 

164 project_entry = tag_entry.project_entry 

165 

166 # rm old mount point if one exists 

167 if tag_entry.version is not None: 

168 MountHelper.unmount_tag(project_name=project_entry.name, tag=tag_entry.tag) 

169 

170 LOGGER.info( 

171 "{token_id: %d, user_id: %d, username: %s, project_id: %d, project_name: %s, tag: %s}", 

172 user_entry.session_token_entry.id, 

173 user_entry.id, 

174 user_entry.username, 

175 project_entry.id, 

176 project_entry.name, 

177 tag, 

178 ) 

179 

180 response = _tag_entry_to_response_schema(tag_entry) 

181 delete_tag_entry_by_ref(tag_entry=tag_entry, db=db) 

182 return response 

183 

184 

185#################################################################################################### 

186#### Util 

187#################################################################################################### 

188 

189 

190def _tag_entry_to_response_schema(tag_entry: TagEntry) -> TagResponseSchema: 

191 return TagResponseSchema( 

192 project_id=tag_entry.project_id, 

193 tag=tag_entry.tag, 

194 created_at=tag_entry.created_at, 

195 updated_at=tag_entry.updated_at, 

196 version=tag_entry.version, 

197 primary=tag_entry.primary, 

198 )