Coverage for src/fastapi_cloud_cli/api/_models.py: 100%

114 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-11-09 00:25 +0000

1from enum import Enum 1abcdefg

2from typing import Annotated, Literal 1abcdefg

3 

4from pydantic import BaseModel, Field, TypeAdapter 1abcdefg

5 

6 

7class EnvironmentVariable(BaseModel): 1abcdefg

8 name: str 1abcdefg

9 value: str | None = None 1abcdefg

10 is_secret: bool = False 1abcdefg

11 updated_at: str | None = None 1abcdefg

12 

13 

14class EnvironmentVariableResponse(BaseModel): 1abcdefg

15 data: list[EnvironmentVariable] 1abcdefg

16 

17 

18class EnvironmentVariableCreatePayload(BaseModel): 1abcdefg

19 value: str 1abcdefg

20 is_secret: bool = False 1abcdefg

21 

22 

23class AppLogEntry(BaseModel): 1abcdefg

24 timestamp: str 1abcdefg

25 message: str 1abcdefg

26 level: str 1abcdefg

27 

28 

29class BuildLogLineGeneric(BaseModel): 1abcdefg

30 type: Literal["complete", "failed", "timeout", "heartbeat"] 1abcdefg

31 id: str | None = None 1abcdefg

32 

33 

34class BuildLogLineMessage(BaseModel): 1abcdefg

35 type: Literal["message"] = "message" 1abcdefg

36 message: str 1abcdefg

37 id: str | None = None 1abcdefg

38 

39 

40class BuildFailure(BaseModel): 1abcdefg

41 error_code: str 1abcdefg

42 error_title: str 1abcdefg

43 error_message: str 1abcdefg

44 error_hint: str 1abcdefg

45 

46 

47BuildLogLine = BuildLogLineMessage | BuildLogLineGeneric 1abcdefg

48BuildLogAdapter: TypeAdapter[BuildLogLine] = TypeAdapter( 1abcdefg

49 Annotated[BuildLogLine, Field(discriminator="type")] 

50) 

51 

52 

53class CustomDomainStatus(str, Enum): 1abcdefg

54 internal_dcv_pending = "internal_dcv_pending" 1abcdefg

55 internal_dcv_missing = "internal_dcv_missing" 1abcdefg

56 internal_dcv_invalid = "internal_dcv_invalid" 1abcdefg

57 internal_dcv_timeout = "internal_dcv_timeout" 1abcdefg

58 internal_dcv_revoked = "internal_dcv_revoked" 1abcdefg

59 external_dcv_pending = "external_dcv_pending" 1abcdefg

60 external_dcv_proxied = "external_dcv_proxied" 1abcdefg

61 external_dcv_secured = "external_dcv_secured" 1abcdefg

62 external_dcv_blocked = "external_dcv_blocked" 1abcdefg

63 external_dcv_timeout = "external_dcv_timeout" 1abcdefg

64 origin_setup_pending = "origin_setup_pending" 1abcdefg

65 origin_setup_missing = "origin_setup_missing" 1abcdefg

66 origin_setup_invalid = "origin_setup_invalid" 1abcdefg

67 origin_setup_timeout = "origin_setup_timeout" 1abcdefg

68 origin_setup_success = "origin_setup_success" 1abcdefg

69 origin_setup_removed = "origin_setup_removed" 1abcdefg

70 

71 

72class CustomDomainRecord(BaseModel): 1abcdefg

73 type: Literal["TXT", "CNAME", "A"] 1abcdefg

74 name: str | None 1abcdefg

75 value: str | None 1abcdefg

76 

77 

78class CustomDomain(BaseModel): 1abcdefg

79 id: str 1abcdefg

80 name: str 1abcdefg

81 status: CustomDomainStatus 1abcdefg

82 setup_in_progress: bool 1abcdefg

83 setup_failed: bool 1abcdefg

84 setup_successful: bool 1abcdefg

85 is_using_pre_validation: bool 1abcdefg

86 dns_records: list[CustomDomainRecord] 1abcdefg

87 created_at: str 1abcdefg

88 updated_at: str 1abcdefg

89 setup_started_at: str | None 1abcdefg

90 setup_checked_at: str | None 1abcdefg

91 app_id: str 1abcdefg

92 

93 

94class CustomDomainsAPIResponse(BaseModel): 1abcdefg

95 data: list[CustomDomain] 1abcdefg

96 count: int 1abcdefg

97 

98 

99class DeploymentStatus(str, Enum): 1abcdefg

100 waiting_upload = "waiting_upload" 1abcdefg

101 upload_cancelled = "upload_cancelled" 1abcdefg

102 ready_for_build = "ready_for_build" 1abcdefg

