> ## Documentation Index
> Fetch the complete documentation index at: https://docs.baseten.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Choose where to run your Loops script

> Run your Loops training script on your local machine to start, then on Baseten with baseten loops exec for long or unattended runs.

Run a Loops script on your local machine to start. The local Python process submits training operations, waits for results, and requests samples. Baseten runs the trainer and sampler.

For long or unattended runs, use [`baseten loops exec`](https://docs.baseten.co/reference/cli/baseten/loops#exec) to run the same script on Baseten.

## Prerequisites

* The project and `train_loops.py` from the [Loops quickstart](https://docs.baseten.co/loops/quickstart.md).
* [uv](https://docs.astral.sh/uv/) and Python 3.12 or later.
* A [workspace API key](https://docs.baseten.co/organization/api-keys.md) to run the script locally.
* The [Baseten CLI](https://docs.baseten.co/reference/cli/baseten/overview.md) with an active profile to run the script on Baseten.

Keep the same [`ServiceClient`](https://docs.baseten.co/reference/sdk/loops/service-client) setup in the script for either location:

```python train_loops.py theme={"system"}
from baseten.loops import ServiceClient

service_client = ServiceClient()
```

`ServiceClient()` reads `BASETEN_API_KEY` and connects to `https://api.baseten.co` by default.

## Run the Python script on your local machine

**To run the script locally**:

1. From your project directory, export your workspace API key as `BASETEN_API_KEY`. Replace `YOUR_API_KEY` with your key:

   ```bash macOS/Linux theme={"system"}
   export BASETEN_API_KEY="YOUR_API_KEY"
   ```

   ```powershell Windows theme={"system"}
   $env:BASETEN_API_KEY = "YOUR_API_KEY"
   ```

2. Run your training script:

   ```bash theme={"system"}
   uv run python train_loops.py
   ```

   The quickstart script prints the session and run IDs, the reward of each step, sampled text, and checkpoint paths. Compare its output with [Inspect the results](https://docs.baseten.co/loops/quickstart.md#list-checkpoints).

Keep the local machine or third-party host awake and ensure it permits sustained outbound HTTPS connections to Baseten. Sandboxes and hosted notebooks can suspend processes or restrict network access even after a successful first request. The SDK retries transient connection failures, but it can't keep a run going from a persistently unstable host or network.

## Run the Python script on Baseten

`baseten loops exec` packages a project directory and runs your script as a [Training Job](https://docs.baseten.co/training/overview.md), using your active [Baseten CLI profile](https://docs.baseten.co/reference/cli/baseten/overview.md). The job supplies `BASETEN_API_KEY` from a team secret, which Truss creates on first use unless you supply your own credential. Use a CLI profile for the same workspace as your local API key.

Baseten bills for the Training Job that runs your script. The Loops run bills separately according to its [availability mode](https://docs.baseten.co/loops/availability-modes/overview.md).

**To run the script on Baseten**:

From your project directory, run the same `train_loops.py` with its uv dependencies and stream its logs:

```bash theme={"system"}
baseten loops exec --dir . --tail --with-uv --no-ssh --output json -- uv run python train_loops.py
```

The submission result includes the job ID:

```json Output theme={"system"}
{
  "job_id": "<job_id>",
  ...
}
```

By default, the job opens an SSH session you can connect to, which requires [Training SSH](https://docs.baseten.co/training/ssh.md#prerequisites) for your workspace. This command disables SSH with `--no-ssh`. Omit it if you want an SSH session and your workspace has Training SSH enabled.

Always pass `--dir`. Use `.` for the current project directory or pass another project path. The remote command runs from the uploaded directory.

With `--tail`, the command writes the submission result to stdout and streams logs to stderr until the job finishes. It returns zero if the job completes successfully and a nonzero exit code if it fails. Press Ctrl+C to stop watching; the remote job keeps running.

**To submit the script and check it later**:

1. Run the following command to return a structured result after submission:

   ```bash theme={"system"}
   baseten loops exec --dir . --with-uv --no-ssh --output json -- uv run python train_loops.py
   ```

   ```json Output theme={"system"}
   {
     "job_id": "<job_id>",
     ...
   }
   ```

2. Use `job_id` from the result to follow the job's logs with [`baseten train job logs`](https://docs.baseten.co/reference/cli/baseten/train#logs):

   ```bash theme={"system"}
   baseten train job logs --job-id "<job_id>" --tail
   ```

3. Check that the job completed with [`baseten train job describe`](https://docs.baseten.co/reference/cli/baseten/train#describe):

   ```bash theme={"system"}
   baseten train job describe --job-id "<job_id>" --jq '.training_job.current_status'
   ```

   ```json Output theme={"system"}
   "TRAINING_JOB_COMPLETED"
   ```

`baseten loops exec` has no Loops API equivalent because it uploads local source. For more information, see the [`baseten loops exec` reference](https://docs.baseten.co/reference/cli/baseten/loops#exec).

## Deactivate the run

Closing the training client doesn't deactivate the Loops run. [Deactivate the run](https://docs.baseten.co/loops/deactivate-a-run.md) to end it and its paired sampler and to stop a dedicated run's GPU billing.
