Skip to content

Commit f40596a

Browse files
committed
refactor: improve error readability
1 parent 2dd3013 commit f40596a

File tree

1 file changed

+90
-34
lines changed

1 file changed

+90
-34
lines changed

manager-dashboard/user_scripts/generate_coco_from_dropbox.py

Lines changed: 90 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,94 @@
11
# /// script
2+
# requires-python = ">=3.13"
23
# dependencies = [
3-
# "requests<3",
4+
# "httpx~=0.28.1",
5+
# "colorama",
46
# ]
57
# ///
68
from pathlib import Path
7-
from argparse import ArgumentParser
8-
import requests
9+
from colorama import init, Fore
10+
11+
import argparse
12+
import textwrap
13+
import httpx
914
import json
1015
import re
1116

17+
# Initialize colorama
18+
init(autoreset=True)
19+
20+
21+
DROPBOX_PERMISSION_MESSAGE = f"""
22+
{Fore.YELLOW}
23+
----------------------------------------------------
24+
Make sure the dropbox App includes these permissions
25+
- files.metadata.read
26+
- files.content.write
27+
- files.content.read
28+
- sharing.write
29+
- sharing.read
30+
"""
31+
32+
33+
def dropbox_request_error_handler(res: httpx.Response):
34+
try:
35+
res.raise_for_status()
36+
except httpx.HTTPStatusError as http_err:
37+
print(f"{Fore.RED}HTTP error occurred while requesting {res.url}: {http_err}")
38+
print(f"{Fore.RED}Response content: {res.text}")
39+
raise
40+
except httpx.RequestError as req_err:
41+
print(
42+
f"{Fore.RED}An error occurred while making the request to {res.url}: {req_err}"
43+
)
44+
raise
45+
except Exception as err:
46+
print(f"{Fore.RED}An unexpected error occurred: {err}")
47+
raise
48+
finally:
49+
print(DROPBOX_PERMISSION_MESSAGE)
50+
51+
1252
def dropbox_request(endpoint: str, data: object, *, access_token: str):
1353
url = f"https://api.dropboxapi.com/2/{endpoint}"
1454
headers = {
1555
"Authorization": f"Bearer {access_token}",
1656
"Content-Type": "application/json",
1757
}
18-
res = requests.post(
58+
res = httpx.post(
1959
url,
2060
headers=headers,
2161
data=json.dumps(data),
2262
)
23-
res.raise_for_status()
63+
dropbox_request_error_handler(res)
2464
return res.json()
2565

26-
def dropbox_content_request(endpoint: str, path: str, data: object, *, access_token: str):
66+
67+
def dropbox_content_request(
68+
endpoint: str, path: str, data: object, *, access_token: str
69+
):
2770
url = f"https://content.dropboxapi.com/2/{endpoint}"
2871
headers = {
2972
"Authorization": f"Bearer {access_token}",
3073
"Content-Type": "application/octet-stream",
31-
"Dropbox-API-Arg": json.dumps({
32-
"path": path,
33-
"mode": "overwrite", # overwrite if exists
34-
"autorename": False,
35-
"mute": False
36-
})
74+
"Dropbox-API-Arg": json.dumps(
75+
{
76+
"path": path,
77+
"mode": "overwrite", # overwrite if exists
78+
"autorename": False,
79+
"mute": False,
80+
}
81+
),
3782
}
38-
res = requests.post(
83+
res = httpx.post(
3984
url,
4085
headers=headers,
4186
data=json.dumps(data).encode("utf-8"),
4287
)
43-
res.raise_for_status()
88+
dropbox_request_error_handler(res)
4489
return res.json()
4590

91+
4692
def list_all_files(folder_path: str, *, access_token: str):
4793
ALLOWED_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp"}
4894
files = []
@@ -65,11 +111,14 @@ def list_all_files(folder_path: str, *, access_token: str):
65111
files = sorted(files, key=lambda file: file["name"].lower())
66112
# Filter out only files (not folders) that are supported
67113
files = [
68-
file for file in files
69-
if file[".tag"] == "file" and Path(file["name"]).suffix.lower() in ALLOWED_EXTENSIONS
114+
file
115+
for file in files
116+
if file[".tag"] == "file"
117+
and Path(file["name"]).suffix.lower() in ALLOWED_EXTENSIONS
70118
]
71119
return files
72120

121+
73122
def share_file_and_get_links(files, *, access_token: str):
74123
total = len(files)
75124
images = []
@@ -88,34 +137,40 @@ def share_file_and_get_links(files, *, access_token: str):
88137
if res.get("links"):
89138
link = res["links"][0]["url"]
90139
else:
91-
data = {
92-
"path": path,
93-
"settings": {
94-
"requested_visibility": "public"
95-
}
96-
}
140+
data = {"path": path, "settings": {"requested_visibility": "public"}}
97141
res_create = dropbox_request(
98142
"sharing/create_shared_link_with_settings",
99143
data,
100144
access_token=access_token,
101145
)
102146
link = res_create["url"]
103147

104-
raw_url = re.sub(r'&dl=0\b', '', link) + '&raw=1'
148+
raw_url = re.sub(r"&dl=0\b", "", link) + "&raw=1"
105149

106-
images.append({
107-
"id": i + 1,
108-
"file_name": actual_path,
109-
"coco_url": raw_url,
110-
})
150+
images.append(
151+
{
152+
"id": i + 1,
153+
"file_name": actual_path,
154+
"coco_url": raw_url,
155+
}
156+
)
111157
return images
112158

113159

114160
def main():
115-
parser = ArgumentParser(description="Generate COCO file from images folder.")
161+
parser = argparse.ArgumentParser(
162+
description="Generate COCO file from images folder.",
163+
formatter_class=argparse.RawDescriptionHelpFormatter,
164+
epilog=textwrap.dedent(DROPBOX_PERMISSION_MESSAGE),
165+
)
116166
parser.add_argument("access_token", help="Access token for authentication")
117-
parser.add_argument("images_folder", help="Path to the images folder")
118-
parser.add_argument("export_file_name", help="Name of the export COCO file")
167+
parser.add_argument(
168+
"images_folder", help='Path to the images folder in dropbox. eg: "/COCO TEST"'
169+
)
170+
parser.add_argument(
171+
"export_file_name",
172+
help="Name of the export COCO file to be created in dropbox under provided images_folder",
173+
)
119174

120175
args = parser.parse_args()
121176

@@ -141,17 +196,18 @@ def main():
141196
dropbox_content_request(
142197
"files/upload",
143198
absolute_export_file_name,
144-
{ "images": public_images },
199+
{"images": public_images},
145200
access_token=access_token,
146201
)
147202

148203
# Get temporary link
149204
res = dropbox_request(
150205
"files/get_temporary_link",
151-
{ "path": absolute_export_file_name },
206+
{"path": absolute_export_file_name},
152207
access_token=access_token,
153208
)
154-
print(f"COCO file available at {res["link"]}")
209+
print(f"COCO file available at {res['link']}")
210+
155211

156212
if __name__ == "__main__":
157213
main()

0 commit comments

Comments
 (0)