miosa 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- miosa-0.4.0/.gitignore +13 -0
- miosa-0.4.0/BUILDER_GUIDE.md +64 -0
- miosa-0.4.0/PKG-INFO +293 -0
- miosa-0.4.0/README.md +254 -0
- miosa-0.4.0/examples/agent_builds_static_app.py +160 -0
- miosa-0.4.0/examples/agent_sandbox_app_builder.py +25 -0
- miosa-0.4.0/examples/agent_sandbox_artifact_builder.py +26 -0
- miosa-0.4.0/examples/agent_sandbox_slide_deck_builder.py +25 -0
- miosa-0.4.0/examples/agent_sandbox_website_builder.py +24 -0
- miosa-0.4.0/miosa/__init__.py +145 -0
- miosa-0.4.0/miosa/_http.py +421 -0
- miosa-0.4.0/miosa/agent/__init__.py +58 -0
- miosa-0.4.0/miosa/agent/core.py +136 -0
- miosa-0.4.0/miosa/agent/presets.py +41 -0
- miosa-0.4.0/miosa/agent/providers.py +288 -0
- miosa-0.4.0/miosa/agent/tools.py +251 -0
- miosa-0.4.0/miosa/agent/types.py +79 -0
- miosa-0.4.0/miosa/client.py +286 -0
- miosa-0.4.0/miosa/errors.py +153 -0
- miosa-0.4.0/miosa/py.typed +1 -0
- miosa-0.4.0/miosa/resources/__init__.py +86 -0
- miosa-0.4.0/miosa/resources/admin.py +565 -0
- miosa-0.4.0/miosa/resources/agent.py +144 -0
- miosa-0.4.0/miosa/resources/analytics.py +87 -0
- miosa-0.4.0/miosa/resources/api_keys.py +86 -0
- miosa-0.4.0/miosa/resources/audit_log.py +46 -0
- miosa-0.4.0/miosa/resources/benchmarks.py +127 -0
- miosa-0.4.0/miosa/resources/builder_sessions.py +94 -0
- miosa-0.4.0/miosa/resources/channels.py +130 -0
- miosa-0.4.0/miosa/resources/checkpoints.py +248 -0
- miosa-0.4.0/miosa/resources/command_center.py +103 -0
- miosa-0.4.0/miosa/resources/community.py +138 -0
- miosa-0.4.0/miosa/resources/completions.py +126 -0
- miosa-0.4.0/miosa/resources/computer.py +724 -0
- miosa-0.4.0/miosa/resources/computer_extras.py +637 -0
- miosa-0.4.0/miosa/resources/computers.py +164 -0
- miosa-0.4.0/miosa/resources/cron_jobs.py +175 -0
- miosa-0.4.0/miosa/resources/custom_domains.py +136 -0
- miosa-0.4.0/miosa/resources/dashboard.py +47 -0
- miosa-0.4.0/miosa/resources/databases.py +200 -0
- miosa-0.4.0/miosa/resources/deployments.py +1170 -0
- miosa-0.4.0/miosa/resources/desktop.py +779 -0
- miosa-0.4.0/miosa/resources/egress_audit.py +346 -0
- miosa-0.4.0/miosa/resources/egress_network.py +633 -0
- miosa-0.4.0/miosa/resources/egress_secrets.py +679 -0
- miosa-0.4.0/miosa/resources/email.py +316 -0
- miosa-0.4.0/miosa/resources/embeddings.py +66 -0
- miosa-0.4.0/miosa/resources/events.py +312 -0
- miosa-0.4.0/miosa/resources/exec.py +310 -0
- miosa-0.4.0/miosa/resources/external_keys.py +89 -0
- miosa-0.4.0/miosa/resources/files.py +315 -0
- miosa-0.4.0/miosa/resources/flat_custom_domains.py +61 -0
- miosa-0.4.0/miosa/resources/functions.py +144 -0
- miosa-0.4.0/miosa/resources/health_checks.py +84 -0
- miosa-0.4.0/miosa/resources/integrations.py +168 -0
- miosa-0.4.0/miosa/resources/mcp.py +83 -0
- miosa-0.4.0/miosa/resources/models.py +66 -0
- miosa-0.4.0/miosa/resources/network_policy.py +134 -0
- miosa-0.4.0/miosa/resources/open_computers/__init__.py +133 -0
- miosa-0.4.0/miosa/resources/open_computers/agents.py +105 -0
- miosa-0.4.0/miosa/resources/open_computers/apps.py +112 -0
- miosa-0.4.0/miosa/resources/open_computers/clusters.py +99 -0
- miosa-0.4.0/miosa/resources/open_computers/files.py +130 -0
- miosa-0.4.0/miosa/resources/open_computers/hosts.py +89 -0
- miosa-0.4.0/miosa/resources/open_computers/jobs.py +95 -0
- miosa-0.4.0/miosa/resources/open_computers/secrets.py +115 -0
- miosa-0.4.0/miosa/resources/open_computers/terminal_desktop.py +64 -0
- miosa-0.4.0/miosa/resources/open_computers/tunnels.py +82 -0
- miosa-0.4.0/miosa/resources/open_computers/types.py +434 -0
- miosa-0.4.0/miosa/resources/open_computers/workspaces.py +158 -0
- miosa-0.4.0/miosa/resources/org_invites.py +187 -0
- miosa-0.4.0/miosa/resources/project_auth.py +150 -0
- miosa-0.4.0/miosa/resources/project_integrations.py +128 -0
- miosa-0.4.0/miosa/resources/provider_defaults.py +119 -0
- miosa-0.4.0/miosa/resources/regions.py +89 -0
- miosa-0.4.0/miosa/resources/sandbox_namespaces.py +1287 -0
- miosa-0.4.0/miosa/resources/sandbox_templates.py +116 -0
- miosa-0.4.0/miosa/resources/sandboxes.py +1635 -0
- miosa-0.4.0/miosa/resources/services.py +249 -0
- miosa-0.4.0/miosa/resources/settings.py +148 -0
- miosa-0.4.0/miosa/resources/snapshots_standalone.py +64 -0
- miosa-0.4.0/miosa/resources/storage.py +277 -0
- miosa-0.4.0/miosa/resources/tenant.py +37 -0
- miosa-0.4.0/miosa/resources/usage.py +90 -0
- miosa-0.4.0/miosa/resources/volumes.py +113 -0
- miosa-0.4.0/miosa/resources/webhooks.py +100 -0
- miosa-0.4.0/miosa/resources/workspace_invites.py +197 -0
- miosa-0.4.0/miosa/resources/workspace_members.py +168 -0
- miosa-0.4.0/miosa/resources/workspaces.py +314 -0
- miosa-0.4.0/miosa/types.py +1142 -0
- miosa-0.4.0/pyproject.toml +79 -0
- miosa-0.4.0/tests/__init__.py +0 -0
- miosa-0.4.0/tests/conftest.py +70 -0
- miosa-0.4.0/tests/test_checkpoints.py +79 -0
- miosa-0.4.0/tests/test_client.py +1063 -0
- miosa-0.4.0/tests/test_custom_domains.py +78 -0
- miosa-0.4.0/tests/test_egress.py +276 -0
- miosa-0.4.0/tests/test_events_spawn.py +218 -0
- miosa-0.4.0/tests/test_http_transport.py +63 -0
- miosa-0.4.0/tests/test_network_policy.py +93 -0
- miosa-0.4.0/tests/test_open_computers.py +264 -0
- miosa-0.4.0/tests/test_sandbox_gaps.py +598 -0
- miosa-0.4.0/tests/test_sandbox_live.py +165 -0
- miosa-0.4.0/tests/test_services.py +96 -0
- miosa-0.4.0/tests/test_wait_until_ready.py +92 -0
- miosa-0.4.0/tests/test_workspace_members.py +74 -0
- miosa-0.4.0/tests/test_workspaces.py +81 -0
- miosa-0.4.0/uv.lock +1066 -0
miosa-0.4.0/.gitignore
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Build Your Own Lovable With MIOSA Sandboxes
|
|
2
|
+
|
|
3
|
+
The Python agent SDK lets your product run a prompt-to-app builder on top of
|
|
4
|
+
MIOSA sandboxes.
|
|
5
|
+
|
|
6
|
+
Use it for:
|
|
7
|
+
|
|
8
|
+
- AI website builders with live previews
|
|
9
|
+
- AI app builders with source files, shell commands, tests, and dev servers
|
|
10
|
+
- artifact builders that generate docs, reports, and export bundles
|
|
11
|
+
- slide deck builders that render and repair decks in a sandbox
|
|
12
|
+
|
|
13
|
+
## Minimal Website Builder
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import os
|
|
17
|
+
from miosa.agent import Agent, groq_provider, sandbox_builder_system_prompt
|
|
18
|
+
|
|
19
|
+
agent = Agent(
|
|
20
|
+
provider=groq_provider(
|
|
21
|
+
api_key=os.environ["GROQ_API_KEY"],
|
|
22
|
+
model="moonshotai/kimi-k2-instruct-0905",
|
|
23
|
+
),
|
|
24
|
+
miosa_api_key=os.environ["MIOSA_API_KEY"],
|
|
25
|
+
miosa_tool_options={"allow_destroy": False},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
result = agent.run(
|
|
29
|
+
"Build a landing page for a boutique gym. Run it on port 3000 and give me the preview URL.",
|
|
30
|
+
system=sandbox_builder_system_prompt("website"),
|
|
31
|
+
max_iterations=12,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
print(result.final_text)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Product Pattern
|
|
38
|
+
|
|
39
|
+
1. Create one sandbox per project or generation run.
|
|
40
|
+
2. Give the agent the builder preset and a user prompt.
|
|
41
|
+
3. Stream steps into your UI as command logs and file activity.
|
|
42
|
+
4. Show the preview URL in an iframe.
|
|
43
|
+
5. Let the user ask for revisions against the same sandbox.
|
|
44
|
+
6. Export, publish, snapshot, or destroy the sandbox when done.
|
|
45
|
+
|
|
46
|
+
## Presets
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
sandbox_builder_system_prompt("website")
|
|
50
|
+
sandbox_builder_system_prompt("app")
|
|
51
|
+
sandbox_builder_system_prompt("artifact")
|
|
52
|
+
sandbox_builder_system_prompt("slide_deck")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
These prompts make the agent work under `/workspace`, run and verify outputs,
|
|
56
|
+
return file paths and preview URLs, and keep the sandbox alive unless cleanup is
|
|
57
|
+
requested.
|
|
58
|
+
|
|
59
|
+
Runnable examples:
|
|
60
|
+
|
|
61
|
+
- `examples/agent_sandbox_website_builder.py`
|
|
62
|
+
- `examples/agent_sandbox_app_builder.py`
|
|
63
|
+
- `examples/agent_sandbox_artifact_builder.py`
|
|
64
|
+
- `examples/agent_sandbox_slide_deck_builder.py`
|
miosa-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: miosa
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Python SDK for the MIOSA API — desktop infrastructure for AI agents
|
|
5
|
+
Project-URL: Homepage, https://miosa.ai
|
|
6
|
+
Project-URL: Documentation, https://docs.miosa.ai/sdk/python
|
|
7
|
+
Project-URL: Repository, https://github.com/robertohluna/miosa-python
|
|
8
|
+
Author-email: MIOSA <dev@miosa.ai>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: agents,ai,cloud,desktop,miosa,sdk,vm
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Requires-Dist: httpx<1.0.0,>=0.25.0
|
|
23
|
+
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: h2<5.0.0,>=4.0.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
32
|
+
Requires-Dist: websockets>=11.0; extra == 'dev'
|
|
33
|
+
Provides-Extra: events
|
|
34
|
+
Requires-Dist: websockets>=11.0; extra == 'events'
|
|
35
|
+
Provides-Extra: http2
|
|
36
|
+
Requires-Dist: h2<5.0.0,>=4.0.0; extra == 'http2'
|
|
37
|
+
Requires-Dist: httpx[http2]<1.0.0,>=0.25.0; extra == 'http2'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# miosa (Python)
|
|
41
|
+
|
|
42
|
+
> Official Python SDK for MIOSA — the AI cloud platform for sandboxes, computers, deployments, and managed data.
|
|
43
|
+
|
|
44
|
+
[](https://pypi.org/project/miosa/)
|
|
45
|
+
[](https://pypi.org/project/miosa/)
|
|
46
|
+
[](https://opensource.org/licenses/MIT)
|
|
47
|
+
[](https://miosa.ai/docs/sdks/python)
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install miosa
|
|
53
|
+
# or
|
|
54
|
+
uv add miosa
|
|
55
|
+
# or
|
|
56
|
+
poetry add miosa
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Requires Python 3.9+. Dependencies: `httpx`, `pydantic v2`.
|
|
60
|
+
|
|
61
|
+
## Quickstart
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from miosa import Miosa
|
|
65
|
+
|
|
66
|
+
miosa = Miosa(api_key="msk_live_...")
|
|
67
|
+
|
|
68
|
+
# Boot a computer, run a command, expose a preview
|
|
69
|
+
computer = miosa.computers.create(
|
|
70
|
+
name="my-build",
|
|
71
|
+
template_type="miosa-sandbox",
|
|
72
|
+
size="small",
|
|
73
|
+
)
|
|
74
|
+
computer.start()
|
|
75
|
+
computer.wait(status="running")
|
|
76
|
+
|
|
77
|
+
result = computer.exec.run("python --version")
|
|
78
|
+
print(result.stdout) # Python 3.12.x
|
|
79
|
+
|
|
80
|
+
computer.files.write_file("/workspace/hello.py", "print('hello from miosa')")
|
|
81
|
+
out = computer.exec.run("python /workspace/hello.py")
|
|
82
|
+
print(out.stdout) # hello from miosa
|
|
83
|
+
|
|
84
|
+
print(computer.preview_url(8000, "/"))
|
|
85
|
+
# https://8000-<slug>.sandbox.miosa.ai/
|
|
86
|
+
|
|
87
|
+
computer.destroy()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## What's included
|
|
91
|
+
|
|
92
|
+
| Resource | Description |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `miosa.computers` | Firecracker microVMs — full lifecycle, exec, files, services |
|
|
95
|
+
| `miosa.sandboxes` | Lightweight code-execution VMs via the `/sandboxes` route |
|
|
96
|
+
| `miosa.deployments` | Versioned production releases with rollback |
|
|
97
|
+
| `miosa.databases` | Managed Postgres / Redis lifecycle |
|
|
98
|
+
| `miosa.storage` | S3-compatible object storage |
|
|
99
|
+
| `miosa.volumes` | Persistent block storage |
|
|
100
|
+
| `miosa.api_keys` | Programmatic API key management |
|
|
101
|
+
| `miosa.usage` | Usage reports per workspace, per external tenant |
|
|
102
|
+
| `miosa.settings` | Workspace config, branding, BYOK provider keys |
|
|
103
|
+
| `miosa.webhooks` | Outgoing tenant webhooks — CRUD, test, delivery history |
|
|
104
|
+
| `miosa.open_computers` | BYOC host management — register your own machines |
|
|
105
|
+
|
|
106
|
+
## Agent SDK
|
|
107
|
+
|
|
108
|
+
The Python SDK includes a small agent loop plus provider adapters and a MIOSA
|
|
109
|
+
tool catalogue. This is the quickest path when you want an LLM to operate
|
|
110
|
+
MIOSA computers directly.
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from miosa.agent import Agent, groq_provider
|
|
114
|
+
|
|
115
|
+
agent = Agent(
|
|
116
|
+
provider=groq_provider(
|
|
117
|
+
api_key="gsk_...",
|
|
118
|
+
model="moonshotai/kimi-k2-instruct-0905",
|
|
119
|
+
),
|
|
120
|
+
miosa_api_key="msk_live_...",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
result = agent.run(
|
|
124
|
+
"Create a sandbox, write /workspace/hello.py, run it, show me the output, "
|
|
125
|
+
"then destroy the sandbox.",
|
|
126
|
+
max_iterations=10,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
print(result.final_text)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Built-in agent tools expose the computer primitive in plain terms:
|
|
133
|
+
|
|
134
|
+
| Tool | Does |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `create_sandbox` | Boot a fast code sandbox computer for shell/Python/Node/files. |
|
|
137
|
+
| `create_computer` | Boot a general MIOSA computer for GUI, services, previews, files. |
|
|
138
|
+
| `list_computers` | List active computers, sandboxes, and desktops. |
|
|
139
|
+
| `get_computer` | Fetch status, template, size, and public URL. |
|
|
140
|
+
| `exec` / `exec_python` | Run bash or Python inside the computer. |
|
|
141
|
+
| `read_file` / `write_file` / `list_files` | Work with files inside the computer. |
|
|
142
|
+
| `preview_url` | Get the public HTTPS URL for a service port. |
|
|
143
|
+
| `destroy_computer` | Release compute resources when done. |
|
|
144
|
+
|
|
145
|
+
Provider factories include `openai_provider`, `groq_provider`,
|
|
146
|
+
`deepseek_provider`, `openrouter_provider`, `together_provider`,
|
|
147
|
+
`fireworks_provider`, `mistral_provider`, `cerebras_provider`,
|
|
148
|
+
`perplexity_provider`, `xai_provider`, `ollama_provider`, `lm_studio_provider`,
|
|
149
|
+
and `openai_compatible_provider` for custom routers.
|
|
150
|
+
|
|
151
|
+
Sandbox-first builder examples live in `examples/`:
|
|
152
|
+
|
|
153
|
+
See [BUILDER_GUIDE.md](./BUILDER_GUIDE.md) for the full “build your own
|
|
154
|
+
Lovable with MIOSA sandboxes” product pattern.
|
|
155
|
+
|
|
156
|
+
| Example | What it builds |
|
|
157
|
+
|---|---|
|
|
158
|
+
| `agent_sandbox_website_builder.py` | A Lovable-style website builder flow. |
|
|
159
|
+
| `agent_sandbox_app_builder.py` | A small app builder with a dev server and preview. |
|
|
160
|
+
| `agent_sandbox_artifact_builder.py` | Markdown/doc artifacts in `/workspace/artifacts`. |
|
|
161
|
+
| `agent_sandbox_slide_deck_builder.py` | A deck workspace under `/workspace/deck`. |
|
|
162
|
+
|
|
163
|
+
Set `GROQ_API_KEY` and `MIOSA_API_KEY`, then run one of the examples. They keep
|
|
164
|
+
the sandbox alive with `miosa_tool_options={"allow_destroy": False}` so your app
|
|
165
|
+
can show previews, inspect generated files, or publish later.
|
|
166
|
+
|
|
167
|
+
## File operations
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
# Write / read
|
|
171
|
+
computer.files.write_file("/workspace/config.json", '{"key": "value"}')
|
|
172
|
+
text = computer.files.read_file("/workspace/config.json")
|
|
173
|
+
|
|
174
|
+
# Upload / download
|
|
175
|
+
computer.files.upload("/local/report.pdf", "/workspace/report.pdf")
|
|
176
|
+
raw_bytes = computer.files.download("/workspace/report.pdf")
|
|
177
|
+
|
|
178
|
+
# List / stat / mkdir / rename / chmod
|
|
179
|
+
entries = computer.files.list("/workspace")
|
|
180
|
+
stat = computer.files.stat("/workspace/config.json")
|
|
181
|
+
computer.files.mkdir("/workspace/output", recursive=True)
|
|
182
|
+
computer.files.rename("/workspace/old.txt", "/workspace/new.txt")
|
|
183
|
+
computer.files.chmod("/workspace/run.sh", 0o755)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Services (background processes)
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
svc = computer.services.create(
|
|
190
|
+
name="api",
|
|
191
|
+
command="uvicorn app:main --port 8080",
|
|
192
|
+
working_dir="/workspace",
|
|
193
|
+
env={"DEBUG": "1"},
|
|
194
|
+
port=8080,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
for log in computer.services.logs(svc.id, follow=True):
|
|
198
|
+
print(log.stream, log.line)
|
|
199
|
+
|
|
200
|
+
computer.services.restart(svc.id)
|
|
201
|
+
computer.services.delete(svc.id)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Desktop control
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
screenshot = computer.screenshot() # PNG bytes
|
|
208
|
+
computer.click(640, 400)
|
|
209
|
+
computer.double_click(640, 400)
|
|
210
|
+
computer.type("hello world")
|
|
211
|
+
computer.key("Return")
|
|
212
|
+
computer.scroll("down", 3)
|
|
213
|
+
computer.drag(100, 100, 400, 400)
|
|
214
|
+
|
|
215
|
+
cursor = computer.cursor()
|
|
216
|
+
windows = computer.windows()
|
|
217
|
+
computer.launch("firefox")
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Async usage
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
import asyncio
|
|
224
|
+
from miosa import AsyncMiosa
|
|
225
|
+
|
|
226
|
+
async def main():
|
|
227
|
+
async with AsyncMiosa(api_key="msk_live_...") as miosa:
|
|
228
|
+
computer = await miosa.computers.create(
|
|
229
|
+
name="async-build", template_type="miosa-sandbox"
|
|
230
|
+
)
|
|
231
|
+
await computer.files.write_file("/workspace/app.py", "print('async!')")
|
|
232
|
+
result = await computer.exec.run("python /workspace/app.py")
|
|
233
|
+
print(result.stdout)
|
|
234
|
+
await computer.destroy()
|
|
235
|
+
|
|
236
|
+
asyncio.run(main())
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## White-label / multi-tenant
|
|
240
|
+
|
|
241
|
+
Tag resources with `external_workspace_id` and `external_user_id` to attribute usage to your downstream customers:
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
computer = miosa.computers.create(
|
|
245
|
+
name="customer-build",
|
|
246
|
+
template_type="miosa-sandbox",
|
|
247
|
+
metadata={
|
|
248
|
+
"external_workspace_id": "dental-office-123",
|
|
249
|
+
"external_user_id": "dr-smith-456",
|
|
250
|
+
},
|
|
251
|
+
)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Error handling
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from miosa import (
|
|
258
|
+
AuthenticationError, NotFoundError, RateLimitError, MiosaError
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
try:
|
|
262
|
+
computer = miosa.computers.get("cmp_doesnt_exist")
|
|
263
|
+
except NotFoundError:
|
|
264
|
+
print("Computer not found")
|
|
265
|
+
except RateLimitError as e:
|
|
266
|
+
print(f"Rate limited; retry after {e.retry_after}s")
|
|
267
|
+
except AuthenticationError:
|
|
268
|
+
print("Check your API key")
|
|
269
|
+
except MiosaError as e:
|
|
270
|
+
print(f"API error {e.status}: {e.message}")
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Exception hierarchy: `MiosaError` > `AuthenticationError` (401), `InsufficientCreditsError` (402), `PermissionError` (403), `NotFoundError` (404), `ValidationError` (422), `RateLimitError` (429), `ServerError` (5xx), `ConnectionError`, `TimeoutError`.
|
|
274
|
+
|
|
275
|
+
## Configuration
|
|
276
|
+
|
|
277
|
+
| Option | Env var | Default |
|
|
278
|
+
|---|---|---|
|
|
279
|
+
| `api_key` | `MIOSA_API_KEY` | — |
|
|
280
|
+
| `base_url` | `MIOSA_BASE_URL` | `https://api.miosa.ai/api/v1` |
|
|
281
|
+
| `timeout` | — | 30s |
|
|
282
|
+
| `max_retries` | — | 3 |
|
|
283
|
+
|
|
284
|
+
## Links
|
|
285
|
+
|
|
286
|
+
- [Full documentation](https://miosa.ai/docs/sdks/python)
|
|
287
|
+
- [Quickstart](https://miosa.ai/docs/quickstart)
|
|
288
|
+
- [GitHub](https://github.com/robertohluna/miosa-python)
|
|
289
|
+
- [Contact](mailto:platform@miosa.ai)
|
|
290
|
+
|
|
291
|
+
## License
|
|
292
|
+
|
|
293
|
+
MIT
|
miosa-0.4.0/README.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# miosa (Python)
|
|
2
|
+
|
|
3
|
+
> Official Python SDK for MIOSA — the AI cloud platform for sandboxes, computers, deployments, and managed data.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/miosa/)
|
|
6
|
+
[](https://pypi.org/project/miosa/)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://miosa.ai/docs/sdks/python)
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install miosa
|
|
14
|
+
# or
|
|
15
|
+
uv add miosa
|
|
16
|
+
# or
|
|
17
|
+
poetry add miosa
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Requires Python 3.9+. Dependencies: `httpx`, `pydantic v2`.
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from miosa import Miosa
|
|
26
|
+
|
|
27
|
+
miosa = Miosa(api_key="msk_live_...")
|
|
28
|
+
|
|
29
|
+
# Boot a computer, run a command, expose a preview
|
|
30
|
+
computer = miosa.computers.create(
|
|
31
|
+
name="my-build",
|
|
32
|
+
template_type="miosa-sandbox",
|
|
33
|
+
size="small",
|
|
34
|
+
)
|
|
35
|
+
computer.start()
|
|
36
|
+
computer.wait(status="running")
|
|
37
|
+
|
|
38
|
+
result = computer.exec.run("python --version")
|
|
39
|
+
print(result.stdout) # Python 3.12.x
|
|
40
|
+
|
|
41
|
+
computer.files.write_file("/workspace/hello.py", "print('hello from miosa')")
|
|
42
|
+
out = computer.exec.run("python /workspace/hello.py")
|
|
43
|
+
print(out.stdout) # hello from miosa
|
|
44
|
+
|
|
45
|
+
print(computer.preview_url(8000, "/"))
|
|
46
|
+
# https://8000-<slug>.sandbox.miosa.ai/
|
|
47
|
+
|
|
48
|
+
computer.destroy()
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## What's included
|
|
52
|
+
|
|
53
|
+
| Resource | Description |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `miosa.computers` | Firecracker microVMs — full lifecycle, exec, files, services |
|
|
56
|
+
| `miosa.sandboxes` | Lightweight code-execution VMs via the `/sandboxes` route |
|
|
57
|
+
| `miosa.deployments` | Versioned production releases with rollback |
|
|
58
|
+
| `miosa.databases` | Managed Postgres / Redis lifecycle |
|
|
59
|
+
| `miosa.storage` | S3-compatible object storage |
|
|
60
|
+
| `miosa.volumes` | Persistent block storage |
|
|
61
|
+
| `miosa.api_keys` | Programmatic API key management |
|
|
62
|
+
| `miosa.usage` | Usage reports per workspace, per external tenant |
|
|
63
|
+
| `miosa.settings` | Workspace config, branding, BYOK provider keys |
|
|
64
|
+
| `miosa.webhooks` | Outgoing tenant webhooks — CRUD, test, delivery history |
|
|
65
|
+
| `miosa.open_computers` | BYOC host management — register your own machines |
|
|
66
|
+
|
|
67
|
+
## Agent SDK
|
|
68
|
+
|
|
69
|
+
The Python SDK includes a small agent loop plus provider adapters and a MIOSA
|
|
70
|
+
tool catalogue. This is the quickest path when you want an LLM to operate
|
|
71
|
+
MIOSA computers directly.
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from miosa.agent import Agent, groq_provider
|
|
75
|
+
|
|
76
|
+
agent = Agent(
|
|
77
|
+
provider=groq_provider(
|
|
78
|
+
api_key="gsk_...",
|
|
79
|
+
model="moonshotai/kimi-k2-instruct-0905",
|
|
80
|
+
),
|
|
81
|
+
miosa_api_key="msk_live_...",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
result = agent.run(
|
|
85
|
+
"Create a sandbox, write /workspace/hello.py, run it, show me the output, "
|
|
86
|
+
"then destroy the sandbox.",
|
|
87
|
+
max_iterations=10,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
print(result.final_text)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Built-in agent tools expose the computer primitive in plain terms:
|
|
94
|
+
|
|
95
|
+
| Tool | Does |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `create_sandbox` | Boot a fast code sandbox computer for shell/Python/Node/files. |
|
|
98
|
+
| `create_computer` | Boot a general MIOSA computer for GUI, services, previews, files. |
|
|
99
|
+
| `list_computers` | List active computers, sandboxes, and desktops. |
|
|
100
|
+
| `get_computer` | Fetch status, template, size, and public URL. |
|
|
101
|
+
| `exec` / `exec_python` | Run bash or Python inside the computer. |
|
|
102
|
+
| `read_file` / `write_file` / `list_files` | Work with files inside the computer. |
|
|
103
|
+
| `preview_url` | Get the public HTTPS URL for a service port. |
|
|
104
|
+
| `destroy_computer` | Release compute resources when done. |
|
|
105
|
+
|
|
106
|
+
Provider factories include `openai_provider`, `groq_provider`,
|
|
107
|
+
`deepseek_provider`, `openrouter_provider`, `together_provider`,
|
|
108
|
+
`fireworks_provider`, `mistral_provider`, `cerebras_provider`,
|
|
109
|
+
`perplexity_provider`, `xai_provider`, `ollama_provider`, `lm_studio_provider`,
|
|
110
|
+
and `openai_compatible_provider` for custom routers.
|
|
111
|
+
|
|
112
|
+
Sandbox-first builder examples live in `examples/`:
|
|
113
|
+
|
|
114
|
+
See [BUILDER_GUIDE.md](./BUILDER_GUIDE.md) for the full “build your own
|
|
115
|
+
Lovable with MIOSA sandboxes” product pattern.
|
|
116
|
+
|
|
117
|
+
| Example | What it builds |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `agent_sandbox_website_builder.py` | A Lovable-style website builder flow. |
|
|
120
|
+
| `agent_sandbox_app_builder.py` | A small app builder with a dev server and preview. |
|
|
121
|
+
| `agent_sandbox_artifact_builder.py` | Markdown/doc artifacts in `/workspace/artifacts`. |
|
|
122
|
+
| `agent_sandbox_slide_deck_builder.py` | A deck workspace under `/workspace/deck`. |
|
|
123
|
+
|
|
124
|
+
Set `GROQ_API_KEY` and `MIOSA_API_KEY`, then run one of the examples. They keep
|
|
125
|
+
the sandbox alive with `miosa_tool_options={"allow_destroy": False}` so your app
|
|
126
|
+
can show previews, inspect generated files, or publish later.
|
|
127
|
+
|
|
128
|
+
## File operations
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# Write / read
|
|
132
|
+
computer.files.write_file("/workspace/config.json", '{"key": "value"}')
|
|
133
|
+
text = computer.files.read_file("/workspace/config.json")
|
|
134
|
+
|
|
135
|
+
# Upload / download
|
|
136
|
+
computer.files.upload("/local/report.pdf", "/workspace/report.pdf")
|
|
137
|
+
raw_bytes = computer.files.download("/workspace/report.pdf")
|
|
138
|
+
|
|
139
|
+
# List / stat / mkdir / rename / chmod
|
|
140
|
+
entries = computer.files.list("/workspace")
|
|
141
|
+
stat = computer.files.stat("/workspace/config.json")
|
|
142
|
+
computer.files.mkdir("/workspace/output", recursive=True)
|
|
143
|
+
computer.files.rename("/workspace/old.txt", "/workspace/new.txt")
|
|
144
|
+
computer.files.chmod("/workspace/run.sh", 0o755)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Services (background processes)
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
svc = computer.services.create(
|
|
151
|
+
name="api",
|
|
152
|
+
command="uvicorn app:main --port 8080",
|
|
153
|
+
working_dir="/workspace",
|
|
154
|
+
env={"DEBUG": "1"},
|
|
155
|
+
port=8080,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
for log in computer.services.logs(svc.id, follow=True):
|
|
159
|
+
print(log.stream, log.line)
|
|
160
|
+
|
|
161
|
+
computer.services.restart(svc.id)
|
|
162
|
+
computer.services.delete(svc.id)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Desktop control
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
screenshot = computer.screenshot() # PNG bytes
|
|
169
|
+
computer.click(640, 400)
|
|
170
|
+
computer.double_click(640, 400)
|
|
171
|
+
computer.type("hello world")
|
|
172
|
+
computer.key("Return")
|
|
173
|
+
computer.scroll("down", 3)
|
|
174
|
+
computer.drag(100, 100, 400, 400)
|
|
175
|
+
|
|
176
|
+
cursor = computer.cursor()
|
|
177
|
+
windows = computer.windows()
|
|
178
|
+
computer.launch("firefox")
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Async usage
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
import asyncio
|
|
185
|
+
from miosa import AsyncMiosa
|
|
186
|
+
|
|
187
|
+
async def main():
|
|
188
|
+
async with AsyncMiosa(api_key="msk_live_...") as miosa:
|
|
189
|
+
computer = await miosa.computers.create(
|
|
190
|
+
name="async-build", template_type="miosa-sandbox"
|
|
191
|
+
)
|
|
192
|
+
await computer.files.write_file("/workspace/app.py", "print('async!')")
|
|
193
|
+
result = await computer.exec.run("python /workspace/app.py")
|
|
194
|
+
print(result.stdout)
|
|
195
|
+
await computer.destroy()
|
|
196
|
+
|
|
197
|
+
asyncio.run(main())
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## White-label / multi-tenant
|
|
201
|
+
|
|
202
|
+
Tag resources with `external_workspace_id` and `external_user_id` to attribute usage to your downstream customers:
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
computer = miosa.computers.create(
|
|
206
|
+
name="customer-build",
|
|
207
|
+
template_type="miosa-sandbox",
|
|
208
|
+
metadata={
|
|
209
|
+
"external_workspace_id": "dental-office-123",
|
|
210
|
+
"external_user_id": "dr-smith-456",
|
|
211
|
+
},
|
|
212
|
+
)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Error handling
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
from miosa import (
|
|
219
|
+
AuthenticationError, NotFoundError, RateLimitError, MiosaError
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
computer = miosa.computers.get("cmp_doesnt_exist")
|
|
224
|
+
except NotFoundError:
|
|
225
|
+
print("Computer not found")
|
|
226
|
+
except RateLimitError as e:
|
|
227
|
+
print(f"Rate limited; retry after {e.retry_after}s")
|
|
228
|
+
except AuthenticationError:
|
|
229
|
+
print("Check your API key")
|
|
230
|
+
except MiosaError as e:
|
|
231
|
+
print(f"API error {e.status}: {e.message}")
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Exception hierarchy: `MiosaError` > `AuthenticationError` (401), `InsufficientCreditsError` (402), `PermissionError` (403), `NotFoundError` (404), `ValidationError` (422), `RateLimitError` (429), `ServerError` (5xx), `ConnectionError`, `TimeoutError`.
|
|
235
|
+
|
|
236
|
+
## Configuration
|
|
237
|
+
|
|
238
|
+
| Option | Env var | Default |
|
|
239
|
+
|---|---|---|
|
|
240
|
+
| `api_key` | `MIOSA_API_KEY` | — |
|
|
241
|
+
| `base_url` | `MIOSA_BASE_URL` | `https://api.miosa.ai/api/v1` |
|
|
242
|
+
| `timeout` | — | 30s |
|
|
243
|
+
| `max_retries` | — | 3 |
|
|
244
|
+
|
|
245
|
+
## Links
|
|
246
|
+
|
|
247
|
+
- [Full documentation](https://miosa.ai/docs/sdks/python)
|
|
248
|
+
- [Quickstart](https://miosa.ai/docs/quickstart)
|
|
249
|
+
- [GitHub](https://github.com/robertohluna/miosa-python)
|
|
250
|
+
- [Contact](mailto:platform@miosa.ai)
|
|
251
|
+
|
|
252
|
+
## License
|
|
253
|
+
|
|
254
|
+
MIT
|