boxd 0.2.2.dev44__tar.gz → 0.2.5.dev47__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.
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/PKG-INFO +48 -4
- boxd-0.2.2.dev44/src/boxd.egg-info/PKG-INFO → boxd-0.2.5.dev47/README.md +44 -32
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/pyproject.toml +15 -4
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/__init__.py +8 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_client.py +3 -0
- boxd-0.2.5.dev47/src/boxd/_generated/api_pb2.py +406 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_generated/api_pb2_grpc.py +496 -43
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_mappers.py +57 -2
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_transport.py +55 -19
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/models.py +53 -1
- boxd-0.2.5.dev47/src/boxd/resources/domains.py +72 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/machines.py +114 -0
- boxd-0.2.5.dev47/src/boxd/resources/orgs.py +85 -0
- boxd-0.2.2.dev44/README.md → boxd-0.2.5.dev47/src/boxd.egg-info/PKG-INFO +76 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd.egg-info/SOURCES.txt +1 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd.egg-info/requires.txt +3 -3
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_credentials.py +23 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_mappers.py +38 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_namespaces.py +79 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_transport.py +72 -0
- boxd-0.2.2.dev44/src/boxd/_generated/api_pb2.py +0 -362
- boxd-0.2.2.dev44/src/boxd/resources/orgs.py +0 -27
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/LICENSE +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/setup.cfg +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_credentials.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_generated/__init__.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_requests.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_streaming.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_urls.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_version_check.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/errors.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/__init__.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/account.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/credentials.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/disks.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/snapshots.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/vars.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd.egg-info/dependency_links.txt +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd.egg-info/top_level.txt +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_requests.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_streaming.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_urls.py +0 -0
- {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_version_check.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boxd
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5.dev47
|
|
4
4
|
Summary: Python SDK for the boxd cloud VM platform
|
|
5
5
|
Author: Azin
|
|
6
6
|
License-Expression: MIT
|
|
@@ -18,12 +18,12 @@ Classifier: Topic :: System :: Distributed Computing
|
|
|
18
18
|
Requires-Python: >=3.10
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE
|
|
21
|
-
Requires-Dist: grpcio>=1.
|
|
22
|
-
Requires-Dist: protobuf>=
|
|
21
|
+
Requires-Dist: grpcio>=1.80
|
|
22
|
+
Requires-Dist: protobuf>=6.31.1
|
|
23
23
|
Requires-Dist: pydantic>=2
|
|
24
24
|
Requires-Dist: httpx<1,>=0.27
|
|
25
25
|
Provides-Extra: dev
|
|
26
|
-
Requires-Dist: grpcio-tools
|
|
26
|
+
Requires-Dist: grpcio-tools<=1.80,>=1.60; extra == "dev"
|
|
27
27
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
28
28
|
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
29
29
|
Requires-Dist: build>=1.0; extra == "dev"
|
|
@@ -531,6 +531,32 @@ volume.attachments # [DiskAttachment(machine_id, machine_name, mount_path,
|
|
|
531
531
|
# mount_mode is "ro" or "rw"
|
|
532
532
|
```
|
|
533
533
|
|
|
534
|
+
## Custom domains
|
|
535
|
+
|
|
536
|
+
```python
|
|
537
|
+
machine = boxd.machines.get(machine_id)
|
|
538
|
+
print(boxd.domains.dns_instructions(
|
|
539
|
+
"app.example.com", machine_name=machine.name, machine_ip="<machine's public IP>",
|
|
540
|
+
zone=boxd.account.config().zone,
|
|
541
|
+
))
|
|
542
|
+
# Point an A record at the machine's public IP, and a wildcard CNAME
|
|
543
|
+
# (*.app.example.com) at <machine>.<zone> — only once those are actually in
|
|
544
|
+
# place:
|
|
545
|
+
domain = boxd.domains.create("app.example.com", machine_id) # starts "pending"
|
|
546
|
+
domain.status # "pending" | "active"
|
|
547
|
+
domain.last_error # empty once active
|
|
548
|
+
boxd.domains.list()
|
|
549
|
+
boxd.domains.delete("app.example.com")
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
`create` binds the domain and starts verification immediately — call it only
|
|
553
|
+
once DNS is actually set. Checking before the records exist risks a public
|
|
554
|
+
DNS resolver caching the "no records" answer, which would delay verification
|
|
555
|
+
after you do set them. `dns_instructions` is a local helper (no network
|
|
556
|
+
call) for rendering the records to show a user first — it doesn't touch the
|
|
557
|
+
API. A background check verifies DNS and issues certs automatically, then
|
|
558
|
+
flips `status` to `"active"`.
|
|
559
|
+
|
|
534
560
|
## Organizations, credentials, account
|
|
535
561
|
|
|
536
562
|
```python
|
|
@@ -544,6 +570,24 @@ orgs[0].is_default # where your personal machines are billed
|
|
|
544
570
|
|
|
545
571
|
Anywhere a call takes `org`, it accepts an organization's name or id.
|
|
546
572
|
|
|
573
|
+
An org can also have a wildcard domain (e.g. `preview.mysaas.com`,
|
|
574
|
+
covering `<machine>.preview.mysaas.com` for every machine in the org).
|
|
575
|
+
Setting or clearing it requires org admin; reading it doesn't.
|
|
576
|
+
|
|
577
|
+
```python
|
|
578
|
+
# Delegate the apex's NS records to boxd's cluster nameservers at your
|
|
579
|
+
# registrar — only once that's actually done:
|
|
580
|
+
d = boxd.orgs.set_domain("acme", "preview.mysaas.com") # starts "pending"
|
|
581
|
+
d.status, d.last_error
|
|
582
|
+
boxd.orgs.get_domain("acme") # None if unset
|
|
583
|
+
boxd.orgs.clear_domain("acme")
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
`set_domain` starts verification immediately — call it only once NS
|
|
587
|
+
delegation is actually live, for the same reason as per-machine domains
|
|
588
|
+
above. A background check then verifies delegation and issues certs
|
|
589
|
+
automatically, then flips `status` to `"active"`.
|
|
590
|
+
|
|
547
591
|
```python
|
|
548
592
|
key = boxd.api_keys.create(
|
|
549
593
|
"ci",
|
|
@@ -1,35 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: boxd
|
|
3
|
-
Version: 0.2.2.dev44
|
|
4
|
-
Summary: Python SDK for the boxd cloud VM platform
|
|
5
|
-
Author: Azin
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://boxd.sh
|
|
8
|
-
Keywords: boxd,vm,microvm,sandbox,compute,grpc,sdk
|
|
9
|
-
Classifier: Development Status :: 4 - Beta
|
|
10
|
-
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: Operating System :: OS Independent
|
|
12
|
-
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
-
Classifier: Topic :: System :: Distributed Computing
|
|
18
|
-
Requires-Python: >=3.10
|
|
19
|
-
Description-Content-Type: text/markdown
|
|
20
|
-
License-File: LICENSE
|
|
21
|
-
Requires-Dist: grpcio>=1.60
|
|
22
|
-
Requires-Dist: protobuf>=4.25
|
|
23
|
-
Requires-Dist: pydantic>=2
|
|
24
|
-
Requires-Dist: httpx<1,>=0.27
|
|
25
|
-
Provides-Extra: dev
|
|
26
|
-
Requires-Dist: grpcio-tools>=1.60; extra == "dev"
|
|
27
|
-
Requires-Dist: pytest>=8; extra == "dev"
|
|
28
|
-
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
29
|
-
Requires-Dist: build>=1.0; extra == "dev"
|
|
30
|
-
Requires-Dist: twine>=4.0; extra == "dev"
|
|
31
|
-
Dynamic: license-file
|
|
32
|
-
|
|
33
1
|
# boxd Python SDK
|
|
34
2
|
|
|
35
3
|
Python SDK for the [boxd](https://boxd.sh) cloud machine platform. Create
|
|
@@ -531,6 +499,32 @@ volume.attachments # [DiskAttachment(machine_id, machine_name, mount_path,
|
|
|
531
499
|
# mount_mode is "ro" or "rw"
|
|
532
500
|
```
|
|
533
501
|
|
|
502
|
+
## Custom domains
|
|
503
|
+
|
|
504
|
+
```python
|
|
505
|
+
machine = boxd.machines.get(machine_id)
|
|
506
|
+
print(boxd.domains.dns_instructions(
|
|
507
|
+
"app.example.com", machine_name=machine.name, machine_ip="<machine's public IP>",
|
|
508
|
+
zone=boxd.account.config().zone,
|
|
509
|
+
))
|
|
510
|
+
# Point an A record at the machine's public IP, and a wildcard CNAME
|
|
511
|
+
# (*.app.example.com) at <machine>.<zone> — only once those are actually in
|
|
512
|
+
# place:
|
|
513
|
+
domain = boxd.domains.create("app.example.com", machine_id) # starts "pending"
|
|
514
|
+
domain.status # "pending" | "active"
|
|
515
|
+
domain.last_error # empty once active
|
|
516
|
+
boxd.domains.list()
|
|
517
|
+
boxd.domains.delete("app.example.com")
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
`create` binds the domain and starts verification immediately — call it only
|
|
521
|
+
once DNS is actually set. Checking before the records exist risks a public
|
|
522
|
+
DNS resolver caching the "no records" answer, which would delay verification
|
|
523
|
+
after you do set them. `dns_instructions` is a local helper (no network
|
|
524
|
+
call) for rendering the records to show a user first — it doesn't touch the
|
|
525
|
+
API. A background check verifies DNS and issues certs automatically, then
|
|
526
|
+
flips `status` to `"active"`.
|
|
527
|
+
|
|
534
528
|
## Organizations, credentials, account
|
|
535
529
|
|
|
536
530
|
```python
|
|
@@ -544,6 +538,24 @@ orgs[0].is_default # where your personal machines are billed
|
|
|
544
538
|
|
|
545
539
|
Anywhere a call takes `org`, it accepts an organization's name or id.
|
|
546
540
|
|
|
541
|
+
An org can also have a wildcard domain (e.g. `preview.mysaas.com`,
|
|
542
|
+
covering `<machine>.preview.mysaas.com` for every machine in the org).
|
|
543
|
+
Setting or clearing it requires org admin; reading it doesn't.
|
|
544
|
+
|
|
545
|
+
```python
|
|
546
|
+
# Delegate the apex's NS records to boxd's cluster nameservers at your
|
|
547
|
+
# registrar — only once that's actually done:
|
|
548
|
+
d = boxd.orgs.set_domain("acme", "preview.mysaas.com") # starts "pending"
|
|
549
|
+
d.status, d.last_error
|
|
550
|
+
boxd.orgs.get_domain("acme") # None if unset
|
|
551
|
+
boxd.orgs.clear_domain("acme")
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
`set_domain` starts verification immediately — call it only once NS
|
|
555
|
+
delegation is actually live, for the same reason as per-machine domains
|
|
556
|
+
above. A background check then verifies delegation and issues certs
|
|
557
|
+
automatically, then flips `status` to `"active"`.
|
|
558
|
+
|
|
547
559
|
```python
|
|
548
560
|
key = boxd.api_keys.create(
|
|
549
561
|
"ci",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "boxd"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.5.dev47"
|
|
4
4
|
description = "Python SDK for the boxd cloud VM platform"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -20,8 +20,15 @@ classifiers = [
|
|
|
20
20
|
"Topic :: System :: Distributed Computing",
|
|
21
21
|
]
|
|
22
22
|
dependencies = [
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
# Floors match what api_pb2*.py actually require (protobuf's
|
|
24
|
+
# compat guarantee is forward-only: gencode built with grpcio-tools
|
|
25
|
+
# 1.80 needs grpcio>=1.80 / protobuf>=6.31.1 at runtime, never older).
|
|
26
|
+
# Keep these in lockstep with the grpcio-tools pin below — bumping
|
|
27
|
+
# the codegen toolchain without bumping these floors reintroduces
|
|
28
|
+
# BOX-70 (resolvers install an old protobuf/grpcio that can't load
|
|
29
|
+
# the newer gencode).
|
|
30
|
+
"grpcio>=1.80",
|
|
31
|
+
"protobuf>=6.31.1",
|
|
25
32
|
"pydantic>=2",
|
|
26
33
|
# Cap below 1.0: httpx 1.0 (currently in pre-release as 1.0.devN)
|
|
27
34
|
# removed `httpx.AsyncClient`, which _credentials.py uses for the
|
|
@@ -38,7 +45,11 @@ Homepage = "https://boxd.sh"
|
|
|
38
45
|
|
|
39
46
|
[project.optional-dependencies]
|
|
40
47
|
dev = [
|
|
41
|
-
|
|
48
|
+
# Capped at 1.80: newer grpcio-tools stamps gencode against protobuf
|
|
49
|
+
# 7.x, which bumps the runtime floor above what shared environments
|
|
50
|
+
# (e.g. anything depending on beta9's protobuf<7) can satisfy. See
|
|
51
|
+
# BOX-70 — bump this only alongside the dependency floors above.
|
|
52
|
+
"grpcio-tools>=1.60,<=1.80",
|
|
42
53
|
"pytest>=8",
|
|
43
54
|
"pytest-asyncio>=0.23",
|
|
44
55
|
"build>=1.0",
|
|
@@ -33,6 +33,8 @@ from .errors import (
|
|
|
33
33
|
from .models import (
|
|
34
34
|
Account,
|
|
35
35
|
ApiKey,
|
|
36
|
+
Backup,
|
|
37
|
+
BackupSchedule,
|
|
36
38
|
Billing,
|
|
37
39
|
Checkpoint,
|
|
38
40
|
ClusterConfig,
|
|
@@ -41,6 +43,7 @@ from .models import (
|
|
|
41
43
|
CreatedDisk,
|
|
42
44
|
CreatedProxy,
|
|
43
45
|
CreatedSnapshot,
|
|
46
|
+
CustomDomain,
|
|
44
47
|
Disk,
|
|
45
48
|
DiskAttachment,
|
|
46
49
|
DiskStatus,
|
|
@@ -56,6 +59,7 @@ from .models import (
|
|
|
56
59
|
MachineSourceKind,
|
|
57
60
|
MachineStatus,
|
|
58
61
|
Org,
|
|
62
|
+
OrgDomain,
|
|
59
63
|
OrgRef,
|
|
60
64
|
PauseResult,
|
|
61
65
|
Proxy,
|
|
@@ -87,6 +91,8 @@ __all__ = [
|
|
|
87
91
|
# Models
|
|
88
92
|
"Account",
|
|
89
93
|
"ApiKey",
|
|
94
|
+
"Backup",
|
|
95
|
+
"BackupSchedule",
|
|
90
96
|
"Billing",
|
|
91
97
|
"Checkpoint",
|
|
92
98
|
"ClusterConfig",
|
|
@@ -95,6 +101,7 @@ __all__ = [
|
|
|
95
101
|
"CreatedDisk",
|
|
96
102
|
"CreatedProxy",
|
|
97
103
|
"CreatedSnapshot",
|
|
104
|
+
"CustomDomain",
|
|
98
105
|
"Disk",
|
|
99
106
|
"DiskAttachment",
|
|
100
107
|
"DiskStatus",
|
|
@@ -110,6 +117,7 @@ __all__ = [
|
|
|
110
117
|
"MachineSourceKind",
|
|
111
118
|
"MachineStatus",
|
|
112
119
|
"Org",
|
|
120
|
+
"OrgDomain",
|
|
113
121
|
"OrgRef",
|
|
114
122
|
"PauseResult",
|
|
115
123
|
"Proxy",
|
|
@@ -13,6 +13,7 @@ from ._urls import DEFAULT_BASE_URL, exchange_url_for, resolve_base_url
|
|
|
13
13
|
from .resources.account import Account, AsyncAccount
|
|
14
14
|
from .resources.credentials import ApiKeys, AsyncApiKeys
|
|
15
15
|
from .resources.disks import AsyncDisks, Disks
|
|
16
|
+
from .resources.domains import AsyncDomains, Domains
|
|
16
17
|
from .resources.machines import AsyncMachines, Machines
|
|
17
18
|
from .resources.orgs import AsyncOrgs, Orgs
|
|
18
19
|
from .resources.snapshots import AsyncSnapshots, Snapshots
|
|
@@ -72,6 +73,7 @@ class Boxd:
|
|
|
72
73
|
self.disks = Disks(self._transport)
|
|
73
74
|
self.env = Env(self._transport)
|
|
74
75
|
self.secrets = Secrets(self._transport)
|
|
76
|
+
self.domains = Domains(self._transport)
|
|
75
77
|
self.orgs = Orgs(self._transport)
|
|
76
78
|
self.api_keys = ApiKeys(self._transport)
|
|
77
79
|
self.account = Account(self._transport)
|
|
@@ -128,6 +130,7 @@ class AsyncBoxd:
|
|
|
128
130
|
self.disks = AsyncDisks(self._transport)
|
|
129
131
|
self.env = AsyncEnv(self._transport)
|
|
130
132
|
self.secrets = AsyncSecrets(self._transport)
|
|
133
|
+
self.domains = AsyncDomains(self._transport)
|
|
131
134
|
self.orgs = AsyncOrgs(self._transport)
|
|
132
135
|
self.api_keys = AsyncApiKeys(self._transport)
|
|
133
136
|
self.account = AsyncAccount(self._transport)
|