Add automatic CUA_API_KEY environment variable support for Computer and CloudProvider

Previously, users had to explicitly read the CUA_API_KEY environment variable
and pass it to the Computer/CloudProvider constructor. This change makes the
API key parameter optional and automatically reads from the CUA_API_KEY
environment variable if not provided.

Changes:
- CloudProvider.__init__: Made api_key parameter optional, reads from CUA_API_KEY env var
- Computer.__init__: Added fallback to CUA_API_KEY env var for api_key parameter
- Updated documentation examples to show simplified usage without explicit api_key
- Updated cloud_api_examples.py to demonstrate the new simpler pattern

This provides a cleaner API while maintaining backward compatibility with
explicit api_key parameter passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
f-trycua
2025-11-19 19:35:32 +01:00
parent 1a65bd8ed3
commit 73c0f3e52e
4 changed files with 25 additions and 23 deletions

View File

@@ -17,16 +17,16 @@ All examples require a CUA API key. You can obtain one from the [Dashboard](http
<Tab value="Python">
```python
import os
import asyncio
from computer.providers.cloud.provider import CloudProvider
async def main():
api_key = os.getenv("CUA_API_KEY") or "your-api-key"
# CloudProvider automatically reads CUA_API_KEY from environment
# You can also pass api_key explicitly: CloudProvider(api_key="your-api-key")
# Optional: point to a different API base
# os.environ["CUA_API_BASE"] = "https://api.cua.ai"
provider = CloudProvider(api_key=api_key, verbose=False)
provider = CloudProvider(verbose=False)
async with provider:
vms = await provider.list_vms()
for vm in vms:
@@ -88,15 +88,14 @@ Provide the sandbox name you want to start.
<Tab value="Python">
```python
import os
import asyncio
from computer.providers.cloud.provider import CloudProvider
async def main():
api_key = os.getenv("CUA_API_KEY") or "your-api-key"
# CloudProvider automatically reads CUA_API_KEY from environment
name = "my-vm-name" # e.g., "m-linux-96lcxd2c2k"
provider = CloudProvider(api_key=api_key)
provider = CloudProvider()
async with provider:
resp = await provider.run_vm(name)
print(resp) # { "name": name, "status": "starting" }
@@ -137,15 +136,14 @@ Stops the sandbox asynchronously.
<Tab value="Python">
```python
import os
import asyncio
from computer.providers.cloud.provider import CloudProvider
async def main():
api_key = os.getenv("CUA_API_KEY") or "your-api-key"
# CloudProvider automatically reads CUA_API_KEY from environment
name = "my-vm-name"
provider = CloudProvider(api_key=api_key)
provider = CloudProvider()
async with provider:
resp = await provider.stop_vm(name)
print(resp) # { "name": name, "status": "stopping" }
@@ -186,15 +184,14 @@ Restarts the sandbox asynchronously.
<Tab value="Python">
```python
import os
import asyncio
from computer.providers.cloud.provider import CloudProvider
async def main():
api_key = os.getenv("CUA_API_KEY") or "your-api-key"
# CloudProvider automatically reads CUA_API_KEY from environment
name = "my-vm-name"
provider = CloudProvider(api_key=api_key)
provider = CloudProvider()
async with provider:
resp = await provider.restart_vm(name)
print(resp) # { "name": name, "status": "restarting" }
@@ -235,15 +232,14 @@ Query the computer-server running on the sandbox. Useful for checking details li
<Tab value="Python">
```python
import os
import asyncio
from computer.providers.cloud.provider import CloudProvider
async def main():
api_key = os.getenv("CUA_API_KEY") or "your-api-key"
# CloudProvider automatically reads CUA_API_KEY from environment
name = "my-vm-name"
provider = CloudProvider(api_key=api_key)
provider = CloudProvider()
async with provider:
info = await provider.get_vm(name)
print(info)

View File

@@ -9,14 +9,13 @@ from computer.providers.cloud.provider import CloudProvider
async def main() -> None:
api_key = os.getenv("CUA_API_KEY")
if not api_key:
raise RuntimeError("CUA_API_KEY environment variable is not set")
# CloudProvider will automatically read CUA_API_KEY from environment if not provided
# You can still pass api_key explicitly if needed: CloudProvider(api_key="your_key")
api_base = os.getenv("CUA_API_BASE")
if api_base:
print(f"Using API base: {api_base}")
provider = CloudProvider(api_key=api_key, verbose=True)
provider = CloudProvider(verbose=True)
async with provider:
# List all VMs

View File

@@ -98,13 +98,17 @@ class Computer:
host: Host to use for VM provider connections (e.g. "localhost", "host.docker.internal")
storage: Optional path for persistent VM storage (Lumier provider)
ephemeral: Whether to use ephemeral storage
api_key: Optional API key for cloud providers
api_key: Optional API key for cloud providers (defaults to CUA_API_KEY environment variable)
experiments: Optional list of experimental features to enable (e.g. ["app-use"])
"""
self.logger = Logger("computer", verbosity)
self.logger.info("Initializing Computer...")
# Fall back to environment variable for api_key if not provided
if api_key is None:
api_key = os.environ.get("CUA_API_KEY")
if not image:
if os_type == "macos":
image = "macos-sequoia-cua:latest"

View File

@@ -31,18 +31,21 @@ class CloudProvider(BaseVMProvider):
def __init__(
self,
api_key: str,
api_key: Optional[str] = None,
verbose: bool = False,
api_base: Optional[str] = None,
**kwargs,
):
"""
Args:
api_key: API key for authentication
api_key: API key for authentication (defaults to CUA_API_KEY environment variable)
name: Name of the VM
verbose: Enable verbose logging
"""
assert api_key, "api_key required for CloudProvider"
# Fall back to environment variable if api_key not provided
if api_key is None:
api_key = os.getenv("CUA_API_KEY")
assert api_key, "api_key required for CloudProvider (provide via parameter or CUA_API_KEY environment variable)"
self.api_key = api_key
self.verbose = verbose
self.api_base = (api_base or DEFAULT_API_BASE).rstrip("/")