Buckets:

hf-doc-build/doc-dev / openenv /pr_749 /en /getting_started /environment-builder.html
download
raw
74.3 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Packaging &amp; Deploying&quot;,&quot;local&quot;:&quot;packaging--deploying&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Quick Reference Card&quot;,&quot;local&quot;:&quot;quick-reference-card&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;CLI Quick Reference&quot;,&quot;local&quot;:&quot;cli-quick-reference&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Overview&quot;,&quot;local&quot;:&quot;overview&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Prerequisites&quot;,&quot;local&quot;:&quot;prerequisites&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step-by-Step Guide&quot;,&quot;local&quot;:&quot;step-by-step-guide&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;1. Scaffold with openenv init&quot;,&quot;local&quot;:&quot;1-scaffold-with-openenv-init&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;2. Define Models&quot;,&quot;local&quot;:&quot;2-define-models&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;3. Implement Environment Logic&quot;,&quot;local&quot;:&quot;3-implement-environment-logic&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;4. Create the FastAPI Server&quot;,&quot;local&quot;:&quot;4-create-the-fastapi-server&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;5. Implement the Client&quot;,&quot;local&quot;:&quot;5-implement-the-client&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;6. Configure Dependencies &amp; Dockerfile&quot;,&quot;local&quot;:&quot;6-configure-dependencies--dockerfile&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;7. Build &amp; Validate with the CLI&quot;,&quot;local&quot;:&quot;7-build--validate-with-the-cli&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;8. Push &amp; Share with openenv push&quot;,&quot;local&quot;:&quot;8-push--share-with-openenv-push&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Declaring public variables in openenv.yaml&quot;,&quot;local&quot;:&quot;declaring-public-variables-in-openenvyaml&quot;,&quot;sections&quot;:[],&quot;depth&quot;:4}],&quot;depth&quot;:3},{&quot;title&quot;:&quot;9. Automate Builds (optional)&quot;,&quot;local&quot;:&quot;9-automate-builds-optional&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Use Your Environment&quot;,&quot;local&quot;:&quot;use-your-environment&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Nice work! You’ve now built and used your own OpenEnv environment.&quot;,&quot;local&quot;:&quot;nice-work-youve-now-built-and-used-your-own-openenv-environment&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}">
<link href="/docs/openenv/pr_749/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/entry/start.85477f45.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/scheduler.2b22cead.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/singletons.63566282.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/paths.dd876c7b.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/entry/app.51835dc5.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/preload-helper.0820fbc7.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/index.1a0e8013.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/nodes/0.167255c0.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/each.e59479a4.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/nodes/40.11873d1d.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/Heading.c0d3f116.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.21bcf336.js">
<link rel="modulepreload" href="/docs/openenv/pr_749/en/_app/immutable/chunks/CodeBlock.c8d73295.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Packaging &amp; Deploying&quot;,&quot;local&quot;:&quot;packaging--deploying&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Quick Reference Card&quot;,&quot;local&quot;:&quot;quick-reference-card&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;CLI Quick Reference&quot;,&quot;local&quot;:&quot;cli-quick-reference&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Overview&quot;,&quot;local&quot;:&quot;overview&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Prerequisites&quot;,&quot;local&quot;:&quot;prerequisites&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Step-by-Step Guide&quot;,&quot;local&quot;:&quot;step-by-step-guide&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;1. Scaffold with openenv init&quot;,&quot;local&quot;:&quot;1-scaffold-with-openenv-init&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;2. Define Models&quot;,&quot;local&quot;:&quot;2-define-models&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;3. Implement Environment Logic&quot;,&quot;local&quot;:&quot;3-implement-environment-logic&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;4. Create the FastAPI Server&quot;,&quot;local&quot;:&quot;4-create-the-fastapi-server&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;5. Implement the Client&quot;,&quot;local&quot;:&quot;5-implement-the-client&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;6. Configure Dependencies &amp; Dockerfile&quot;,&quot;local&quot;:&quot;6-configure-dependencies--dockerfile&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;7. Build &amp; Validate with the CLI&quot;,&quot;local&quot;:&quot;7-build--validate-with-the-cli&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;8. Push &amp; Share with openenv push&quot;,&quot;local&quot;:&quot;8-push--share-with-openenv-push&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Declaring public variables in openenv.yaml&quot;,&quot;local&quot;:&quot;declaring-public-variables-in-openenvyaml&quot;,&quot;sections&quot;:[],&quot;depth&quot;:4}],&quot;depth&quot;:3},{&quot;title&quot;:&quot;9. Automate Builds (optional)&quot;,&quot;local&quot;:&quot;9-automate-builds-optional&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Use Your Environment&quot;,&quot;local&quot;:&quot;use-your-environment&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Nice work! You’ve now built and used your own OpenEnv environment.&quot;,&quot;local&quot;:&quot;nice-work-youve-now-built-and-used-your-own-openenv-environment&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="packaging--deploying" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#packaging--deploying"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Packaging &amp; Deploying</span></h1> <p data-svelte-h="svelte-16obzct"><strong>Part 4 of 5</strong> in the OpenEnv Getting Started Series</p> <p data-svelte-h="svelte-ctnfvd">This guide walks you through creating a custom environment using the <code>OpenEnv</code> framework and the <code>openenv</code> CLI.</p> <p data-svelte-h="svelte-a8bq9v">The CLI handles scaffolding, builds, validation, and deployment so you can stay focused on environment logic.</p> <blockquote class="note" data-svelte-h="svelte-r906iz"><p><strong>New to OpenEnv?</strong> If you’re just getting started, we recommend completing the <a href="../tutorials/index">Getting Started tutorials</a> first. They provide a conceptual introduction to OpenEnv and reinforcement learning fundamentals. This guide is for developers ready to build production-quality environments.</p></blockquote> <h2 class="relative group"><a id="quick-reference-card" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#quick-reference-card"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Quick Reference Card</span></h2> <p data-svelte-h="svelte-1nsuea4">Already familiar with OpenEnv? Here’s the 8-step process at a glance:</p> <table data-svelte-h="svelte-1ig457w"><thead><tr><th>Step</th> <th>Command / Action</th> <th>Description</th></tr></thead> <tbody><tr><td>1</td> <td><code>openenv init my_env</code></td> <td>Scaffold new environment</td></tr> <tr><td>2</td> <td>Edit <code>models.py</code></td> <td>Define Action &amp; Observation dataclasses</td></tr> <tr><td>3</td> <td>Edit <code>server/my_environment.py</code></td> <td>Implement <code>reset()</code> and <code>step()</code> methods</td></tr> <tr><td>4</td> <td>Edit <code>client.py</code></td> <td>Implement <code>_step_payload()</code>, <code>_parse_result()</code>, <code>_parse_state()</code></td></tr> <tr><td>5</td> <td><code>openenv serve</code></td> <td>Start local dev server for testing</td></tr> <tr><td>6</td> <td><code>openenv validate</code></td> <td>Validate environment structure</td></tr> <tr><td>7</td> <td><code>openenv push</code></td> <td>Deploy to Hugging Face Hub</td></tr> <tr><td>8</td> <td>Share the URL!</td> <td>Others use via <code>MyEnv.from_hub(&quot;you/my-env&quot;)</code></td></tr></tbody></table> <h3 class="relative group"><a id="cli-quick-reference" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#cli-quick-reference"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>CLI Quick Reference</span></h3> <table data-svelte-h="svelte-1gg898p"><thead><tr><th>Command</th> <th>Description</th></tr></thead> <tbody><tr><td><code>openenv init NAME</code></td> <td>Scaffold new environment</td></tr> <tr><td><code>openenv serve</code></td> <td>Start local dev server</td></tr> <tr><td><code>openenv build</code></td> <td>Build Docker image</td></tr> <tr><td><code>openenv validate --verbose</code></td> <td>Validate environment structure</td></tr> <tr><td><code>openenv push</code></td> <td>Deploy to Hugging Face Hub</td></tr> <tr><td><code>openenv push --repo-id NAME</code></td> <td>Deploy to specific repo</td></tr> <tr><td><code>openenv push --private</code></td> <td>Deploy as private environment</td></tr> <tr><td><code>openenv push --registry ghcr.io/ORG</code></td> <td>Push to GitHub Container Registry</td></tr></tbody></table> <blockquote class="tip" data-svelte-h="svelte-1c5nyvq"><p>For a hands-on tutorial that builds a complete environment step-by-step, see <a href="../tutorials/index">Building Environments</a> in the Getting Started series.</p></blockquote> <hr> <h2 class="relative group"><a id="overview" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#overview"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Overview</span></h2> <p data-svelte-h="svelte-1rxjx2x">A typical workflow looks like:</p> <ol data-svelte-h="svelte-18h6ho"><li>Scaffold a new environment with <code>openenv init</code>.</li> <li>Customize your models, environment logic, and FastAPI server.</li> <li>Implement a typed <code>EnvClient</code> (WebSocket-based for persistent sessions).</li> <li>Configure dependencies and the Dockerfile once.</li> <li>Use the CLI (<code>openenv build</code>, <code>openenv validate</code>, <code>openenv push</code>) to package and share your work.</li></ol> <blockquote class="note" data-svelte-h="svelte-id12cf"><p>These integrations are handled automatically by the <code>openenv</code> CLI when you run <code>openenv init</code>.</p></blockquote> <h3 class="relative group"><a id="prerequisites" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#prerequisites"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Prerequisites</span></h3> <ul data-svelte-h="svelte-ghdn1o"><li>Python 3.11+ and <a href="https://github.com/astral-sh/uv" rel="nofollow"><code>uv</code></a> for dependency locking</li> <li>Docker Desktop / Docker Engine</li> <li>The OpenEnv library installed: <code>pip install https://github.com/huggingface/OpenEnv.git</code></li></ul> <h2 class="relative group"><a id="step-by-step-guide" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#step-by-step-guide"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Step-by-Step Guide</span></h2> <p data-svelte-h="svelte-u52you">Let’s walk through the process of building a custom environment with OpenEnv.</p> <h3 class="relative group"><a id="1-scaffold-with-openenv-init" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#1-scaffold-with-openenv-init"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>1. Scaffold with openenv init</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-bash "><!-- HTML_TAG_START --><span class="hljs-comment"># Run from anywhere – defaults to current directory</span>
openenv init my_env
<span class="hljs-comment"># Optionally choose an output directory</span>
openenv init my_env --output-dir /Users/you/envs<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-czocs9">The command creates a fully-typed template with <code>openenv.yaml</code>, <code>pyproject.toml</code>, <code>uv.lock</code>, Docker assets, and stub implementations. If you’re working inside this repo, move the generated folder under <code>envs/</code>.</p> <p data-svelte-h="svelte-1e70fkc">Typical layout:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=" "><!-- HTML_TAG_START -->my_env/
├── __init__<span class="hljs-selector-class">.py</span>
├── README<span class="hljs-selector-class">.md</span>
├── client<span class="hljs-selector-class">.py</span>
├── models<span class="hljs-selector-class">.py</span>
├── openenv<span class="hljs-selector-class">.yaml</span>
├── pyproject<span class="hljs-selector-class">.toml</span>
├── uv<span class="hljs-selector-class">.lock</span>
└── server/
├── __init__<span class="hljs-selector-class">.py</span>
├── app<span class="hljs-selector-class">.py</span>
├── my_environment<span class="hljs-selector-class">.py</span>
├── requirements<span class="hljs-selector-class">.txt</span>
└── Dockerfile<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1csvp49">Python classes are generated for the action, observation, environment, and client. For example, you will find <code>MyEnvironment</code>, <code>MyAction</code>, <code>MyObservation</code>, and <code>MyEnv</code> (client) in the <code>my_env</code> directory based on the name you provided. The environment uses the core <code>State</code> class from <code>openenv.core.env_server.types</code>.</p> <h3 class="relative group"><a id="2-define-models" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#2-define-models"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>2. Define Models</span></h3> <p data-svelte-h="svelte-ewzzeg">Edit <code>models.py</code> to describe your action and observation using Pydantic:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-comment"># models.py</span>
<span class="hljs-keyword">from</span> pydantic <span class="hljs-keyword">import</span> Field
<span class="hljs-keyword">from</span> openenv.core.env_server.types <span class="hljs-keyword">import</span> Action, Observation
<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyAction</span>(<span class="hljs-title class_ inherited__">Action</span>):
<span class="hljs-string">&quot;&quot;&quot;Your custom action.&quot;&quot;&quot;</span>
command: <span class="hljs-built_in">str</span> = Field(..., description=<span class="hljs-string">&quot;Command to execute&quot;</span>)
parameters: <span class="hljs-built_in">dict</span> = Field(default_factory=<span class="hljs-built_in">dict</span>, description=<span class="hljs-string">&quot;Command parameters&quot;</span>)
<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyObservation</span>(<span class="hljs-title class_ inherited__">Observation</span>):
<span class="hljs-string">&quot;&quot;&quot;Your custom observation.&quot;&quot;&quot;</span>
result: <span class="hljs-built_in">str</span> = Field(..., description=<span class="hljs-string">&quot;Result of the action&quot;</span>)
success: <span class="hljs-built_in">bool</span> = Field(..., description=<span class="hljs-string">&quot;Whether the action succeeded&quot;</span>)<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="3-implement-environment-logic" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#3-implement-environment-logic"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>3. Implement Environment Logic</span></h3> <p data-svelte-h="svelte-1kzvzkk">Customize <code>server/my_environment.py</code> by extending <code>Environment</code>:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-comment"># server/my_environment.py</span>
<span class="hljs-keyword">from</span> uuid <span class="hljs-keyword">import</span> uuid4
<span class="hljs-keyword">from</span> openenv.core.env_server.interfaces <span class="hljs-keyword">import</span> Environment
<span class="hljs-keyword">from</span> openenv.core.env_server.types <span class="hljs-keyword">import</span> State
<span class="hljs-keyword">from</span> models <span class="hljs-keyword">import</span> MyAction, MyObservation
<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyEnvironment</span>(<span class="hljs-title class_ inherited__">Environment</span>):
<span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self</span>):
self._state = State(episode_id=<span class="hljs-built_in">str</span>(uuid4()), step_count=<span class="hljs-number">0</span>)
<span class="hljs-keyword">def</span> <span class="hljs-title function_">reset</span>(<span class="hljs-params">self</span>) -&gt; MyObservation:
self._state = State(episode_id=<span class="hljs-built_in">str</span>(uuid4()), step_count=<span class="hljs-number">0</span>)
<span class="hljs-keyword">return</span> MyObservation(result=<span class="hljs-string">&quot;Ready&quot;</span>, success=<span class="hljs-literal">True</span>, done=<span class="hljs-literal">False</span>, reward=<span class="hljs-number">0.0</span>)
<span class="hljs-keyword">def</span> <span class="hljs-title function_">step</span>(<span class="hljs-params">self, action: MyAction</span>) -&gt; MyObservation:
<span class="hljs-comment"># Implement your logic here</span>
self._state.step_count += <span class="hljs-number">1</span>
result = self._execute_command(action.command)
<span class="hljs-keyword">return</span> MyObservation(result=result, success=<span class="hljs-literal">True</span>, done=<span class="hljs-literal">False</span>, reward=<span class="hljs-number">1.0</span>)
<span class="hljs-meta"> @property</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">state</span>(<span class="hljs-params">self</span>) -&gt; State:
<span class="hljs-keyword">return</span> self._state<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="4-create-the-fastapi-server" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#4-create-the-fastapi-server"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>4. Create the FastAPI Server</span></h3> <p data-svelte-h="svelte-yy593y"><code>server/app.py</code> should expose the environment through <code>create_app</code>.</p> <p data-svelte-h="svelte-1bx2epd"><strong>Important:</strong> You must pass a class or factory function (not an instance) to enable WebSocket-based concurrent sessions:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-comment"># server/app.py</span>
<span class="hljs-keyword">from</span> openenv.core.env_server <span class="hljs-keyword">import</span> create_app
<span class="hljs-keyword">from</span> ..models <span class="hljs-keyword">import</span> MyAction, MyObservation
<span class="hljs-keyword">from</span> .my_environment <span class="hljs-keyword">import</span> MyEnvironment
<span class="hljs-comment"># Pass the class (factory) - each WebSocket session gets its own instance</span>
app = create_app(MyEnvironment, MyAction, MyObservation, env_name=<span class="hljs-string">&quot;my_env&quot;</span>)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-pom1de">For environments with constructor arguments, create a factory function:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-comment"># server/app.py</span>
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">from</span> openenv.core.env_server <span class="hljs-keyword">import</span> create_app
<span class="hljs-keyword">from</span> ..models <span class="hljs-keyword">import</span> MyAction, MyObservation
<span class="hljs-keyword">from</span> .my_environment <span class="hljs-keyword">import</span> MyEnvironment
<span class="hljs-comment"># Read config from environment variables</span>
api_key = os.getenv(<span class="hljs-string">&quot;MY_API_KEY&quot;</span>)
timeout = <span class="hljs-built_in">int</span>(os.getenv(<span class="hljs-string">&quot;MY_TIMEOUT&quot;</span>, <span class="hljs-string">&quot;30&quot;</span>))
<span class="hljs-keyword">def</span> <span class="hljs-title function_">create_my_environment</span>():
<span class="hljs-string">&quot;&quot;&quot;Factory function that creates MyEnvironment with config.&quot;&quot;&quot;</span>
<span class="hljs-keyword">return</span> MyEnvironment(api_key=api_key, timeout=timeout)
<span class="hljs-comment"># Pass the factory function</span>
app = create_app(create_my_environment, MyAction, MyObservation, env_name=<span class="hljs-string">&quot;my_env&quot;</span>)<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="5-implement-the-client" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#5-implement-the-client"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>5. Implement the Client</span></h3> <p data-svelte-h="svelte-hx7m3p"><code>client.py</code> extends <code>EnvClient</code> so users can interact with your server via WebSocket for persistent sessions:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-comment"># client.py</span>
<span class="hljs-keyword">from</span> openenv.core.env_client <span class="hljs-keyword">import</span> EnvClient
<span class="hljs-keyword">from</span> openenv.core.client_types <span class="hljs-keyword">import</span> StepResult
<span class="hljs-keyword">from</span> .models <span class="hljs-keyword">import</span> MyAction, MyObservation, MyState
<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyEnv</span>(EnvClient[MyAction, MyObservation, MyState]):
<span class="hljs-keyword">def</span> <span class="hljs-title function_">_step_payload</span>(<span class="hljs-params">self, action: MyAction</span>) -&gt; <span class="hljs-built_in">dict</span>:
<span class="hljs-keyword">return</span> {<span class="hljs-string">&quot;command&quot;</span>: action.command, <span class="hljs-string">&quot;parameters&quot;</span>: action.parameters}
<span class="hljs-keyword">def</span> <span class="hljs-title function_">_parse_result</span>(<span class="hljs-params">self, payload: <span class="hljs-built_in">dict</span></span>) -&gt; StepResult[MyObservation]:
obs_data = payload.get(<span class="hljs-string">&quot;observation&quot;</span>, {})
obs = MyObservation(
result=obs_data.get(<span class="hljs-string">&quot;result&quot;</span>, <span class="hljs-string">&quot;&quot;</span>),
success=obs_data.get(<span class="hljs-string">&quot;success&quot;</span>, <span class="hljs-literal">False</span>),
done=payload.get(<span class="hljs-string">&quot;done&quot;</span>, <span class="hljs-literal">False</span>),
reward=payload.get(<span class="hljs-string">&quot;reward&quot;</span>),
)
<span class="hljs-keyword">return</span> StepResult(
observation=obs,
reward=payload.get(<span class="hljs-string">&quot;reward&quot;</span>),
done=payload.get(<span class="hljs-string">&quot;done&quot;</span>, <span class="hljs-literal">False</span>),
)
<span class="hljs-keyword">def</span> <span class="hljs-title function_">_parse_state</span>(<span class="hljs-params">self, payload: <span class="hljs-built_in">dict</span></span>) -&gt; State:
<span class="hljs-keyword">return</span> State(
episode_id=payload.get(<span class="hljs-string">&quot;episode_id&quot;</span>),
step_count=payload.get(<span class="hljs-string">&quot;step_count&quot;</span>, <span class="hljs-number">0</span>),
)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1gtng2a">The <code>EnvClient</code> maintains a persistent WebSocket connection to the server, enabling efficient multi-step interactions with lower latency compared to HTTP. Each client instance gets its own dedicated environment session on the server.</p> <h3 class="relative group"><a id="6-configure-dependencies--dockerfile" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#6-configure-dependencies--dockerfile"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>6. Configure Dependencies &amp; Dockerfile</span></h3> <p data-svelte-h="svelte-az7dkj">The CLI template ships with <code>pyproject.toml</code> and <code>server/Dockerfile</code>. You should manage your python dependencies with <code>uv</code> or <code>pip</code> in the <code>pyproject.toml</code> file. Other dependencies should be installed in the Dockerfile.</p> <p data-svelte-h="svelte-1gnchy7">Keep building from the <code>openenv-base</code> image so shared tooling stays available:</p> <details><summary data-svelte-h="svelte-ycltuu">Dockerfile</summary> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-dockerfile "><!-- HTML_TAG_START --><span class="hljs-comment"># Copyright (c) Meta Platforms, Inc. and affiliates.</span>
<span class="hljs-comment"># All rights reserved.</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment"># This source code is licensed under the BSD-style license found in the</span>
<span class="hljs-comment"># LICENSE file in the root directory of this source tree.</span>
<span class="hljs-comment"># Multi-stage build using openenv-base</span>
<span class="hljs-comment"># This Dockerfile is flexible and works for both:</span>
<span class="hljs-comment"># - In-repo environments (with local src/core)</span>
<span class="hljs-comment"># - Standalone environments (with openenv from pip)</span>
<span class="hljs-comment"># The build script (openenv build) handles context detection and sets appropriate build args.</span>
<span class="hljs-keyword">ARG</span> BASE_IMAGE=openenv-base:latest
<span class="hljs-keyword">FROM</span> ${BASE_IMAGE} AS builder
<span class="hljs-keyword">WORKDIR</span><span class="language-bash"> /app</span>
<span class="hljs-comment"># Build argument to control whether we&#x27;re building standalone or in-repo</span>
<span class="hljs-keyword">ARG</span> BUILD_MODE=in-repo
<span class="hljs-keyword">ARG</span> ENV_NAME=__ENV_NAME__
<span class="hljs-comment"># Copy environment code (always at root of build context)</span>
<span class="hljs-keyword">COPY</span><span class="language-bash"> . /app/env</span>
<span class="hljs-comment"># For in-repo builds, openenv is already in the pyproject.toml dependencies</span>
<span class="hljs-comment"># For standalone builds, openenv will be installed from pip via pyproject.toml</span>
<span class="hljs-keyword">WORKDIR</span><span class="language-bash"> /app/env</span>
<span class="hljs-comment"># Install dependencies using uv sync</span>
<span class="hljs-comment"># If uv.lock exists, use it; otherwise resolve on the fly</span>
<span class="hljs-keyword">RUN</span><span class="language-bash"> --mount=<span class="hljs-built_in">type</span>=cache,target=/root/.cache/uv \
<span class="hljs-keyword">if</span> [ -f uv.lock ]; <span class="hljs-keyword">then</span> \
uv <span class="hljs-built_in">sync</span> --frozen --no-install-project --no-editable; \
<span class="hljs-keyword">else</span> \
uv <span class="hljs-built_in">sync</span> --no-install-project --no-editable; \
<span class="hljs-keyword">fi</span></span>
<span class="hljs-keyword">RUN</span><span class="language-bash"> --mount=<span class="hljs-built_in">type</span>=cache,target=/root/.cache/uv \
<span class="hljs-keyword">if</span> [ -f uv.lock ]; <span class="hljs-keyword">then</span> \
uv <span class="hljs-built_in">sync</span> --frozen --no-editable; \
<span class="hljs-keyword">else</span> \
uv <span class="hljs-built_in">sync</span> --no-editable; \
<span class="hljs-keyword">fi</span></span>
<span class="hljs-comment"># Final runtime stage</span>
<span class="hljs-keyword">FROM</span> ${BASE_IMAGE}
<span class="hljs-keyword">WORKDIR</span><span class="language-bash"> /app</span>
<span class="hljs-comment"># Copy the virtual environment from builder</span>
<span class="hljs-keyword">COPY</span><span class="language-bash"> --from=builder /app/env/.venv /app/.venv</span>
<span class="hljs-comment"># Copy the environment code</span>
<span class="hljs-keyword">COPY</span><span class="language-bash"> --from=builder /app/env /app/env</span>
<span class="hljs-comment"># Set PATH to use the virtual environment</span>
<span class="hljs-keyword">ENV</span> PATH=<span class="hljs-string">&quot;/app/.venv/bin:$PATH&quot;</span>
<span class="hljs-comment"># Set PYTHONPATH so imports work correctly</span>
<span class="hljs-keyword">ENV</span> PYTHONPATH=<span class="hljs-string">&quot;/app/env:$PYTHONPATH&quot;</span>
<span class="hljs-comment"># Health check</span>
<span class="hljs-keyword">HEALTHCHECK</span><span class="language-bash"> --interval=30s --<span class="hljs-built_in">timeout</span>=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || <span class="hljs-built_in">exit</span> 1</span>
<span class="hljs-comment"># Run the FastAPI server</span>
<span class="hljs-comment"># The module path is constructed to work with the /app/env structure</span>
<span class="hljs-keyword">CMD</span><span class="language-bash"> [<span class="hljs-string">&quot;sh&quot;</span>, <span class="hljs-string">&quot;-c&quot;</span>, <span class="hljs-string">&quot;cd /app/env &amp;&amp; uvicorn server.app:app --host 0.0.0.0 --port 8000&quot;</span>]</span>
<!-- HTML_TAG_END --></pre></div></details> <p data-svelte-h="svelte-19ugog0">If you introduced extra dependencies in the Dockerfile, you should install them in the Dockerfile before removing temp files.</p> <h3 class="relative group"><a id="7-build--validate-with-the-cli" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#7-build--validate-with-the-cli"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>7. Build &amp; Validate with the CLI</span></h3> <p data-svelte-h="svelte-u4crad">From the environment directory:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-bash "><!-- HTML_TAG_START --><span class="hljs-built_in">cd</span> envs/my_env
openenv build <span class="hljs-comment"># Builds Docker image (auto-detects context)</span>
openenv validate --verbose<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-wir32s"><code>openenv build</code> understands both standalone environments and in-repo ones. Useful flags:</p> <ul data-svelte-h="svelte-1ddboft"><li><code>--tag/-t</code>: override the default <code>openenv-&lt;env_name&gt;</code> tag</li> <li><code>--build-arg KEY=VALUE</code>: pass multiple Docker build arguments</li> <li><code>--dockerfile</code> / <code>--context</code>: custom locations when experimenting</li> <li><code>--no-cache</code>: force fresh dependency installs</li></ul> <p data-svelte-h="svelte-1i9gylz"><code>openenv validate</code> checks for required files, ensures the Dockerfile/server entrypoints function, and lists supported deployment modes. The command exits non-zero if issues are found so you can wire it into CI.</p> <h3 class="relative group"><a id="8-push--share-with-openenv-push" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#8-push--share-with-openenv-push"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>8. Push &amp; Share with openenv push</span></h3> <p data-svelte-h="svelte-l2ct19">Once validation passes, the CLI can deploy directly to Hugging Face Spaces or any registry:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-bash "><!-- HTML_TAG_START --><span class="hljs-comment"># Push to HF Spaces (auto enables web UI and prompts for login if needed)</span>
openenv push
<span class="hljs-comment"># Push to a specific repo or namespace</span>
openenv push --repo-id my-org/my-env
<span class="hljs-comment"># Push to Docker/ghcr (interface disabled by default)</span>
openenv push --registry ghcr.io/my-org --tag my-env:latest
<span class="hljs-comment"># Customize image base or visibility</span>
openenv push --base-image ghcr.io/meta-pytorch/openenv-base:latest --private
<span class="hljs-comment"># Configure Space variables and secrets at push time</span>
openenv push -e OPENSPIEL_GAME=tic_tac_toe --secret OPENAI_API_KEY=sk-...<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-ctgyqz">Key options:</p> <ul data-svelte-h="svelte-nchqxm"><li><code>--directory</code>: path to the environment (defaults to <code>cwd</code>)</li> <li><code>--repo-id</code>: explicit Hugging Face space name</li> <li><code>--registry</code>: push to Docker Hub, GHCR, etc.</li> <li><code>--interface/--no-interface</code>: toggle the optional web UI</li> <li><code>--base-image</code>: override the Dockerfile <code>FROM</code></li> <li><code>--private</code>: mark the space as private</li> <li><code>--env-var/-e KEY=VALUE</code>: set a public Space variable (repeatable); overrides matching keys from <code>variables:</code> in <code>openenv.yaml</code></li> <li><code>--secret KEY=VALUE</code>: set a private Space secret (repeatable); value is never logged</li></ul> <p data-svelte-h="svelte-1bgmmlj">The command validates your <code>openenv.yaml</code>, injects Hugging Face frontmatter when needed, and uploads the prepared bundle.
Space variables and secrets are only applied on direct Hugging Face Space pushes;
they are not available for <code>--registry</code>, and they cannot be staged through
<code>--create-pr</code>.</p> <h4 class="relative group"><a id="declaring-public-variables-in-openenvyaml" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#declaring-public-variables-in-openenvyaml"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Declaring public variables in openenv.yaml</span></h4> <p data-svelte-h="svelte-x39e7s">For defaults that belong with the environment (game name, benchmark, max
steps…), add a <code>variables:</code> block to <code>openenv.yaml</code>; <code>openenv push</code> will apply
them to the Space automatically:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-yaml "><!-- HTML_TAG_START --><span class="hljs-attr">variables:</span>
<span class="hljs-attr">OPENSPIEL_GAME:</span> <span class="hljs-string">catch</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-12uu88k">CLI <code>-e</code> overrides matching keys. Put secrets (API keys, tokens) <strong>only</strong> on
the CLI via <code>--secret KEY=VALUE</code> — never in the yaml.</p> <h3 class="relative group"><a id="9-automate-builds-optional" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#9-automate-builds-optional"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>9. Automate Builds (optional)</span></h3> <p data-svelte-h="svelte-tsfsth">To trigger Docker builds on every push to <code>main</code>, add your environment to the matrix in <code>.github/workflows/docker-build.yml</code>:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-yaml "><!-- HTML_TAG_START --><span class="hljs-attr">strategy:</span>
<span class="hljs-attr">matrix:</span>
<span class="hljs-attr">image:</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">echo-env</span>
<span class="hljs-attr">dockerfile:</span> <span class="hljs-string">envs/echo_env/server/Dockerfile</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">chat-env</span>
<span class="hljs-attr">dockerfile:</span> <span class="hljs-string">envs/chat_env/server/Dockerfile</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">coding-env</span>
<span class="hljs-attr">dockerfile:</span> <span class="hljs-string">envs/coding_env/server/Dockerfile</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">my-env</span> <span class="hljs-comment"># Add your environment here</span>
<span class="hljs-attr">dockerfile:</span> <span class="hljs-string">envs/my_env/server/Dockerfile</span><!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="use-your-environment" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#use-your-environment"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Use Your Environment</span></h3> <p data-svelte-h="svelte-xtyn70">Here is a simple example of using your environment:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> envs.my_env <span class="hljs-keyword">import</span> MyAction, MyEnv
<span class="hljs-comment"># Create environment from Docker image</span>
client = MyEnv.from_docker_image(<span class="hljs-string">&quot;my-env:latest&quot;</span>)
<span class="hljs-comment"># Or, connect to the remote space on Hugging Face</span>
client = MyEnv.from_hub(<span class="hljs-string">&quot;my-org/my-env&quot;</span>)
<span class="hljs-comment"># Or, connect to the local server</span>
client = MyEnv(base_url=<span class="hljs-string">&quot;http://localhost:8000&quot;</span>)
<span class="hljs-comment"># Use context manager for automatic cleanup (recommended)</span>
<span class="hljs-keyword">with</span> client:
<span class="hljs-comment"># Reset</span>
result = client.reset()
<span class="hljs-built_in">print</span>(result.observation.result) <span class="hljs-comment"># &quot;Ready&quot;</span>
<span class="hljs-comment"># Execute actions</span>
result = client.step(MyAction(command=<span class="hljs-string">&quot;test&quot;</span>, parameters={}))
<span class="hljs-built_in">print</span>(result.observation.result)
<span class="hljs-built_in">print</span>(result.observation.success)
<span class="hljs-comment"># Get state</span>
state = client.state()
<span class="hljs-built_in">print</span>(state.episode_id)
<span class="hljs-built_in">print</span>(state.step_count)
<span class="hljs-comment"># Or manually manage the connection</span>
<span class="hljs-keyword">try</span>:
client = MyEnv(base_url=<span class="hljs-string">&quot;http://localhost:8000&quot;</span>)
result = client.reset()
result = client.step(MyAction(command=<span class="hljs-string">&quot;test&quot;</span>, parameters={}))
<span class="hljs-keyword">finally</span>:
client.close()<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="nice-work-youve-now-built-and-used-your-own-openenv-environment" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#nice-work-youve-now-built-and-used-your-own-openenv-environment"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Nice work! You’ve now built and used your own OpenEnv environment.</span></h2> <p data-svelte-h="svelte-15prqjs">Your next steps are to:</p> <ul data-svelte-h="svelte-1qkff8e"><li><a href="https://colab.research.google.com/github/huggingface/OpenEnv/blob/main/examples/OpenEnv_Tutorial.ipynb" rel="nofollow">Try out the end-to-end tutorial</a></li></ul> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/openenv/blob/main/docs/source/getting_started/environment-builder.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p>
<script>
{
__sveltekit_1qwoa43 = {
assets: "/docs/openenv/pr_749/en",
base: "/docs/openenv/pr_749/en",
env: {}
};
const element = document.currentScript.parentElement;
const data = [null,null];
Promise.all([
import("/docs/openenv/pr_749/en/_app/immutable/entry/start.85477f45.js"),
import("/docs/openenv/pr_749/en/_app/immutable/entry/app.51835dc5.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 40],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
74.3 kB
·
Xet hash:
553141e410585dc1817566abb77013ba1d224b1cbfd2b3864a31c0baa0fb91cb

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.