Python browser sandbox based on Pyodide. Write and share Python code, run it in the browser.
Built to demonstrate Pydantic, PydanticAI, and Pydantic Logfire.
If you choose to save code, it's stored in CloudFlare's R2 object storage, and should be available for one year.
Dependencies are installed when code is run.
Dependencies can be defined in one of two ways:
If there's no metadata, dependencies are inferred from imports in the code.
import pydantic
class Model(pydantic.BaseModel):
x: int
print(Model(x='42'))
As introduced in PEP 723, explained here, and popularised by uv — dependencies can be defined in a comment at the top of the file.
This allows use of dependencies that aren't imported in the code, and is more explicit.
# /// script
# dependencies = ["pydantic", "email-validator"]
# ///
import pydantic
class Model(pydantic.BaseModel):
email: pydantic.EmailStr
print(Model(email='hello@pydantic.dev'))
It also allows version to be pinned for non-binary packages (Pyodide only supports a single version for the binary packages it supports, like pydantic
and numpy
).
# /// script
# dependencies = ["rich<13"]
# ///
import rich
from importlib.metadata import version
rich.print(f'[red]Rich version:[/red] [blue]{version('rich')}[/blue]')
To programmatically create a sandbox, make a GET
request to https://pydantic.run/new
, with the files
parameter set to a JSON object containing the files you want to show.
The response is a 302 redirect to the newly created sandbox, hence you can direct a user to a sandbox with the code you want them to see. Repeated requests with the same files
will use the same sandbox.
files
should be an array of objects with the following keys:
name
- (string) the name of the filecontent
- (string) the content of the file- Optionally
activeIndex
- (integer) indicating which file/tab is open by default, the highest value wins
You can also set the tab
parameter to select which tab is open by default, that advantage of using this over activeIndex
is that it will reuse the same sandbox for requests choosing different tabs.
Here's a minimal HTML page that provides a link to create a new sandbox with two files:
<div>loading...</div>
<script>
const files = [
{
name: 'main.py',
content: 'print("This is an example!")',
activeIndex: 1,
},
{
name: 'another.py',
content: 'x = 42\nprint(f"The answer is {x}")',
},
]
const redirectUrl = new URL('https://pydantic.run/new')
redirectUrl.searchParams.append('files', JSON.stringify(files))
document.querySelector('div').innerHTML = `<a href="${redirectUrl}">Click here to create a new sandbox</a>`
</script>
Demo here.