Export and Convert Snapshots

Bulk export as JSON

For a quick JSON export, you can use the following example to bulk export from a project without creating a snapshot first.

1# Define the URL where Label Studio is accessible
2LABEL_STUDIO_URL = 'YOUR_BASE_URL'
3# API key is available at the Account & Settings page in Label Studio UI
4LABEL_STUDIO_API_KEY = 'YOUR_ACCESS_TOKEN'
5PROJECT_ID=1 # replace with your project ID
6
7from label_studio_sdk import LabelStudio
8
9client = LabelStudio(base_url=LABEL_STUDIO_URL, api_key=LABEL_STUDIO_API_KEY)
10
11
12data = client.projects.exports.as_json(PROJECT_ID)

Use snapshots

In this example, you will:

  1. Create an export snapshot
  2. Poll for export completion
  3. Download the resulting export file
  4. Convert the export to a specified format (optional and only if an export type is specified)
  5. Poll for conversion completion
  6. Download the resulting converted file

When running this script, you can optionally provide an argument for the export type (CSV, COCO, JSON, etc.) to convert to. For example:

python export_snapshots.py CSV

Read more about supported export formats in the Label Studio documentation.

For information on finding your API key and base URL, see Authenticate and Connect to the API.

Example script

You can also find this as a Python script in the SDK repo. Note that in that example, you must first set the URL, API key (access token), and project ID as environment variables.

