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

# Package & publish

> Lay out the environment folder, declare dependencies, and publish it to the managed Hub.

Turn your local files into a published environment that training runs reach by
id. Structure the folder, declare its dependencies, and push it to the managed
Hub.

## Structure the package

A published environment is a small folder. Flash packages it, imports its
`environment.py` entrypoint on the worker, and calls
`load_environment(**params)`, which must return a Freesolo SDK environment. The
folder can be named anything as long as it contains `environment.py` at its
root.

```text theme={null}
math/
  environment.py          # defines load_environment()
  helpers.py              # optional Python helpers
  dataset/
    train.jsonl           # input/output records
    eval.jsonl
```

Publish the folder:

```bash theme={null}
flash env push --name math math
```

A single `.py` upload still works for tiny smoke tests, but push real environments
as folders. The `--name` value is normalized to a lowercase hyphen slug, and the
published id uses your Freesolo org namespace, for example `your-org/math`.

Keep all imports either from sibling files in the folder you publish, from the
`freesolo` SDK, or from third-party packages you declare under
`[environment].pip` (see below).

### Declare third-party dependencies

If your `environment.py` imports a package that isn't part of the `freesolo` SDK,
list it under `[environment].pip` so the worker installs it before importing your
environment:

```toml theme={null}
[environment]
id = "your-org/your-env"
pip = ["rapidfuzz>=3.0", "pydantic"]
```

This is the supported worker dependency mechanism. A `pyproject.toml`,
`requirements.txt`, or lockfile beside `environment.py` can help local
development, but Flash does not use those files to install packages for a managed
training run. Put runtime packages in the [training config](/reference/configuration) that references
the published environment.

Only list packages your environment imports. Flash manages the training stack
itself, so do not pin packages such as `torch`, `trl`, `vllm`, `peft`, or
`bitsandbytes` here unless your environment directly imports them.

For example, an environment whose reward calls a judge model should declare the
client library and the secret it reads. Here the judge is reached through an
OpenAI-compatible client (such as OpenRouter), but the same pattern applies to
any provider:

```toml theme={null}
[environment]
id = "your-org/search-reward"
pip = ["openai>=1.0.0"]
secrets = ["JUDGE_API_KEY"]
```

If that same reward also queries a database, declare its client library and the
exact environment variable name your code reads. Here the database is MongoDB via
`pymongo`, but the same pattern applies to any database:

```toml theme={null}
[environment]
id = "your-org/search-reward"
pip = ["openai>=1.0.0", "pymongo>=4.17.0"]
secrets = ["JUDGE_API_KEY", "DATABASE_URL"]
```

Do not declare unused packages or secrets. If the active reward only calls the
judge model and no longer queries the database, leave out the database client and
its secret.

## Publish it

Training runs on managed infrastructure, so the environment must be reachable by id.
Publish your local environment folder to the managed Environments Hub:

```bash theme={null}
flash env push --name math math
```

It prints the published id
(`your-org/math`). Put that in your config's `[environment] id`.

## Use an existing environment

If you already have a published env id (yours or one shared with you), reference
it directly. A config `[environment] id` also accepts a `github:owner/repo@ref:path` ref or a
GitHub URL, which Flash resolves at run time. `flash env pull` (below) takes
managed `namespace/name` slugs only — it no longer accepts `github:` refs or
GitHub URLs.

```toml theme={null}
[environment]
id = "your-org/your-env"
```

To edit or inspect the source locally, pull the whole environment into a
directory:

```bash theme={null}
flash env pull your-org/your-env
```

Pull one file by adding its path inside the environment. Use `-o` to choose the
destination and `-f` to overwrite an existing output:

```bash theme={null}
flash env pull your-org/your-env dataset/train.jsonl -o train.jsonl
```

## List what you have

```bash theme={null}
flash env list
```

Shows local environment sources you can publish, such as `./environment.py` or
folders under `environments/`.

## Delete a Hub environment

Delete only targets managed Hub ids of the form `namespace/name`; GitHub refs
and local paths are not Hub records and cannot be deleted this way.

```bash theme={null}
flash env delete your-org/your-env
flash env delete your-org/your-env -y   # skip the confirmation prompt
```

## Use API keys

If your environment needs an external service, read the key from `os.environ` in
`environment.py`:

```python environment.py theme={null}
import os

SERVICE_API_KEY = os.environ["SERVICE_API_KEY"]
```

Then declare the environment variable names in your training config:

```toml theme={null}
[environment]
id = "your-org/your-env"
secrets = ["SERVICE_API_KEY"]
```

Set the value in your shell before submitting:

```bash theme={null}
export SERVICE_API_KEY="..."
flash train configs/sft.toml
```

You can also put local development values in `.env` or `.env.local`:

```bash theme={null}
SERVICE_API_KEY=...
```

Flash sends declared secret values to the worker out-of-band. Secret values are
not stored in the TOML config, run spec, status JSON, logs, or environment
artifact. Do not put API keys in `[environment.params]`.
If a declared secret is missing when you submit, `flash train` fails before the
run starts.

## Next steps

<CardGroup cols={2}>
  <Card title="Single-turn environments" icon="flask" href="/guides/environments/single-turn">
    Fill in the environment class you just published.
  </Card>

  <Card title="Training" icon="dumbbell" href="/guides/training">
    Reference the published id from a config and train.
  </Card>
</CardGroup>
