From 2dd3013839511e70e49910065bd175a4f73791e5 Mon Sep 17 00:00:00 2001 From: Keyur Khadka Date: Wed, 30 Jul 2025 18:12:24 +0545 Subject: [PATCH 1/8] docs(coco): update readme.md --- manager-dashboard/user_scripts/README.md | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 manager-dashboard/user_scripts/README.md diff --git a/manager-dashboard/user_scripts/README.md b/manager-dashboard/user_scripts/README.md new file mode 100644 index 00000000..fbc18dec --- /dev/null +++ b/manager-dashboard/user_scripts/README.md @@ -0,0 +1,36 @@ +## DropBox +### Prerequisites + +- Create account: https://www.dropbox.com/register +- Create new App: https://www.dropbox.com/developers/apps + - Choose an API: Scoped access + - Choose the type of access you need: Full Dropbox + - Name your app: Mapswipe COCO +- Update `Permission type` + - Go to the app settings + - Click **Scoped App** + - Select + - files.metadata.read + - files.content.write + - files.content.read + - sharing.write + - sharing.read + - Submit +- Generate new access token: + - Go to the app settings + - Click **Generated access token** +- Install uv on your system: https://docs.astral.sh/uv/getting-started/installation/ +- Download the [generate_coco_from_dropbox.py](user_scripts/generate_coco_from_dropbox.py) script + +- Run the script + ```bash + # Help + uv run generate_coco_dropbox.py --help + + # Sample + uv run generate_coco_dropbox.py "DROPBOX_ACCESS_TOKEN" "FOLDER_PATH_IN_DROPBOX" "DESTINATION_EXPORT_FILE_NAME_IN_DROPBOX" + + # Example + uv run generate_coco_dropbox.py sl.yourAccessTokenHere “/COCO TEST” “coco_export.json” + ``` +- Download the coco_export.json from the dropbox From f40596a7c926ee185005c1eba0e7b2d93efe2999 Mon Sep 17 00:00:00 2001 From: Keyur Date: Wed, 30 Jul 2025 18:14:58 +0545 Subject: [PATCH 2/8] refactor: improve error readability --- .../generate_coco_from_dropbox.py | 124 +++++++++++++----- 1 file changed, 90 insertions(+), 34 deletions(-) diff --git a/manager-dashboard/user_scripts/generate_coco_from_dropbox.py b/manager-dashboard/user_scripts/generate_coco_from_dropbox.py index 6f3bedfe..47249d2d 100644 --- a/manager-dashboard/user_scripts/generate_coco_from_dropbox.py +++ b/manager-dashboard/user_scripts/generate_coco_from_dropbox.py @@ -1,48 +1,94 @@ # /// script +# requires-python = ">=3.13" # dependencies = [ -# "requests<3", +# "httpx~=0.28.1", +# "colorama", # ] # /// from pathlib import Path -from argparse import ArgumentParser -import requests +from colorama import init, Fore + +import argparse +import textwrap +import httpx import json import re +# Initialize colorama +init(autoreset=True) + + +DROPBOX_PERMISSION_MESSAGE = f""" +{Fore.YELLOW} +---------------------------------------------------- +Make sure the dropbox App includes these permissions +- files.metadata.read +- files.content.write +- files.content.read +- sharing.write +- sharing.read +""" + + +def dropbox_request_error_handler(res: httpx.Response): + try: + res.raise_for_status() + except httpx.HTTPStatusError as http_err: + print(f"{Fore.RED}HTTP error occurred while requesting {res.url}: {http_err}") + print(f"{Fore.RED}Response content: {res.text}") + raise + except httpx.RequestError as req_err: + print( + f"{Fore.RED}An error occurred while making the request to {res.url}: {req_err}" + ) + raise + except Exception as err: + print(f"{Fore.RED}An unexpected error occurred: {err}") + raise + finally: + print(DROPBOX_PERMISSION_MESSAGE) + + def dropbox_request(endpoint: str, data: object, *, access_token: str): url = f"https://api.dropboxapi.com/2/{endpoint}" headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json", } - res = requests.post( + res = httpx.post( url, headers=headers, data=json.dumps(data), ) - res.raise_for_status() + dropbox_request_error_handler(res) return res.json() -def dropbox_content_request(endpoint: str, path: str, data: object, *, access_token: str): + +def dropbox_content_request( + endpoint: str, path: str, data: object, *, access_token: str +): url = f"https://content.dropboxapi.com/2/{endpoint}" headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/octet-stream", - "Dropbox-API-Arg": json.dumps({ - "path": path, - "mode": "overwrite", # overwrite if exists - "autorename": False, - "mute": False - }) + "Dropbox-API-Arg": json.dumps( + { + "path": path, + "mode": "overwrite", # overwrite if exists + "autorename": False, + "mute": False, + } + ), } - res = requests.post( + res = httpx.post( url, headers=headers, data=json.dumps(data).encode("utf-8"), ) - res.raise_for_status() + dropbox_request_error_handler(res) return res.json() + def list_all_files(folder_path: str, *, access_token: str): ALLOWED_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp"} files = [] @@ -65,11 +111,14 @@ def list_all_files(folder_path: str, *, access_token: str): files = sorted(files, key=lambda file: file["name"].lower()) # Filter out only files (not folders) that are supported files = [ - file for file in files - if file[".tag"] == "file" and Path(file["name"]).suffix.lower() in ALLOWED_EXTENSIONS + file + for file in files + if file[".tag"] == "file" + and Path(file["name"]).suffix.lower() in ALLOWED_EXTENSIONS ] return files + def share_file_and_get_links(files, *, access_token: str): total = len(files) images = [] @@ -88,12 +137,7 @@ def share_file_and_get_links(files, *, access_token: str): if res.get("links"): link = res["links"][0]["url"] else: - data = { - "path": path, - "settings": { - "requested_visibility": "public" - } - } + data = {"path": path, "settings": {"requested_visibility": "public"}} res_create = dropbox_request( "sharing/create_shared_link_with_settings", data, @@ -101,21 +145,32 @@ def share_file_and_get_links(files, *, access_token: str): ) link = res_create["url"] - raw_url = re.sub(r'&dl=0\b', '', link) + '&raw=1' + raw_url = re.sub(r"&dl=0\b", "", link) + "&raw=1" - images.append({ - "id": i + 1, - "file_name": actual_path, - "coco_url": raw_url, - }) + images.append( + { + "id": i + 1, + "file_name": actual_path, + "coco_url": raw_url, + } + ) return images def main(): - parser = ArgumentParser(description="Generate COCO file from images folder.") + parser = argparse.ArgumentParser( + description="Generate COCO file from images folder.", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=textwrap.dedent(DROPBOX_PERMISSION_MESSAGE), + ) parser.add_argument("access_token", help="Access token for authentication") - parser.add_argument("images_folder", help="Path to the images folder") - parser.add_argument("export_file_name", help="Name of the export COCO file") + parser.add_argument( + "images_folder", help='Path to the images folder in dropbox. eg: "/COCO TEST"' + ) + parser.add_argument( + "export_file_name", + help="Name of the export COCO file to be created in dropbox under provided images_folder", + ) args = parser.parse_args() @@ -141,17 +196,18 @@ def main(): dropbox_content_request( "files/upload", absolute_export_file_name, - { "images": public_images }, + {"images": public_images}, access_token=access_token, ) # Get temporary link res = dropbox_request( "files/get_temporary_link", - { "path": absolute_export_file_name }, + {"path": absolute_export_file_name}, access_token=access_token, ) - print(f"COCO file available at {res["link"]}") + print(f"COCO file available at {res['link']}") + if __name__ == "__main__": main() From f8c9ee7039138ee4085cf27b91e9f4027fce53d1 Mon Sep 17 00:00:00 2001 From: Keyur Date: Wed, 30 Jul 2025 18:18:06 +0545 Subject: [PATCH 3/8] fixup! docs(coco): update readme.md --- manager-dashboard/user_scripts/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/manager-dashboard/user_scripts/README.md b/manager-dashboard/user_scripts/README.md index fbc18dec..4be621c0 100644 --- a/manager-dashboard/user_scripts/README.md +++ b/manager-dashboard/user_scripts/README.md @@ -21,7 +21,6 @@ - Click **Generated access token** - Install uv on your system: https://docs.astral.sh/uv/getting-started/installation/ - Download the [generate_coco_from_dropbox.py](user_scripts/generate_coco_from_dropbox.py) script - - Run the script ```bash # Help From 747b97eb4469c7b29f86b38ff006b8c0f22899eb Mon Sep 17 00:00:00 2001 From: Keyur Khadka Date: Wed, 30 Jul 2025 18:27:41 +0545 Subject: [PATCH 4/8] Update README.md --- manager-dashboard/user_scripts/README.md | 59 +++++++++++++++++++----- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/manager-dashboard/user_scripts/README.md b/manager-dashboard/user_scripts/README.md index 4be621c0..4a4a30e0 100644 --- a/manager-dashboard/user_scripts/README.md +++ b/manager-dashboard/user_scripts/README.md @@ -1,4 +1,37 @@ +## Google Drive + +### Prerequisites +- You must have a Google account +- Your image files should be stored in a public Google Drive folder +- You have access to Google Apps Script via https://script.google.com + +### Creation Steps +- Create a Google Apps script project + - Go to https://script.google.com + - Click on "New Project" + - Rename the project name to your desired project name +- Paste the utility script + - Replace any existing default code the code from this utility file +- Replace Placeholder Values + - Replace 'your_coco_export.json' with your output filename + - Replace 'your_public_folder_id' with the ID of your Google Drive folder + +> The folder ID is the alphanumeric string that appears after "/folders/" in the URL.\ +> Eg: https://drive.google.com/drive/folders/1prcCevijN5mubTllB2kr5ki1gjh_IO4u?usp=sharing + +### Run the script + +- Save the project to Drive using the floppy disk 💾icon +- Press Run +- Accept the authorization prompts the first time you run the script + +### View COCO JSON Output +- Go to View > Logs +- Copy the Google Drive URL where the coco file is created and generated +- Download the json file + ## DropBox + ### Prerequisites - Create account: https://www.dropbox.com/register @@ -21,15 +54,17 @@ - Click **Generated access token** - Install uv on your system: https://docs.astral.sh/uv/getting-started/installation/ - Download the [generate_coco_from_dropbox.py](user_scripts/generate_coco_from_dropbox.py) script -- Run the script - ```bash - # Help - uv run generate_coco_dropbox.py --help - - # Sample - uv run generate_coco_dropbox.py "DROPBOX_ACCESS_TOKEN" "FOLDER_PATH_IN_DROPBOX" "DESTINATION_EXPORT_FILE_NAME_IN_DROPBOX" - - # Example - uv run generate_coco_dropbox.py sl.yourAccessTokenHere “/COCO TEST” “coco_export.json” - ``` -- Download the coco_export.json from the dropbox + +### Run the script +```bash +# Help +uv run generate_coco_dropbox.py --help + +# Sample +uv run generate_coco_dropbox.py "DROPBOX_ACCESS_TOKEN" "FOLDER_PATH_IN_DROPBOX" "DESTINATION_EXPORT_FILE_NAME_IN_DROPBOX" + +# Example +uv run generate_coco_dropbox.py sl.yourAccessTokenHere “/COCO TEST” “coco_export.json” +``` + +Download the coco_export.json from the dropbox From 91e6e0da290105fe3a92984264cbd06a998c6c07 Mon Sep 17 00:00:00 2001 From: Keyur Khadka Date: Wed, 30 Jul 2025 19:11:22 +0545 Subject: [PATCH 5/8] Update README.md --- manager-dashboard/user_scripts/README.md | 59 ++++++++++++------------ 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/manager-dashboard/user_scripts/README.md b/manager-dashboard/user_scripts/README.md index 4a4a30e0..2eb9d0d3 100644 --- a/manager-dashboard/user_scripts/README.md +++ b/manager-dashboard/user_scripts/README.md @@ -1,4 +1,8 @@ +## Description +This read me will guide you on how to create a COCO file using the utility script for Google Drive and DropBox + ## Google Drive +You can find the utility script for Google Drive here: [generate_coco_from_drive.js](./generate_coco_from_drive.js) ### Prerequisites - You must have a Google account @@ -13,36 +17,32 @@ - Paste the utility script - Replace any existing default code the code from this utility file - Replace Placeholder Values - - Replace 'your_coco_export.json' with your output filename - - Replace 'your_public_folder_id' with the ID of your Google Drive folder - + - Replace `your_coco_export.json` with your output filename + - Replace `your_public_folder_id` with the ID of your Google Drive folder > The folder ID is the alphanumeric string that appears after "/folders/" in the URL.\ -> Eg: https://drive.google.com/drive/folders/1prcCevijN5mubTllB2kr5ki1gjh_IO4u?usp=sharing - -### Run the script - -- Save the project to Drive using the floppy disk 💾icon -- Press Run -- Accept the authorization prompts the first time you run the script - -### View COCO JSON Output -- Go to View > Logs -- Copy the Google Drive URL where the coco file is created and generated -- Download the json file +> Eg: drive.google.com/drive/folders/**1prcCevijN5mubTllB2kr5ki1gjh_IO4u**?usp=sharing +- Run the script + - Save the project to Drive using the floppy disk 💾 icon + - Press Run + - Accept the authorization prompts the first time you run the script +- View COCO JSON Output + - Go to View > Logs + - Copy the Google Drive URL where the coco file is created and generated + - Download the json file ## DropBox +You can find the utility script for DropBox here: [generate_coco_from_dropbox.py](./generate_coco_from_dropbox.py) ### Prerequisites - - Create account: https://www.dropbox.com/register - Create new App: https://www.dropbox.com/developers/apps - Choose an API: Scoped access - Choose the type of access you need: Full Dropbox - - Name your app: Mapswipe COCO + - Name your app: `your-app-name` - Update `Permission type` - Go to the app settings - Click **Scoped App** - - Select + - Tick the following - files.metadata.read - files.content.write - files.content.read @@ -53,18 +53,19 @@ - Go to the app settings - Click **Generated access token** - Install uv on your system: https://docs.astral.sh/uv/getting-started/installation/ -- Download the [generate_coco_from_dropbox.py](user_scripts/generate_coco_from_dropbox.py) script +- Download the [generate_coco_from_dropbox.py](./generate_coco_from_dropbox.py) script -### Run the script +### Creation Steps +- Run the script ```bash -# Help -uv run generate_coco_dropbox.py --help - -# Sample -uv run generate_coco_dropbox.py "DROPBOX_ACCESS_TOKEN" "FOLDER_PATH_IN_DROPBOX" "DESTINATION_EXPORT_FILE_NAME_IN_DROPBOX" - -# Example -uv run generate_coco_dropbox.py sl.yourAccessTokenHere “/COCO TEST” “coco_export.json” + # Help + uv run generate_coco_dropbox.py --help + + # Sample + uv run generate_coco_dropbox.py "DROPBOX_ACCESS_TOKEN" "FOLDER_PATH_IN_DROPBOX" "DESTINATION_EXPORT_FILE_NAME_IN_DROPBOX" + + # Example + uv run generate_coco_dropbox.py sl.yourAccessTokenHere “/COCO TEST” “coco_export.json” ``` +- Download the coco_export.json from the your DropBox folder -Download the coco_export.json from the dropbox From 1e65d9af5a09891846f4504d0e9f4e1ec11c3e7e Mon Sep 17 00:00:00 2001 From: Keyur Khadka Date: Wed, 30 Jul 2025 19:24:01 +0545 Subject: [PATCH 6/8] Update README.md --- manager-dashboard/user_scripts/README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/manager-dashboard/user_scripts/README.md b/manager-dashboard/user_scripts/README.md index 2eb9d0d3..741b4da6 100644 --- a/manager-dashboard/user_scripts/README.md +++ b/manager-dashboard/user_scripts/README.md @@ -54,18 +54,21 @@ You can find the utility script for DropBox here: [generate_coco_from_dropbox.py - Click **Generated access token** - Install uv on your system: https://docs.astral.sh/uv/getting-started/installation/ - Download the [generate_coco_from_dropbox.py](./generate_coco_from_dropbox.py) script +- Create a DropBox folder and upload images + - Your image files should be stored in a public DropBox folder ### Creation Steps -- Run the script +- Copy the folder pathname in DropBox +- Copy the generated access token from DropBox +- Run the script ```bash # Help uv run generate_coco_dropbox.py --help # Sample - uv run generate_coco_dropbox.py "DROPBOX_ACCESS_TOKEN" "FOLDER_PATH_IN_DROPBOX" "DESTINATION_EXPORT_FILE_NAME_IN_DROPBOX" + uv run generate_coco_dropbox.py "DROPBOX_ACCESS_TOKEN" "FOLDER_PATHNAME_IN_DROPBOX" "DESTINATION_EXPORT_FILE_NAME_IN_DROPBOX" # Example uv run generate_coco_dropbox.py sl.yourAccessTokenHere “/COCO TEST” “coco_export.json” ``` -- Download the coco_export.json from the your DropBox folder - +- Download the exported coco json from the link in terminal or your DropBox folder From f05ffa1535ef469e30d0e0a01fe4cf7e42a90a72 Mon Sep 17 00:00:00 2001 From: Keyur Khadka Date: Wed, 30 Jul 2025 19:32:35 +0545 Subject: [PATCH 7/8] Fix review comments and update description --- manager-dashboard/user_scripts/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager-dashboard/user_scripts/README.md b/manager-dashboard/user_scripts/README.md index 741b4da6..feb965fd 100644 --- a/manager-dashboard/user_scripts/README.md +++ b/manager-dashboard/user_scripts/README.md @@ -1,5 +1,5 @@ ## Description -This read me will guide you on how to create a COCO file using the utility script for Google Drive and DropBox +This will serve as a guide on how to create a COCO file using the utility script for Google Drive and DropBox ## Google Drive You can find the utility script for Google Drive here: [generate_coco_from_drive.js](./generate_coco_from_drive.js) From cb3be554a5bfe0f19bd8bf8a2d5740015f65a1cb Mon Sep 17 00:00:00 2001 From: Keyur Khadka Date: Wed, 30 Jul 2025 19:48:42 +0545 Subject: [PATCH 8/8] Fix comments --- manager-dashboard/user_scripts/README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/manager-dashboard/user_scripts/README.md b/manager-dashboard/user_scripts/README.md index feb965fd..3964cc12 100644 --- a/manager-dashboard/user_scripts/README.md +++ b/manager-dashboard/user_scripts/README.md @@ -13,10 +13,10 @@ You can find the utility script for Google Drive here: [generate_coco_from_drive - Create a Google Apps script project - Go to https://script.google.com - Click on "New Project" - - Rename the project name to your desired project name + - Rename the project name to `your-project-name` - Paste the utility script - - Replace any existing default code the code from this utility file -- Replace Placeholder Values + - Replace the default code with the utility file's code +- Replace placeholder values - Replace `your_coco_export.json` with your output filename - Replace `your_public_folder_id` with the ID of your Google Drive folder > The folder ID is the alphanumeric string that appears after "/folders/" in the URL.\ @@ -26,8 +26,8 @@ You can find the utility script for Google Drive here: [generate_coco_from_drive - Press Run - Accept the authorization prompts the first time you run the script - View COCO JSON Output - - Go to View > Logs - - Copy the Google Drive URL where the coco file is created and generated + - Go to **View > Logs** + - Copy the Google Drive URL where the coco file is generated - Download the json file ## DropBox @@ -42,7 +42,7 @@ You can find the utility script for DropBox here: [generate_coco_from_dropbox.py - Update `Permission type` - Go to the app settings - Click **Scoped App** - - Tick the following + - Tick the following permissions - files.metadata.read - files.content.write - files.content.read @@ -55,7 +55,6 @@ You can find the utility script for DropBox here: [generate_coco_from_dropbox.py - Install uv on your system: https://docs.astral.sh/uv/getting-started/installation/ - Download the [generate_coco_from_dropbox.py](./generate_coco_from_dropbox.py) script - Create a DropBox folder and upload images - - Your image files should be stored in a public DropBox folder ### Creation Steps - Copy the folder pathname in DropBox @@ -69,6 +68,6 @@ You can find the utility script for DropBox here: [generate_coco_from_dropbox.py uv run generate_coco_dropbox.py "DROPBOX_ACCESS_TOKEN" "FOLDER_PATHNAME_IN_DROPBOX" "DESTINATION_EXPORT_FILE_NAME_IN_DROPBOX" # Example - uv run generate_coco_dropbox.py sl.yourAccessTokenHere “/COCO TEST” “coco_export.json” + uv run generate_coco_dropbox.py sl.yourAccessTokenHere "/COCO TEST" "coco_export.json" ``` - Download the exported coco json from the link in terminal or your DropBox folder