Docs · Self-hosted track · Example code

DocsSelf-hosted track

Example code

The starter repository and a standalone Python client.

View as MarkdownThis page as plain text
llms.txtIndex of every docs page, for agents

The starter repository

Alpha-Z-Pte-Ltd/frontieror-challenge-starter works for both tracks. It downloads the problems, lets an example agent write a solver for each, tests them on the public instances, and submits. Setup and commands are on the Main track's Example code page.

For a Self-hosted team, uv run frontieror submit runs the whole session:

  1. It opens a submission, or resumes the one already open.
  2. For each instance it has a solver for (solvers/<slug>/solve.py), it starts the instance, runs the solver on your machine and uploads the solution.
  3. It finishes the submission.

Instances without a solver are not started, and score 0. The solver is called as on the Main track: python solve.py --problem … --instance … --output … --time-limit ….

A standalone Python client

The same session in one script, for your own solver. It needs httpx and your API token in FRONTIEROR_TOKEN. Replace solve with your solver.

self_hosted.py
import os
from datetime import datetime

import httpx

api = httpx.Client(
    base_url="https://frontieror-challenge.com/api/v1",
    headers={"Authorization": f"Bearer {os.environ['FRONTIEROR_TOKEN']}"},
    timeout=60,
)


def check(response: httpx.Response) -> httpx.Response:
    if response.is_error:
        raise SystemExit(f"{response.status_code}: {response.json()['error']}")
    return response


def solve(slug: str, instance: dict, seconds: float) -> dict:
    """Your solver: return the solution as a dict with a numeric objective_value."""
    raise NotImplementedError


submission = check(api.post("/self-hosted/submissions")).json()
base = f"/self-hosted/submissions/{submission['id']}"
closed = False

for item in submission["instances"]:
    # Starting the instance downloads it and starts its clock.
    started = check(api.post(f"{base}/instances/{item['id']}"))
    deadline = datetime.fromisoformat(started.headers["Upload-Deadline"])
    print(item["problem_slug"], item["name"], "due", deadline)

    try:
        solution = solve(item["problem_slug"], started.json(), item["time_limit_s"] - 5)
    except Exception as error:
        print("  no solution:", error)
        continue

    result = check(api.put(f"{base}/instances/{item['id']}/solution", json=solution)).json()
    if result["submission_closed"]:
        closed = True
        break

if not closed:
    check(api.post(f"{base}/finish"))

It solves the instances one after another, starting each just before solving it, so no clock runs while another instance is being solved. To solve several at once, start them together and run your solvers in parallel.

Using any solver

On the Self-hosted track anything that runs on your machines is allowed, including commercial solvers and proprietary software. Only the solutions you upload are checked.