1# Define the URL where Label Studio is accessible
2LABEL_STUDIO_URL = 'YOUR_BASE_URL'
3# API key is available at the Account & Settings page in Label Studio UI
4LABEL_STUDIO_API_KEY = 'YOUR_ACCESS_TOKEN'
5PROJECT_ID=1 # replace with your project ID
6
7import sys
8import time
9from pathlib import Path
10import logging
11
12from label_studio_sdk import LabelStudio
13from label_studio_sdk.core.api_error import ApiError
14
15logging.basicConfig(level=logging.INFO)
16logger = logging.getLogger("export_snapshots")
17
18
19def export_and_download_snapshot():
20 """Export project JSON snapshot
21
22 This example demonstrates how to:
23 - Create an export snapshot
24 - Poll for completion
25 - Download the resulting file
26 """
27
28 # Initialize v2 client
29 client = LabelStudio(base_url=LABEL_STUDIO_URL, api_key=LABEL_STUDIO_API_KEY)
30
31 # Fetch project and optional first view id
32 client.projects.get(id=PROJECT_ID)
33 views = client.views.list(project=PROJECT_ID)
34 {"view": views[0].id} if views else None
35
36 # Create export snapshot
37 create_kwargs = {
38 "title": "Export SDK Snapshot",
39 # task_filter_options follows API schema; pass only if a view is available
40 # "task_filter_options": {"view": task_filter_options["view"]} if task_filter_options else None,
41 }
42 # Remove None keys to avoid sending them
43 create_kwargs = {k: v for k, v in create_kwargs.items() if v is not None}
44
45 export_job = client.projects.exports.create(id=PROJECT_ID, **create_kwargs)
46 export_id = export_job.id
47 logger.info(f"Created export snapshot: id={export_id}, status={export_job.status}")
48
49 # Poll until completed or failed
50 start = time.time()
51 timeout_sec = 300
52 logger.info("Waiting for export snapshot to complete...")
53 while True:
54 job = client.projects.exports.get(id=PROJECT_ID, export_pk=export_id)
55 elapsed = int(time.time() - start)
56 logger.info(f"Export status: {job.status} (elapsed {elapsed}s)")
57 if job.status in ("completed", "failed"):
58 break
59 if time.time() - start > timeout_sec:
60 raise TimeoutError(
61 f"Export job timed out (id={export_id}, status={job.status})"
62 )
63 time.sleep(1.0)
64
65 if job.status == "failed":
66 raise ApiError(status_code=500, body=f"Export failed: {job}")
67
68 # Download export as JSON to local file
69 out_dir = Path(".")
70 out_dir.mkdir(parents=True, exist_ok=True)
71 out_path = out_dir / f"project_{PROJECT_ID}_export_{export_id}.json"
72
73 with open(out_path, "wb") as f:
74 for chunk in client.projects.exports.download(
75 id=PROJECT_ID,
76 export_pk=export_id,
77 export_type="JSON",
78 request_options={"chunk_size": 1024},
79 ):
80 f.write(chunk)
81
82 logger.info(f"Export completed. File saved to: {out_path}")
83 return export_id
84
85
86def convert_snapshot(export_type: str, export_id: str = None):
87 """Convert the project export JSON snapshot to a specified format and download it.
88
89 The conversion API is used to start a conversion on the Label Studio backend, then we poll export status
90 until the specific converted format is completed, and finally download it.
91 See docs: projects/exports/convert and projects/exports/list.
92
93 Args:
94 export_type: The type of export to convert to.
95 export_id: The ID of the export to convert. If not provided, the latest export will be used.
96 """
97 client = LabelStudio(base_url=LABEL_STUDIO_URL, api_key=LABEL_STUDIO_API_KEY)
98
99 # Get the latest export snapshot for the project
100 exports = client.projects.exports.list(id=PROJECT_ID)
101 if not exports:
102 raise ApiError(
103 status_code=404, body="No export snapshots found for the project"
104 )
105 exports = sorted(exports, key=lambda e: e.created_at, reverse=True)
106 export = exports[0]
107 export_id = export.id if not export_id else export_id
108
109 # Start conversion
110 conv = client.projects.exports.convert(
111 export_pk=export_id, id=PROJECT_ID, export_type=export_type
112 )
113 converted_format_id = conv.converted_format
114 logger.info(
115 f"Started conversion: export_id={export_id}, export_type={export_type}, converted_format_id={converted_format_id}"
116 )
117
118 # Poll converted format status
119 start = time.time()
120 timeout_sec = 300
121 logger.info("Waiting for conversion to complete...")
122 while True:
123 cur = client.projects.exports.get(id=PROJECT_ID, export_pk=export_id)
124 cf = None
125 if cur.converted_formats:
126 cf = next(
127 (
128 c
129 for c in cur.converted_formats
130 if (converted_format_id and c.id == converted_format_id)
131 or (c.export_type == export_type)
132 ),
133 None,
134 )
135 status = getattr(cf, "status", None)
136 elapsed = int(time.time() - start)
137 logger.info(
138 f"Conversion status: {status or 'pending'} (format {export_type}, elapsed {elapsed}s)"
139 )
140 if status in ("completed", "failed"):
141 break
142 if time.time() - start > timeout_sec:
143 raise TimeoutError(
144 f"Conversion timed out (export_id={export_id}, format={export_type}, status={status})"
145 )
146 time.sleep(1.0)
147
148 if status == "failed":
149 raise ApiError(
150 status_code=500,
151 body=f"Conversion failed (export_id={export_id}, format={export_type})",
152 )
153
154 # Download converted file using export_type param
155 ext = "json" if export_type.upper().startswith("JSON") else export_type.lower()
156 out_dir = Path(".")
157 out_dir.mkdir(parents=True, exist_ok=True)
158 out_path = out_dir / f"project_{PROJECT_ID}_export_{export_id}.{ext}"
159
160 with open(out_path, "wb") as f:
161 for chunk in client.projects.exports.download(
162 id=PROJECT_ID,
163 export_pk=export_id,
164 export_type=export_type,
165 request_options={"chunk_size": 1024},
166 ):
167 f.write(chunk)
168
169 logger.info(f"Converted export downloaded. File saved to: {out_path}")
170
171
172if __name__ == "__main__":
173
174 export_id = export_and_download_snapshot()
175 logger.info(f"Export ID: {export_id}")
176
177 export_type = sys.argv[1] if len(sys.argv) > 1 else None
178 if export_type and export_type != "JSON":
179 logger.info(f"Converting export to {export_type} format")
180 convert_snapshot(export_type, export_id)