This article explains how to download the solution JSON for a completed solve using the API (with a Python example). This can also be translated into other programming languages.
The full API docs can be found here.
Prerequisites
Before you begin:
- Authenticate and load your access token
- The
load_token()andauthenticate()functions are given in the Authenticating and getting a token article
- The
- Having a solve ID to pass in. You can get this from:
- If using the API to submit your solves, the response to the
/solveendpoint is a list of solve ID(s) - If looking through the web UI, the solve ID can be found in the URL where it says
id=, for example this solve ID is 1234./solve?id=1234
- If using the API to submit your solves, the response to the
See the Output JSON article for interpreting the solution JSON file that is downloaded from this API endpoint. This is the same solution JSON file that is downloaded by clicking the download button on a solve in the web interface.
Example: Python code to download the solution JSON
import json
import os
import sys
import requests
from datetime import datetime, timedelta, UTC
ROSEPY_API_KEY_TOKEN = os.getenv("ROSEPY_API_KEY_TOKEN")
TOKEN_CACHE_FILE = ".simplerose_token_cache.json"
BASE_URL = "https://sapi.prod.solaas.simplerose.com/api/1.0"
# Solve ID from PUT /solve (or from GET /solves)
SOLVE_ID = ""
# === AUTHORIZATION FUNCTIONS ===
# Save the access token and its expiration to disk
def save_token(auth_token):
with open(TOKEN_CACHE_FILE, "w") as f:
expires = (datetime.now(UTC) + timedelta(seconds=auth_token["expires_in"])).isoformat()
json.dump({
"access_token": auth_token["access_token"],
"expires": expires
}, f)
# Use the existing token on disk if it exists and has not expired
def load_token():
if not os.path.exists(TOKEN_CACHE_FILE):
return None
with open(TOKEN_CACHE_FILE, "r") as f:
data = json.load(f)
if datetime.now(UTC) > datetime.fromisoformat(data["expires"]):
return None
return data["access_token"]
# Request a new authorization token
def authenticate():
payload = {"api_key_token": ROSEPY_API_KEY_TOKEN}
response = requests.post(
f"{BASE_URL}/authenticate",
json=payload,
timeout=10)
response.raise_for_status()
auth_token = response.json()
save_token(auth_token)
return auth_token["access_token"]
# === SOLUTION FUNCTIONS ===
def download_solution(token: str, solve_id: str, output_path: str = "solution.json"):
"""
GET /solve/{solve_id}/solution → presigned URL, then download the solution file.
"""
url = f"{BASE_URL}/solve/{solve_id}/solution"
headers = {"Authorization": f"Bearer {token}"}
print("⬇️ Downloading solution...")
# Step 1: Get the presigned URL for the solution
response = requests.get(url, headers=headers)
if not response.ok:
print(f"Solution URL request failed ({response.status_code}): {response.text}")
response.raise_for_status()
data = response.json()
solution_url = data.get("solution_url")
if not solution_url:
raise ValueError(
"❌ No presigned URL returned — the solve may not be completed "
"or did not produce a downloadable solution."
)
# Step 2: Download the actual solution from S3
solution_response = requests.get(solution_url)
solution_response.raise_for_status()
with open(output_path, "wb") as f:
f.write(solution_response.content)
print(f"✅ Solution downloaded and saved to {output_path}")
# Main workflow
if __name__ == "__main__":
solve_id = sys.argv[1] if len(sys.argv) > 1 else SOLVE_ID
if not solve_id or solve_id.startswith("<"):
raise SystemExit(
"Provide a solve ID: set SOLVE_ID, pass it as the first CLI arg, "
"or edit SOLVE_ID in this file.\n"
"Example: python ep-solution.py f90fbd0b-4474-495b-9ed9-4b03c3eb06eb"
)
token = load_token() or authenticate()
print("✅ Authenticated")
print(f"Solve ID: {solve_id}")
download_solution(token, solve_id, "solution.json")
You can now open the downloaded solution.json in any text editor or parse it programmatically to extract objective values, variable assignments, or solver metadata.
Comments
0 comments
Please sign in to leave a comment.