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.
Files changed (43) hide show
  1. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/PKG-INFO +48 -4
  2. boxd-0.2.2.dev44/src/boxd.egg-info/PKG-INFO → boxd-0.2.5.dev47/README.md +44 -32
  3. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/pyproject.toml +15 -4
  4. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/__init__.py +8 -0
  5. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_client.py +3 -0
  6. boxd-0.2.5.dev47/src/boxd/_generated/api_pb2.py +406 -0
  7. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_generated/api_pb2_grpc.py +496 -43
  8. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_mappers.py +57 -2
  9. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_transport.py +55 -19
  10. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/models.py +53 -1
  11. boxd-0.2.5.dev47/src/boxd/resources/domains.py +72 -0
  12. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/machines.py +114 -0
  13. boxd-0.2.5.dev47/src/boxd/resources/orgs.py +85 -0
  14. boxd-0.2.2.dev44/README.md → boxd-0.2.5.dev47/src/boxd.egg-info/PKG-INFO +76 -0
  15. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd.egg-info/SOURCES.txt +1 -0
  16. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd.egg-info/requires.txt +3 -3
  17. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_credentials.py +23 -0
  18. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_mappers.py +38 -0
  19. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_namespaces.py +79 -0
  20. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_transport.py +72 -0
  21. boxd-0.2.2.dev44/src/boxd/_generated/api_pb2.py +0 -362
  22. boxd-0.2.2.dev44/src/boxd/resources/orgs.py +0 -27
  23. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/LICENSE +0 -0
  24. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/setup.cfg +0 -0
  25. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_credentials.py +0 -0
  26. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_generated/__init__.py +0 -0
  27. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_requests.py +0 -0
  28. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_streaming.py +0 -0
  29. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_urls.py +0 -0
  30. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/_version_check.py +0 -0
  31. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/errors.py +0 -0
  32. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/__init__.py +0 -0
  33. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/account.py +0 -0
  34. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/credentials.py +0 -0
  35. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/disks.py +0 -0
  36. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/snapshots.py +0 -0
  37. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd/resources/vars.py +0 -0
  38. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd.egg-info/dependency_links.txt +0 -0
  39. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/src/boxd.egg-info/top_level.txt +0 -0
  40. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_requests.py +0 -0
  41. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_streaming.py +0 -0
  42. {boxd-0.2.2.dev44 → boxd-0.2.5.dev47}/tests/test_urls.py +0 -0
  43. {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.2.dev44
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.60
22
- Requires-Dist: protobuf>=4.25
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>=1.60; extra == "dev"
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.2.dev44"
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
- "grpcio>=1.60",
24
- "protobuf>=4.25",
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
- "grpcio-tools>=1.60",
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)