Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Packaging & Deploying","local":"packaging--deploying","sections":[{"title":"Quick Reference Card","local":"quick-reference-card","sections":[{"title":"CLI Quick Reference","local":"cli-quick-reference","sections":[],"depth":3}],"depth":2},{"title":"Overview","local":"overview","sections":[{"title":"Prerequisites","local":"prerequisites","sections":[],"depth":3}],"depth":2},{"title":"Step-by-Step Guide","local":"step-by-step-guide","sections":[{"title":"1. Scaffold with openenv init","local":"1-scaffold-with-openenv-init","sections":[],"depth":3},{"title":"2. Define Models","local":"2-define-models","sections":[],"depth":3},{"title":"3. Implement Environment Logic","local":"3-implement-environment-logic","sections":[],"depth":3},{"title":"4. Create the FastAPI Server","local":"4-create-the-fastapi-server","sections":[],"depth":3},{"title":"5. Implement the Client","local":"5-implement-the-client","sections":[],"depth":3},{"title":"6. Configure Dependencies & Dockerfile","local":"6-configure-dependencies--dockerfile","sections":[],"depth":3},{"title":"7. Build & Validate with the CLI","local":"7-build--validate-with-the-cli","sections":[],"depth":3},{"title":"8. Push & Share with openenv push","local":"8-push--share-with-openenv-push","sections":[{"title":"Declaring public variables in openenv.yaml","local":"declaring-public-variables-in-openenvyaml","sections":[],"depth":4}],"depth":3},{"title":"9. Automate Builds (optional)","local":"9-automate-builds-optional","sections":[],"depth":3},{"title":"Use Your Environment","local":"use-your-environment","sections":[],"depth":3}],"depth":2},{"title":"Nice work! You’ve now built and used your own OpenEnv environment.","local":"nice-work-youve-now-built-and-used-your-own-openenv-environment","sections":[],"depth":2}],"depth":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="{"title":"Packaging & Deploying","local":"packaging--deploying","sections":[{"title":"Quick Reference Card","local":"quick-reference-card","sections":[{"title":"CLI Quick Reference","local":"cli-quick-reference","sections":[],"depth":3}],"depth":2},{"title":"Overview","local":"overview","sections":[{"title":"Prerequisites","local":"prerequisites","sections":[],"depth":3}],"depth":2},{"title":"Step-by-Step Guide","local":"step-by-step-guide","sections":[{"title":"1. Scaffold with openenv init","local":"1-scaffold-with-openenv-init","sections":[],"depth":3},{"title":"2. Define Models","local":"2-define-models","sections":[],"depth":3},{"title":"3. Implement Environment Logic","local":"3-implement-environment-logic","sections":[],"depth":3},{"title":"4. Create the FastAPI Server","local":"4-create-the-fastapi-server","sections":[],"depth":3},{"title":"5. Implement the Client","local":"5-implement-the-client","sections":[],"depth":3},{"title":"6. Configure Dependencies & Dockerfile","local":"6-configure-dependencies--dockerfile","sections":[],"depth":3},{"title":"7. Build & Validate with the CLI","local":"7-build--validate-with-the-cli","sections":[],"depth":3},{"title":"8. Push & Share with openenv push","local":"8-push--share-with-openenv-push","sections":[{"title":"Declaring public variables in openenv.yaml","local":"declaring-public-variables-in-openenvyaml","sections":[],"depth":4}],"depth":3},{"title":"9. Automate Builds (optional)","local":"9-automate-builds-optional","sections":[],"depth":3},{"title":"Use Your Environment","local":"use-your-environment","sections":[],"depth":3}],"depth":2},{"title":"Nice work! You’ve now built and used your own OpenEnv environment.","local":"nice-work-youve-now-built-and-used-your-own-openenv-environment","sections":[],"depth":2}],"depth":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 & 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 & 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("you/my-env")</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">"""Your custom action."""</span> | |
| command: <span class="hljs-built_in">str</span> = Field(..., description=<span class="hljs-string">"Command to execute"</span>) | |
| parameters: <span class="hljs-built_in">dict</span> = Field(default_factory=<span class="hljs-built_in">dict</span>, description=<span class="hljs-string">"Command parameters"</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">"""Your custom observation."""</span> | |
| result: <span class="hljs-built_in">str</span> = Field(..., description=<span class="hljs-string">"Result of the action"</span>) | |
| success: <span class="hljs-built_in">bool</span> = Field(..., description=<span class="hljs-string">"Whether the action succeeded"</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>) -> 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">"Ready"</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>) -> 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>) -> 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">"my_env"</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">"MY_API_KEY"</span>) | |
| timeout = <span class="hljs-built_in">int</span>(os.getenv(<span class="hljs-string">"MY_TIMEOUT"</span>, <span class="hljs-string">"30"</span>)) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">create_my_environment</span>(): | |
| <span class="hljs-string">"""Factory function that creates MyEnvironment with config."""</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">"my_env"</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>) -> <span class="hljs-built_in">dict</span>: | |
| <span class="hljs-keyword">return</span> {<span class="hljs-string">"command"</span>: action.command, <span class="hljs-string">"parameters"</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>) -> StepResult[MyObservation]: | |
| obs_data = payload.get(<span class="hljs-string">"observation"</span>, {}) | |
| obs = MyObservation( | |
| result=obs_data.get(<span class="hljs-string">"result"</span>, <span class="hljs-string">""</span>), | |
| success=obs_data.get(<span class="hljs-string">"success"</span>, <span class="hljs-literal">False</span>), | |
| done=payload.get(<span class="hljs-string">"done"</span>, <span class="hljs-literal">False</span>), | |
| reward=payload.get(<span class="hljs-string">"reward"</span>), | |
| ) | |
| <span class="hljs-keyword">return</span> StepResult( | |
| observation=obs, | |
| reward=payload.get(<span class="hljs-string">"reward"</span>), | |
| done=payload.get(<span class="hljs-string">"done"</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>) -> State: | |
| <span class="hljs-keyword">return</span> State( | |
| episode_id=payload.get(<span class="hljs-string">"episode_id"</span>), | |
| step_count=payload.get(<span class="hljs-string">"step_count"</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 & 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'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">"/app/.venv/bin:$PATH"</span> | |
| <span class="hljs-comment"># Set PYTHONPATH so imports work correctly</span> | |
| <span class="hljs-keyword">ENV</span> PYTHONPATH=<span class="hljs-string">"/app/env:$PYTHONPATH"</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">"sh"</span>, <span class="hljs-string">"-c"</span>, <span class="hljs-string">"cd /app/env && uvicorn server.app:app --host 0.0.0.0 --port 8000"</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 & 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-<env_name></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 & 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">"my-env:latest"</span>) | |
| <span class="hljs-comment"># Or, connect to the remote space on Hugging Face</span> | |
| client = MyEnv.from_hub(<span class="hljs-string">"my-org/my-env"</span>) | |
| <span class="hljs-comment"># Or, connect to the local server</span> | |
| client = MyEnv(base_url=<span class="hljs-string">"http://localhost:8000"</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"># "Ready"</span> | |
| <span class="hljs-comment"># Execute actions</span> | |
| result = client.step(MyAction(command=<span class="hljs-string">"test"</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">"http://localhost:8000"</span>) | |
| result = client.reset() | |
| result = client.step(MyAction(command=<span class="hljs-string">"test"</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.