103 build_skipped_filtered = "build_skipped_filtered" 1abcdefg

104 build_skipped_superseded = "build_skipped_superseded" 1abcdefg

105 building = "building" 1abcdefg

106 extracting = "extracting" 1abcdefg

107 extracting_failed = "extracting_failed" 1abcdefg

108 extracting_failed_archive_too_large = "extracting_failed_archive_too_large" 1abcdefg

109 building_image = "building_image" 1abcdefg

110 building_image_failed = "building_image_failed" 1abcdefg

111 building_image_failed_timeout = "building_image_failed_timeout" 1abcdefg

112 deploying = "deploying" 1abcdefg

113 deploying_skipped = "deploying_skipped" 1abcdefg

114 deploying_failed = "deploying_failed" 1abcdefg

115 verifying = "verifying" 1abcdefg

116 verifying_failed = "verifying_failed" 1abcdefg

117 verification_failed_oom = "verification_failed_oom" 1abcdefg

118 verifying_skipped = "verifying_skipped" 1abcdefg

119 success = "success" 1abcdefg

120 degraded_oom = "degraded_oom" 1abcdefg

121 degraded = "degraded" 1abcdefg

122 expired = "expired" 1abcdefg

123 failed = "failed" 1abcdefg

124 

125 unknown = "unknown" 1abcdefg

126 

127 @classmethod 1abcdefg

128 def _missing_(cls, value: object) -> "DeploymentStatus": 1abcdefg

129 return cls.unknown 1hijklmnopqrstu

130 

131 @classmethod 1abcdefg

132 def to_human_readable(cls, status: "DeploymentStatus") -> str: 1abcdefg

133 return { 1vwxyzABCDEFGHIJKLMNOPQRSTUVW

134 cls.waiting_upload: "Awaiting Upload", 

135 cls.upload_cancelled: "Upload Cancelled", 

136 cls.ready_for_build: "Build Queued", 

137 cls.build_skipped_filtered: "Build Skipped (Filtered)", 

138 cls.build_skipped_superseded: "Build Skipped (Superseded)", 

139 cls.building: "Building", 

140 cls.extracting: "Extracting Upload", 

141 cls.extracting_failed: "Extraction Failed", 

142 cls.extracting_failed_archive_too_large: "Archive Too Large", 

143 cls.building_image: "Building Image", 

144 cls.building_image_failed: "Build Failed", 

145 cls.building_image_failed_timeout: "Build Timed Out", 

146 cls.deploying: "Deploying Image", 

147 cls.deploying_skipped: "Deployment Skipped", 

148 cls.deploying_failed: "Deployment Failed", 

149 cls.verifying: "Verifying Readiness", 

150 cls.verifying_failed: "Verification Failed", 

151 cls.verification_failed_oom: "Verification Failed (OOM)", 

152 cls.verifying_skipped: "Verification Skipped", 

153 cls.success: "Ready", 

154 cls.degraded_oom: "Degraded (OOM)", 

155 cls.degraded: "Degraded", 

156 cls.expired: "Expired", 

157 cls.failed: "Failed", 

158 cls.unknown: "Unknown", 

159 }[status] 

160 

161 

162class Deployment(BaseModel): 1abcdefg

163 id: str 1abcdefg

164 app_id: str 1abcdefg

165 slug: str 1abcdefg

166 status: DeploymentStatus 1abcdefg

167 created_at: str 1abcdefg

168 url: str | None = None 1abcdefg

169 dashboard_url: str | None = None 1abcdefg

170 failure: BuildFailure | None = None 1abcdefg

171 

172 

173SUCCESSFUL_STATUSES = {DeploymentStatus.success, DeploymentStatus.verifying_skipped} 1abcdefg

174BUILD_FAILED_STATUSES = { 1abcdefg

175 DeploymentStatus.building_image_failed, 

176 DeploymentStatus.building_image_failed_timeout, 

177 DeploymentStatus.extracting_failed, 

178 DeploymentStatus.extracting_failed_archive_too_large, 

179} 

180FAILED_STATUSES = BUILD_FAILED_STATUSES | { 1abcdefg

181 DeploymentStatus.build_skipped_filtered, 

182 DeploymentStatus.build_skipped_superseded, 

183 DeploymentStatus.failed, 

184 DeploymentStatus.verifying_failed, 

185 DeploymentStatus.verification_failed_oom, 

186 DeploymentStatus.deploying_failed, 

187 DeploymentStatus.deploying_skipped, 

188 DeploymentStatus.degraded, 

189 DeploymentStatus.degraded_oom, 

190 DeploymentStatus.expired, 

191} 

192TERMINAL_STATUSES = SUCCESSFUL_STATUSES | FAILED_STATUSES 1abcdefg