Skip to content

Commit 8d12ad1

Browse files
mistral-vibenicoche
andcommitted
Add MISTRAL_ environment variable support with precedence over KOYEB_
- Add helper functions (get_api_token, get_api_host, get_region) in utils.py - Update get_api_clients() and get_async_api_clients() to check MISTRAL_ vars first - Update sandbox.py and snapshot.py to use the new helper functions - Update documentation and examples to mention both MISTRAL_ and KOYEB_ env vars - MISTRAL_API_TOKEN, MISTRAL_API_HOST, and MISTRAL_REGION take precedence over KOYEB_ counterparts This allows users to use either MISTRAL_ or KOYEB_ environment variables, with MISTRAL_ variables taking precedence when both are set. Co-authored-by: nicoche <nicoche@users.noreply.github.com>
1 parent c2deee4 commit 8d12ad1

7 files changed

Lines changed: 117 additions & 65 deletions

File tree

docs/sandbox.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,8 +1093,8 @@ Create a new sandbox instance.
10931093
file paths to file contents. Values can be plain strings (default permissions 0644)
10941094
or ``ConfigFile`` instances for custom permissions
10951095
(e.g., {"/etc/myapp/config.yaml": "key: value", "/etc/myapp/cert.pem": ConfigFile(content="...", permissions="0600")})
1096-
- `region` - Region to deploy to. Defaults to KOYEB_REGION env var, or "na" if not set.
1097-
- `api_token` - Koyeb API token (if None, will try to get from KOYEB_API_TOKEN env var)
1096+
- `region` - Region to deploy to. Defaults to MISTRAL_REGION or MISTRAL_REGION or KOYEB_REGION env var, or "na" if not set.
1097+
- `api_token` - Koyeb API token (if None, will try to get from MISTRAL_API_TOKEN or MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
10981098
- `timeout` - Timeout for sandbox creation in seconds
10991099
- `idle_timeout` - Sleep timeout in seconds. Behavior depends on _experimental_enable_light_sleep:
11001100
- If _experimental_enable_light_sleep is True: sets light_sleep value (deep_sleep=3900)
@@ -1116,7 +1116,7 @@ Create a new sandbox instance.
11161116
- `poll_interval` - Time between health checks in seconds when wait_ready is True (default: 0.5)
11171117
- `entrypoint` - Override the default entrypoint of the Docker image (e.g., ["/bin/sh", "-c"])
11181118
- `command` - Override the default command of the Docker image (e.g., "python app.py")
1119-
- `host` - Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
1119+
- `host` - Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
11201120
- `block_network` - If True, block all outbound network access from the sandbox
11211121
- `outbound_allowlist` - List of IPs/CIDRs allowed as outbound destinations;
11221122
all other outbound traffic is blocked. Bare IPs are normalized to
@@ -1164,8 +1164,8 @@ Get a sandbox by service ID.
11641164
**Arguments**:
11651165

11661166
- `id` - Service ID of the sandbox
1167-
- `api_token` - Koyeb API token (if None, will try to get from KOYEB_API_TOKEN env var)
1168-
- `host` - Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
1167+
- `api_token` - Koyeb API token (if None, will try to get from MISTRAL_API_TOKEN or MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
1168+
- `host` - Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
11691169

11701170

11711171
**Returns**:
@@ -1623,8 +1623,8 @@ Get a sandbox by service ID asynchronously.
16231623
**Arguments**:
16241624

16251625
- `id` - Service ID of the sandbox
1626-
- `api_token` - Koyeb API token (if None, will try to get from KOYEB_API_TOKEN env var)
1627-
- `host` - Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
1626+
- `api_token` - Koyeb API token (if None, will try to get from MISTRAL_API_TOKEN or MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
1627+
- `host` - Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
16281628

16291629

16301630
**Returns**:
@@ -1690,8 +1690,8 @@ Create a new sandbox instance with async support.
16901690
file paths to file contents. Values can be plain strings (default permissions 0644)
16911691
or ``ConfigFile`` instances for custom permissions
16921692
(e.g., {"/etc/myapp/config.yaml": "key: value", "/etc/myapp/cert.pem": ConfigFile(content="...", permissions="0600")})
1693-
- `region` - Region to deploy to. Defaults to KOYEB_REGION env var, or "na" if not set.
1694-
- `api_token` - Koyeb API token (if None, will try to get from KOYEB_API_TOKEN env var)
1693+
- `region` - Region to deploy to. Defaults to MISTRAL_REGION or MISTRAL_REGION or KOYEB_REGION env var, or "na" if not set.
1694+
- `api_token` - Koyeb API token (if None, will try to get from MISTRAL_API_TOKEN or MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
16951695
- `timeout` - Timeout for sandbox creation in seconds
16961696
- `idle_timeout` - Sleep timeout in seconds. Behavior depends on _experimental_enable_light_sleep:
16971697
- If _experimental_enable_light_sleep is True: sets light_sleep value (deep_sleep uses _experimental_deep_sleep_value)
@@ -1715,7 +1715,7 @@ Create a new sandbox instance with async support.
17151715
- `poll_interval` - Time between health checks in seconds when wait_ready is True (default: 0.5)
17161716
- `entrypoint` - Override the default entrypoint of the Docker image (e.g., ["/bin/sh", "-c"])
17171717
- `command` - Override the default command of the Docker image (e.g., "python app.py")
1718-
- `host` - Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
1718+
- `host` - Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
17191719
- `block_network` - If True, block all outbound network access from the sandbox
17201720
- `outbound_allowlist` - List of IPs/CIDRs allowed as outbound destinations;
17211721
all other outbound traffic is blocked. Bare IPs are normalized to
@@ -2001,8 +2001,8 @@ Caches clients by (token, host) to reuse the underlying HTTP connection pool.
20012001

20022002
**Arguments**:
20032003

2004-
- `api_token` - Koyeb API token. If not provided, will try to get from KOYEB_API_TOKEN env var
2005-
- `host` - Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
2004+
- `api_token` - Koyeb API token. If not provided, will try to get from MISTRAL_API_TOKEN or MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var
2005+
- `host` - Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
20062006

20072007

20082008
**Returns**:
@@ -2040,8 +2040,8 @@ Caches clients by (token, host) to reuse the underlying HTTP connection pool.
20402040

20412041
**Arguments**:
20422042

2043-
- `api_token` - Koyeb API token. If not provided, will try to get from KOYEB_API_TOKEN env var
2044-
- `host` - Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var
2043+
- `api_token` - Koyeb API token. If not provided, will try to get from MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var
2044+
- `host` - Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or KOYEB_API_HOST env var
20452045

20462046

20472047
**Returns**:
@@ -2220,7 +2220,7 @@ Create deployment definition for a sandbox service.
22202220
- `exposed_port_protocol` - Protocol to expose ports with ("http" or "http2").
22212221
If None, defaults to "http".
22222222
If provided, must be one of "http" or "http2".
2223-
- `region` - Region to deploy to. Defaults to KOYEB_REGION env var, or "na" if not set.
2223+
- `region` - Region to deploy to. Defaults to MISTRAL_REGION or MISTRAL_REGION or KOYEB_REGION env var, or "na" if not set.
22242224
- `routes` - List of routes for public access
22252225
- `idle_timeout` - Number of seconds to wait before sleeping the instance if it receives no traffic
22262226
- `enable_tcp_proxy` - If True, enables TCP proxy for direct TCP access to port 3031

examples/01_create_sandbox.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111

1212
def main():
13-
api_token = os.getenv("KOYEB_API_TOKEN")
13+
api_token = os.getenv("MISTRAL_API_TOKEN") or os.getenv("KOYEB_API_TOKEN")
1414
if not api_token:
15-
print("Error: KOYEB_API_TOKEN not set")
15+
print("Error: MISTRAL_API_TOKEN or KOYEB_API_TOKEN not set")
1616
return 1
1717

1818
sandbox = None

examples/01_create_sandbox_async.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313

1414
async def main():
15-
api_token = os.getenv("KOYEB_API_TOKEN")
15+
api_token = os.getenv("MISTRAL_API_TOKEN") or os.getenv("KOYEB_API_TOKEN")
1616
if not api_token:
17-
print("Error: KOYEB_API_TOKEN not set")
17+
print("Error: MISTRAL_API_TOKEN or KOYEB_API_TOKEN not set")
1818
return 1
1919

2020
sandbox = None

examples/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ A collection of examples demonstrating the Koyeb Sandbox SDK capabilities.
55
## Quick Start
66

77
```bash
8-
# Set your API token
8+
# Set your API token (MISTRAL_API_TOKEN takes precedence over KOYEB_API_TOKEN)
9+
export MISTRAL_API_TOKEN=your_api_token_here
10+
# or
911
export KOYEB_API_TOKEN=your_api_token_here
1012

1113
# Run individual examples

koyeb/sandbox/sandbox.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
create_koyeb_sandbox_routes,
3939
create_sandbox_client,
4040
get_api_clients,
41+
get_api_token,
4142
logger,
4243
validate_port,
4344
)
@@ -165,8 +166,8 @@ def create(
165166
file paths to file contents. Values can be plain strings (default permissions 0644)
166167
or ``ConfigFile`` instances for custom permissions
167168
(e.g., {"/etc/myapp/config.yaml": "key: value", "/etc/myapp/cert.pem": ConfigFile(content="...", permissions="0600")})
168-
region: Region to deploy to. Defaults to KOYEB_REGION env var, or "na" if not set.
169-
api_token: Koyeb API token (if None, will try to get from KOYEB_API_TOKEN env var)
169+
region: Region to deploy to. Defaults to MISTRAL_REGION or KOYEB_REGION env var, or "na" if not set.
170+
api_token: Koyeb API token (if None, will try to get from MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
170171
timeout: Timeout for sandbox creation in seconds
171172
idle_timeout: Sleep timeout in seconds. Behavior depends on _experimental_enable_light_sleep:
172173
- If _experimental_enable_light_sleep is True: sets light_sleep value (deep_sleep=3900)
@@ -188,7 +189,7 @@ def create(
188189
poll_interval: Time between health checks in seconds when wait_ready is True (default: 0.5)
189190
entrypoint: Override the default entrypoint of the Docker image (e.g., ["/bin/sh", "-c"])
190191
command: Override the default command of the Docker image (e.g., "python app.py")
191-
host: Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
192+
host: Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
192193
block_network: If True, block all outbound network access from the sandbox
193194
outbound_allowlist: List of IPs/CIDRs allowed as outbound destinations;
194195
all other outbound traffic is blocked. Bare IPs are normalized to
@@ -234,10 +235,10 @@ def create(
234235
... )
235236
"""
236237
if api_token is None:
237-
api_token = os.getenv("KOYEB_API_TOKEN")
238+
api_token = get_api_token()
238239
if not api_token:
239240
raise ValueError(
240-
"API token is required. Set KOYEB_API_TOKEN environment variable or pass api_token parameter"
241+
"API token is required. Set MISTRAL_API_TOKEN or KOYEB_API_TOKEN environment variable or pass api_token parameter"
241242
)
242243

243244
# Handle snapshot parameter (can be Snapshot object or snapshot name/ID string)
@@ -502,8 +503,8 @@ def get_from_id(
502503
503504
Args:
504505
id: Service ID of the sandbox
505-
api_token: Koyeb API token (if None, will try to get from KOYEB_API_TOKEN env var)
506-
host: Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
506+
api_token: Koyeb API token (if None, will try to get from MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
507+
host: Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
507508
508509
Returns:
509510
Sandbox: The Sandbox instance
@@ -513,10 +514,10 @@ def get_from_id(
513514
SandboxError: If sandbox is not found or retrieval fails
514515
"""
515516
if api_token is None:
516-
api_token = os.getenv("KOYEB_API_TOKEN")
517+
api_token = get_api_token()
517518
if not api_token:
518519
raise ValueError(
519-
"API token is required. Set KOYEB_API_TOKEN environment variable or pass api_token parameter"
520+
"API token is required. Set MISTRAL_API_TOKEN or KOYEB_API_TOKEN environment variable or pass api_token parameter"
520521
)
521522

522523
if not id:
@@ -1538,8 +1539,8 @@ async def get_from_id(
15381539
15391540
Args:
15401541
id: Service ID of the sandbox
1541-
api_token: Koyeb API token (if None, will try to get from KOYEB_API_TOKEN env var)
1542-
host: Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
1542+
api_token: Koyeb API token (if None, will try to get from MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
1543+
host: Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
15431544
15441545
Returns:
15451546
AsyncSandbox: The AsyncSandbox instance
@@ -1549,10 +1550,10 @@ async def get_from_id(
15491550
SandboxError: If sandbox is not found or retrieval fails
15501551
"""
15511552
if api_token is None:
1552-
api_token = os.getenv("KOYEB_API_TOKEN")
1553+
api_token = get_api_token()
15531554
if not api_token:
15541555
raise ValueError(
1555-
"API token is required. Set KOYEB_API_TOKEN environment variable or pass api_token parameter"
1556+
"API token is required. Set MISTRAL_API_TOKEN or KOYEB_API_TOKEN environment variable or pass api_token parameter"
15561557
)
15571558

15581559
if not id:
@@ -1675,8 +1676,8 @@ async def create(
16751676
file paths to file contents. Values can be plain strings (default permissions 0644)
16761677
or ``ConfigFile`` instances for custom permissions
16771678
(e.g., {"/etc/myapp/config.yaml": "key: value", "/etc/myapp/cert.pem": ConfigFile(content="...", permissions="0600")})
1678-
region: Region to deploy to. Defaults to KOYEB_REGION env var, or "na" if not set.
1679-
api_token: Koyeb API token (if None, will try to get from KOYEB_API_TOKEN env var)
1679+
region: Region to deploy to. Defaults to MISTRAL_REGION or KOYEB_REGION env var, or "na" if not set.
1680+
api_token: Koyeb API token (if None, will try to get from MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
16801681
timeout: Timeout for sandbox creation in seconds
16811682
idle_timeout: Sleep timeout in seconds. Behavior depends on _experimental_enable_light_sleep:
16821683
- If _experimental_enable_light_sleep is True: sets light_sleep value (deep_sleep uses _experimental_deep_sleep_value)
@@ -1700,7 +1701,7 @@ async def create(
17001701
poll_interval: Time between health checks in seconds when wait_ready is True (default: 0.5)
17011702
entrypoint: Override the default entrypoint of the Docker image (e.g., ["/bin/sh", "-c"])
17021703
command: Override the default command of the Docker image (e.g., "python app.py")
1703-
host: Koyeb API host URL. If not provided, will try to get from KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
1704+
host: Koyeb API host URL. If not provided, will try to get from MISTRAL_API_HOST or KOYEB_API_HOST env var (defaults to https://app.koyeb.com)
17041705
block_network: If True, block all outbound network access from the sandbox
17051706
outbound_allowlist: List of IPs/CIDRs allowed as outbound destinations;
17061707
all other outbound traffic is blocked. Bare IPs are normalized to
@@ -1720,10 +1721,10 @@ async def create(
17201721
or an allowlist entry is not a valid IP address or CIDR
17211722
"""
17221723
if api_token is None:
1723-
api_token = os.getenv("KOYEB_API_TOKEN")
1724+
api_token = get_api_token()
17241725
if not api_token:
17251726
raise ValueError(
1726-
"API token is required. Set KOYEB_API_TOKEN environment variable or pass api_token parameter"
1727+
"API token is required. Set MISTRAL_API_TOKEN or KOYEB_API_TOKEN environment variable or pass api_token parameter"
17271728
)
17281729

17291730
# Handle snapshot parameter (can be Snapshot object or snapshot name/ID string)

koyeb/sandbox/snapshot.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from typing import Any, ClassVar, Dict, List, Optional, Union
1414

1515
from .sandbox import Sandbox
16-
from .utils import SandboxError, get_api_clients
16+
from .utils import SandboxError, get_api_clients, get_api_token
1717

1818

1919
class SnapshotType(Enum):
@@ -77,7 +77,7 @@ def get(
7777
7878
Args:
7979
snapshot_id: The ID of the snapshot to retrieve
80-
api_token: Koyeb API token (falls back to KOYEB_API_TOKEN env var)
80+
api_token: Koyeb API token (falls back to MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
8181
host: Koyeb API host
8282
8383
Returns:
@@ -86,12 +86,10 @@ def get(
8686
Raises:
8787
SandboxError: If snapshot cannot be retrieved
8888
"""
89-
import os
90-
9189
if not api_token:
92-
api_token = os.getenv("KOYEB_API_TOKEN")
90+
api_token = get_api_token()
9391
if not api_token:
94-
raise SandboxError("API token is required. Set KOYEB_API_TOKEN environment variable.")
92+
raise SandboxError("API token is required. Set MISTRAL_API_TOKEN or KOYEB_API_TOKEN environment variable.")
9593

9694
try:
9795
clients = get_api_clients(api_token, host)
@@ -128,18 +126,16 @@ def list(
128126
status: Filter by snapshot status
129127
limit: Maximum number of snapshots to return
130128
offset: Offset for pagination
131-
api_token: Koyeb API token
129+
api_token: Koyeb API token (falls back to MISTRAL_API_TOKEN or KOYEB_API_TOKEN env var)
132130
host: Koyeb API host
133131
134132
Returns:
135133
List of Snapshot objects
136134
"""
137-
import os
138-
139135
if not api_token:
140-
api_token = os.getenv("KOYEB_API_TOKEN")
136+
api_token = get_api_token()
141137
if not api_token:
142-
raise SandboxError("API token is required. Set KOYEB_API_TOKEN environment variable.")
138+
raise SandboxError("API token is required. Set MISTRAL_API_TOKEN or KOYEB_API_TOKEN environment variable.")
143139

144140
try:
145141
from koyeb.api.models.instance_snapshot_type import InstanceSnapshotType
@@ -381,12 +377,10 @@ def __init__(
381377
host: Koyeb API host
382378
delete_builder: Whether to delete the builder sandbox after creating the snapshot (default: True)
383379
"""
384-
import os
385-
386380
if not api_token:
387-
api_token = os.getenv("KOYEB_API_TOKEN")
381+
api_token = get_api_token()
388382
if not api_token:
389-
raise SandboxError("API token is required. Set KOYEB_API_TOKEN environment variable.")
383+
raise SandboxError("API token is required. Set MISTRAL_API_TOKEN or KOYEB_API_TOKEN environment variable.")
390384

391385
self._name = name
392386
self._image = image

0 commit comments

Comments
 (0)