use-computer 0.0.1__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.
Files changed (40) hide show
  1. use_computer-0.0.1/.env.example +6 -0
  2. use_computer-0.0.1/.gitignore +9 -0
  3. use_computer-0.0.1/.pre-commit-config.yaml +15 -0
  4. use_computer-0.0.1/PKG-INFO +133 -0
  5. use_computer-0.0.1/README.md +111 -0
  6. use_computer-0.0.1/examples/ios_quickstart.py +89 -0
  7. use_computer-0.0.1/examples/quickstart.py +45 -0
  8. use_computer-0.0.1/examples/setup_with_exec.py +54 -0
  9. use_computer-0.0.1/examples/upload_file.py +43 -0
  10. use_computer-0.0.1/mmini/__init__.py +48 -0
  11. use_computer-0.0.1/mmini/ax_transpile.py +504 -0
  12. use_computer-0.0.1/mmini/client.py +362 -0
  13. use_computer-0.0.1/mmini/display.py +39 -0
  14. use_computer-0.0.1/mmini/errors.py +68 -0
  15. use_computer-0.0.1/mmini/ios/__init__.py +14 -0
  16. use_computer-0.0.1/mmini/ios/apps.py +57 -0
  17. use_computer-0.0.1/mmini/ios/environment.py +49 -0
  18. use_computer-0.0.1/mmini/ios/input.py +118 -0
  19. use_computer-0.0.1/mmini/macos/__init__.py +4 -0
  20. use_computer-0.0.1/mmini/macos/keyboard.py +59 -0
  21. use_computer-0.0.1/mmini/macos/mouse.py +105 -0
  22. use_computer-0.0.1/mmini/models.py +79 -0
  23. use_computer-0.0.1/mmini/parsers.py +308 -0
  24. use_computer-0.0.1/mmini/py.typed +1 -0
  25. use_computer-0.0.1/mmini/recording.py +88 -0
  26. use_computer-0.0.1/mmini/retry.py +135 -0
  27. use_computer-0.0.1/mmini/sandbox.py +419 -0
  28. use_computer-0.0.1/mmini/screenshot.py +63 -0
  29. use_computer-0.0.1/mmini/tasks/__init__.py +307 -0
  30. use_computer-0.0.1/mmini/tasks/templates/pre_command.sh +2 -0
  31. use_computer-0.0.1/mmini/tasks/templates/task.toml +18 -0
  32. use_computer-0.0.1/mmini/tasks/templates/test_ios.sh +20 -0
  33. use_computer-0.0.1/mmini/tasks/templates/test_ios_nograder.sh +4 -0
  34. use_computer-0.0.1/mmini/tasks/templates/test_macos.sh +10 -0
  35. use_computer-0.0.1/mmini/tasks/templates/test_macos_check.sh +10 -0
  36. use_computer-0.0.1/mmini/tasks/templates/test_macos_nograder.sh +7 -0
  37. use_computer-0.0.1/pyproject.toml +59 -0
  38. use_computer-0.0.1/use_computer/__init__.py +15 -0
  39. use_computer-0.0.1/use_computer/py.typed +1 -0
  40. use_computer-0.0.1/uv.lock +941 -0
