Coverage for src/fastapi_cloud_cli/commands/deploy/upload.py: 100%

53 statements  

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

1import logging 2/c:c;c=c?c@c[c

2from pathlib import Path 2/c:c;c=c?c@c[c

3from typing import BinaryIO, cast 2/c:c;c=c?c@c[c

4 

5from httpx import Client 2/c:c;c=c?c@c[c

6from pydantic import BaseModel 2/c:c;c=c?c@c[c

7from rich_toolkit.progress import Progress 2/c:c;c=c?c@c[c

8 

9from fastapi_cloud_cli.api import APIClient 2/c:c;c=c?c@c[c

10from fastapi_cloud_cli.commands.deploy.cloud import CreateDeploymentResponse 2/c:c;c=c?c@c[c

11from fastapi_cloud_cli.utils.progress_file import ProgressFile 2/c:c;c=c?c@c[c

12 

13logger = logging.getLogger(__name__) 2/c:c;c=c?c@c[c

14 

15 

16class RequestUploadResponse(BaseModel): 2/c:c;c=c?c@c[c

17 url: str 2/c:c;c=c?c@c[c

18 fields: dict[str, str] 2/c:c;c=c?c@c[c

19 

20 

21def _cancel_upload(client: APIClient, deployment_id: str) -> None: 2/c:c;c=c?c@c[c

22 logger.debug("Cancelling upload for deployment: %s", deployment_id) 2~c]cad^cbd_ccd`cdd{ced|cfd}c

23 

24 try: 2~c]cad^cbd_ccd`cdd{ced|cfd}c

25 response = client.post(f"/deployments/{deployment_id}/upload-cancelled") 2~c]cad^cbd_ccd`cdd{ced|cfd}c

26 response.raise_for_status() 2~c]cad^cbd_ccd`cdd{ced|cfd}c

27 

28 logger.debug("Upload cancellation notification sent successfully") 2~cadbdcdddedfd

29 except Exception as e: 2]c^c_c`c{c|c}c

30 logger.debug("Failed to notify server about upload cancellation: %s", e) 2]c^c_c`c{c|c}c

31 

32 

33def _format_size(size_in_bytes: int) -> str: 2/c:c;c=c?c@c[c

34 if size_in_bytes >= 1024 * 1024: 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

35 return f"{size_in_bytes / (1024 * 1024):.2f} MB" 1abcdefg

36 elif size_in_bytes >= 1024: 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

37 return f"{size_in_bytes / 1024:.2f} KB" 2D a # b ibc Qbd ;be vcf 3cg

38 else: 

39 return f"{size_in_bytes} bytes" 2h i j k l m n o p (cq r s t u v w x y z A B C E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c4c5c6c7c8c9c!c#c$cg %c'c

40 

41 

42def _upload_deployment( 2/c:c;c=c?c@c[c

43 fastapi_client: APIClient, 

44 deployment_id: str, 

45 archive_path: Path, 

46 archive_size: int, 

47 progress: Progress, 

48) -> CreateDeploymentResponse: 

49 archive_size_str = _format_size(archive_size) 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

50 

51 progress.log(f"Uploading deployment ({archive_size_str})...") 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

52 logger.debug( 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

53 "Starting deployment upload for deployment: %s", 

54 deployment_id, 

55 ) 

56 logger.debug("Archive path: %s, size: %s bytes", archive_path, archive_size) 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

57 

58 def progress_callback(bytes_read: int) -> None: 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

59 progress.log( 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

60 f"Uploading deployment ({_format_size(bytes_read)} of {archive_size_str})..." 

61 ) 

62 

63 logger.debug("Requesting upload URL from API") 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

64 response = fastapi_client.post(f"/deployments/{deployment_id}/upload") 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

65 response.raise_for_status() 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

66 

67 upload_data = RequestUploadResponse.model_validate(response.json()) 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

68 logger.debug("Received upload URL: %s", upload_data.url) 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

69 

70 logger.debug("Starting file upload to S3") 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

71 with Client() as s3_client: 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

72 with open(archive_path, "rb") as archive_file: 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

73 archive_file_with_progress = ProgressFile( 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

74 archive_file, progress_callback=progress_callback 

75 ) 

76 upload_response = s3_client.post( 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

77 upload_data.url, 

78 data=upload_data.fields, 

79 files={"file": cast(BinaryIO, archive_file_with_progress)}, 

80 ) 

81 

82 if upload_response.is_error: 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

83 logger.debug("File upload failed with response: %s", upload_response.text) 2(c)c*c+c,c-c.c

84 

85 upload_response.raise_for_status() 2h i j k l m n o p (cq r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X )cY Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ *c` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCb+cDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b,c#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchc-cicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPc.cQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

86 logger.debug("File upload completed successfully") 2h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

87 

88 logger.debug("Notifying API that upload is complete") 2h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

89 notify_response = fastapi_client.post( 2h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

90 f"/deployments/{deployment_id}/upload-complete" 

91 ) 

92 

93 notify_response.raise_for_status() 2h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

94 logger.debug("Upload notification sent successfully") 2h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c

95 

96 return CreateDeploymentResponse.model_validate(notify_response.json()) 2h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M a N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - b . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbc sbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZbd 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{be |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcf FcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$cg %c'c