@@ -0,0 +1,6 @@
1
+ # SDK runtime
2
+ USE_COMPUTER_API_KEY=mk_live_...
3
+ USE_COMPUTER_BASE_URL=https://api.use.computer
4
+
5
+ # Local PyPI publish only. Prefer CI Trusted Publishing when possible.
6
+ PYPI_API_TOKEN=pypi-...
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ results/
4
+ dist/
5
+ *.egg-info/
6
+ .env
7
+ .env.*
8
+ !.env.example
9
+ .venv/
@@ -0,0 +1,15 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.15.12
4
+ hooks:
5
+ - id: ruff-format
6
+ - id: ruff-check
7
+ args: [--fix]
8
+
9
+ - repo: local
10
+ hooks:
11
+ - id: ty-check
12
+ name: ty check
13
+ entry: uv run --group dev ty check .
14
+ language: system
15
+ pass_filenames: false
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.4
2
+ Name: use-computer
3
+ Version: 0.0.1
4
+ Summary: Python SDK for the use.computer macOS and iOS Computer Use API
5
+ Project-URL: Homepage, https://use.computer
6
+ Project-URL: Documentation, https://github.com/josancamon19/mmini-sdk#readme
7
+ Project-URL: Repository, https://github.com/josancamon19/mmini-sdk
8
+ Author: use.computer
9
+ Keywords: automation,computer-use,ios,macos,sandbox
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Typing :: Typed
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: httpx>=0.27
21
+ Description-Content-Type: text/markdown
22
+
23
+ # use-computer Python SDK
24
+
25
+ Python SDK for the use.computer macOS and iOS Computer Use API.
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ pip install use-computer
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```python
36
+ from use_computer import Computer
37
+
38
+ client = Computer(api_key="mk_live_...")
39
+ sandbox = client.create()
40
+
41
+ # Screenshot
42
+ img = sandbox.screenshot.take_full_screen()
43
+
44
+ # Mouse
45
+ sandbox.mouse.click(500, 400)
46
+ sandbox.mouse.move(100, 200)
47
+ sandbox.mouse.scroll(500, 400, "down", 3)
48
+ sandbox.mouse.drag(100, 100, 300, 300)
49
+
50
+ # Keyboard
51
+ sandbox.keyboard.type("Hello")
52
+ sandbox.keyboard.press("enter")
53
+ sandbox.keyboard.hotkey("command+space")
54
+
55
+ # Display
56
+ info = sandbox.display.get_info()
57
+ windows = sandbox.display.get_windows()
58
+
59
+ # Recording
60
+ recording = sandbox.recording.start(name="my-recording")
61
+ # ... do stuff ...
62
+ sandbox.recording.stop(recording.id)
63
+ sandbox.recording.download(recording.id, "output.mp4")
64
+
65
+ # Cleanup
66
+ sandbox.close()
67
+ client.close()
68
+ ```
69
+
70
+ ## Environment
71
+
72
+ `Computer()` reads these environment variables when explicit values are not passed:
73
+
74
+ ```bash
75
+ USE_COMPUTER_API_KEY=mk_live_...
76
+ USE_COMPUTER_BASE_URL=https://api.use.computer
77
+ ```
78
+
79
+ `USE_COMPUTER_BASE_URL` is optional. The default is `https://api.use.computer`.
80
+
81
+ ## Async
82
+
83
+ ```python
84
+ from use_computer import AsyncComputer
85
+
86
+ client = AsyncComputer(api_key="mk_live_...")
87
+ sandbox = await client.create()
88
+ img = await sandbox.screenshot.take_full_screen()
89
+ await sandbox.close()
90
+ await client.close()
91
+ ```
92
+
93
+ ## Local Gateway
94
+
95
+ ```python
96
+ from use_computer import Computer
97
+
98
+ client = Computer(
99
+ api_key="sk-local",
100
+ base_url="http://localhost:8080",
101
+ )
102
+ ```
103
+
104
+ ## Backward Compatibility
105
+
106
+ The original import path still works:
107
+
108
+ ```python
109
+ from mmini import Mmini
110
+ ```
111
+
112
+ New code should prefer:
113
+
114
+ ```python
115
+ from use_computer import Computer
116
+ ```
117
+
118
+ ## Publishing
119
+
120
+ CI publishes `use-computer` from the `main` branch. The first release is
121
+ `0.0.1`; after that the workflow reads the latest `vX.Y.Z` tag and bumps the
122
+ patch version.
123
+
124
+ For CI, prefer PyPI Trusted Publishing. If using an API token instead, set a
125
+ repo secret named `PYPI_API_TOKEN`; do not commit tokens to `.env`.
126
+
127
+ ## Development
128
+
129
+ ```bash
130
+ uv run --group dev pre-commit install
131
+ ```
132
+
133
+ Pre-commit runs `ruff format`, `ruff check --fix`, and `ty check`.
@@ -0,0 +1,111 @@
1
+ # use-computer Python SDK
2
+
3
+ Python SDK for the use.computer macOS and iOS Computer Use API.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install use-computer
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ from use_computer import Computer
15
+
16
+ client = Computer(api_key="mk_live_...")
17
+ sandbox = client.create()
18
+
19
+ # Screenshot
20
+ img = sandbox.screenshot.take_full_screen()
21
+
22
+ # Mouse
23
+ sandbox.mouse.click(500, 400)
24
+ sandbox.mouse.move(100, 200)
25
+ sandbox.mouse.scroll(500, 400, "down", 3)
26
+ sandbox.mouse.drag(100, 100, 300, 300)
27
+
28
+ # Keyboard
29
+ sandbox.keyboard.type("Hello")
30
+ sandbox.keyboard.press("enter")
31
+ sandbox.keyboard.hotkey("command+space")
32
+
33
+ # Display
34
+ info = sandbox.display.get_info()
35
+ windows = sandbox.display.get_windows()
36
+
37
+ # Recording
38
+ recording = sandbox.recording.start(name="my-recording")
39
+ # ... do stuff ...
40
+ sandbox.recording.stop(recording.id)
41
+ sandbox.recording.download(recording.id, "output.mp4")
42
+
43
+ # Cleanup
44
+ sandbox.close()
45
+ client.close()
46
+ ```
47
+
48
+ ## Environment
49
+
50
+ `Computer()` reads these environment variables when explicit values are not passed:
51
+
52
+ ```bash
53
+ USE_COMPUTER_API_KEY=mk_live_...
54
+ USE_COMPUTER_BASE_URL=https://api.use.computer
55
+ ```
56
+
57
+ `USE_COMPUTER_BASE_URL` is optional. The default is `https://api.use.computer`.
58
+
59
+ ## Async
60
+
61
+ ```python
62
+ from use_computer import AsyncComputer
63
+
64
+ client = AsyncComputer(api_key="mk_live_...")
65
+ sandbox = await client.create()
66
+ img = await sandbox.screenshot.take_full_screen()
67
+ await sandbox.close()
68
+ await client.close()
69
+ ```
70
+
71
+ ## Local Gateway
72
+
73
+ ```python
74
+ from use_computer import Computer
75
+
76
+ client = Computer(
77
+ api_key="sk-local",
78
+ base_url="http://localhost:8080",
79
+ )
80
+ ```
81
+
82
+ ## Backward Compatibility
83
+
84
+ The original import path still works:
85
+
86
+ ```python
87
+ from mmini import Mmini
88
+ ```
89
+
90
+ New code should prefer:
91
+
92
+ ```python
93
+ from use_computer import Computer
94
+ ```
95
+
96
+ ## Publishing
97
+
98
+ CI publishes `use-computer` from the `main` branch. The first release is
99
+ `0.0.1`; after that the workflow reads the latest `vX.Y.Z` tag and bumps the
100
+ patch version.
101
+
102
+ For CI, prefer PyPI Trusted Publishing. If using an API token instead, set a
103
+ repo secret named `PYPI_API_TOKEN`; do not commit tokens to `.env`.
104
+
105
+ ## Development
106
+
107
+ ```bash
108
+ uv run --group dev pre-commit install
109
+ ```
110
+
111
+ Pre-commit runs `ruff format`, `ruff check --fix`, and `ty check`.
@@ -0,0 +1,89 @@
1
+ """
2
+ iOS simulator sandbox — end to end example.
3
+
4
+ Creates an iPhone simulator, opens Safari, takes a screenshot,
5
+ taps around, types a URL, and cleans up.
6
+
7
+ Usage:
8
+ cd sdk && uv run python examples/ios_quickstart.py
9
+ """
10
+
11
+ import time
12
+
13
+ from use_computer import Computer
14
+
15
+ client = Computer(base_url="http://localhost:8080")
16
+
17
+ # Create an iOS sandbox (iPhone 17 Pro by default)
18
+ sandbox = client.create(type="ios")
19
+ print(f"Created: {sandbox}")
20
+
21
+ # Check display info
22
+ info = sandbox.display.get_info()
23
+ print(f"Display: {info.width}x{info.height} @{info.scale}x")
24
+
25
+ # Take initial screenshot (home screen)
26
+ time.sleep(3) # wait for simulator to settle
27
+ img = sandbox.screenshot.take_full_screen()
28
+ with open("ios_home.png", "wb") as f:
29
+ f.write(img)
30
+ print(f"Home screen saved ({len(img)} bytes)")
31
+
32
+ # Open Safari via URL scheme
33
+ sandbox.apps.open_url("https://example.com")
34
+ time.sleep(3)
35
+
36
+ # Screenshot Safari
37
+ img = sandbox.screenshot.take_full_screen()
38
+ with open("ios_safari.png", "wb") as f:
39
+ f.write(img)
40
+ print("Safari screenshot saved")
41
+
42
+ # Tap the address bar (top center of screen)
43
+ sandbox.input.tap(info.width / 2, 70)
44
+ time.sleep(1)
45
+
46
+ # Type a URL
47
+ sandbox.input.type_text("https://apple.com")
48
+ time.sleep(0.5)
49
+
50
+ # Press Go (tap keyboard return area)
51
+ sandbox.input.press_button("HOME") # dismiss keyboard first
52
+ time.sleep(1)
53
+
54
+ # Screenshot final state
55
+ img = sandbox.screenshot.take_full_screen()
56
+ with open("ios_final.png", "wb") as f:
57
+ f.write(img)
58
+ print("Final screenshot saved")
59
+
60
+ # Set dark mode
61
+ sandbox.environment.set_appearance("dark")
62
+ time.sleep(1)
63
+ img = sandbox.screenshot.take_full_screen()
64
+ with open("ios_dark.png", "wb") as f:
65
+ f.write(img)
66
+ print("Dark mode screenshot saved")
67
+
68
+ # Upload a file to the simulator
69
+ sandbox.upload_bytes(b"Hello from use.computer iOS!", "Documents/test.txt")
70
+ print("File uploaded")
71
+
72
+ # Download it back
73
+ sandbox.download_file("Documents/test.txt", "ios_downloaded.txt")
74
+ with open("ios_downloaded.txt") as f:
75
+ print(f"Downloaded: {f.read()}")
76
+
77
+ # Start recording
78
+ rec = sandbox.recording.start(name="demo")
79
+ print(f"Recording started: {rec.id}")
80
+ time.sleep(3)
81
+
82
+ # Stop recording
83
+ rec = sandbox.recording.stop(rec.id)
84
+ print(f"Recording stopped: {rec.status}")
85
+
86
+ # Clean up
87
+ sandbox.close()
88
+ print("Sandbox destroyed.")
89
+ client.close()
@@ -0,0 +1,45 @@
1
+ """
2
+ Quick test of the use-computer SDK against a local gateway.
3
+
4
+ Usage:
5
+ cd sdk && uv run python examples/quickstart.py
6
+ """
7
+
8
+ import time
9
+
10
+ from use_computer import Computer
11
+
12
+ client = Computer(base_url="http://localhost:8080")
13
+
14
+ sandbox = client.create()
15
+ print(f"Created: {sandbox}")
16
+ print(f"VNC: {sandbox.vnc_url}")
17
+
18
+ # Open TextEdit via exec
19
+ sandbox.exec_ssh("open -a TextEdit")
20
+ time.sleep(2)
21
+
22
+ # Click in the document area to focus it
23
+ sandbox.mouse.click(512, 400)
24
+ time.sleep(0.5)
25
+
26
+ # Take initial screenshot
27
+ img = sandbox.screenshot.take_full_screen()
28
+ with open("screen.png", "wb") as f:
29
+ f.write(img)
30
+ print(f"Screenshot saved to screen.png ({len(img)} bytes)")
31
+
32
+ # Type something
33
+ sandbox.keyboard.type("Hello from use.computer!")
34
+ time.sleep(0.5)
35
+
36
+ # Screenshot after typing
37
+ img = sandbox.screenshot.take_full_screen()
38
+ with open("screen_after.png", "wb") as f:
39
+ f.write(img)
40
+ print("After typing saved to screen_after.png")
41
+
42
+ # Clean up
43
+ sandbox.close()
44
+ print("Sandbox destroyed.")
45
+ client.close()
@@ -0,0 +1,54 @@
1
+ """
2
+ Example: seed a sandbox by running shell commands via exec.
3
+
4
+ Opens Notes, creates a note, and sets system preferences — all via exec.
5
+ This replaces the old seed mechanism with direct shell commands.
6
+
7
+ Usage:
8
+ cd sdk && uv run python examples/setup_with_exec.py
9
+ """
10
+
11
+ import asyncio
12
+
13
+ from use_computer import AsyncComputer
14
+
15
+
16
+ async def main() -> None:
17
+ client = AsyncComputer(base_url="http://localhost:8080")
18
+ sandbox = await client.create()
19
+ print(f"Created: {sandbox.sandbox_id}")
20
+
21
+ # Open an app
22
+ await sandbox.exec_ssh("open -a Notes")
23
+ await asyncio.sleep(2)
24
+
25
+ # Create a note via osascript
26
+ await sandbox.exec_ssh(
27
+ 'osascript -e \'tell application "Notes" to make new note'
28
+ ' with properties {name:"Test Note", body:"Created by mmini SDK"}\''
29
+ )
30
+
31
+ # Set system preferences
32
+ await sandbox.exec_ssh("defaults write com.apple.dock autohide -bool true && killall Dock")
33
+
34
+ # Run any shell command
35
+ result = await sandbox.exec_ssh("sw_vers -productVersion")
36
+ print(f"macOS version: {result.stdout.strip()}")
37
+
38
+ # Verify the note was created
39
+ notes = await sandbox.exec_ssh(
40
+ "osascript -e 'tell application \"Notes\" to get the name of every note'"
41
+ )
42
+ print(f"Notes: {notes.stdout.strip()}")
43
+
44
+ # Take a screenshot to see the result
45
+ img = await sandbox.screenshot.take_full_screen()
46
+ with open("setup_result.png", "wb") as f:
47
+ f.write(img)
48
+ print("Screenshot saved to setup_result.png")
49
+
50
+ await sandbox.close()
51
+ await client.close()
52
+
53
+
54
+ asyncio.run(main())
@@ -0,0 +1,43 @@
1
+ """
2
+ Example: upload a file to a sandbox and verify it.
3
+
4
+ Uses the file upload endpoint to put a file on the VM's filesystem,
5
+ then verifies it exists via exec.
6
+
7
+ Usage:
8
+ cd sdk && uv run python examples/upload_file.py
9
+ """
10
+
11
+ import asyncio
12
+
13
+ from use_computer import AsyncComputer
14
+
15
+
16
+ async def main() -> None:
17
+ client = AsyncComputer(base_url="http://localhost:8080")
18
+ sandbox = await client.create()
19
+ print(f"Created: {sandbox.sandbox_id}")
20
+
21
+ # Create some content
22
+ content = b"Name,Score\nAlice,95\nBob,87\nCharlie,92\n"
23
+
24
+ # Upload to the VM
25
+ await sandbox.upload_bytes(content, "/Users/lume/Desktop/scores.csv")
26
+ print("Uploaded scores.csv to Desktop")
27
+
28
+ # Verify it's there
29
+ result = await sandbox.exec_ssh("cat /Users/lume/Desktop/scores.csv")
30
+ print(f"File contents:\n{result.stdout}")
31
+
32
+ # Upload a script and run it
33
+ script = b"#!/bin/bash\necho 'Hello from uploaded script!'\nls ~/Desktop/\n"
34
+ await sandbox.upload_bytes(script, "/Users/lume/Desktop/check.sh")
35
+ await sandbox.exec_ssh("chmod +x /Users/lume/Desktop/check.sh")
36
+ result = await sandbox.exec_ssh("/Users/lume/Desktop/check.sh")
37
+ print(f"Script output:\n{result.stdout}")
38
+
39
+ await sandbox.close()
40
+ await client.close()
41
+
42
+
43
+ asyncio.run(main())
@@ -0,0 +1,48 @@
1
+ from mmini.client import AsyncMmini, Mmini, RunStatus
2
+ from mmini.errors import MminiError, PlatformNotSupportedError
3
+ from mmini.models import (
4
+ ActionResult,
5
+ ActResult,
6
+ CursorPosition,
7
+ DisplayInfo,
8
+ ExecResult,
9
+ RecordingInfo,
10
+ )
11
+ from mmini.parsers import Action, parse_pyautogui, parse_xdotool
12
+ from mmini.sandbox import (
13
+ AsyncIOSSandbox,
14
+ AsyncMacOSSandbox,
15
+ AsyncSandbox,
16
+ IOSSandbox,
17
+ MacOSSandbox,
18
+ Sandbox,
19
+ SandboxType,
20
+ )
21
+ from mmini.tasks import Task, TasksClient, TaskSummary
22
+
23
+ __all__ = [
24
+ "Action",
25
+ "ActionResult",
26
+ "ActResult",
27
+ "AsyncIOSSandbox",
28
+ "AsyncMacOSSandbox",
29
+ "AsyncMmini",
30
+ "AsyncSandbox",
31
+ "CursorPosition",
32
+ "DisplayInfo",
33
+ "ExecResult",
34
+ "IOSSandbox",
35
+ "MacOSSandbox",
36
+ "Mmini",
37
+ "MminiError",
38
+ "PlatformNotSupportedError",
39
+ "RecordingInfo",
40
+ "RunStatus",
41
+ "Sandbox",
42
+ "SandboxType",
43
+ "Task",
44
+ "TaskSummary",
45
+ "TasksClient",
46
+ "parse_pyautogui",
47
+ "parse_xdotool",
48
+ ]