stackmachine 0.3.0__tar.gz → 0.3.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.
- {stackmachine-0.3.0 → stackmachine-0.3.1}/PKG-INFO +3 -1
- {stackmachine-0.3.0 → stackmachine-0.3.1}/README.md +1 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/pyproject.toml +14 -1
- stackmachine-0.3.1/src/stackmachine/__init__.py +144 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_async_client.py +78 -14
- stackmachine-0.3.1/src/stackmachine/_client.py +184 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_config.py +4 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_pagination.py +2 -1
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_transport.py +63 -35
- stackmachine-0.3.1/src/stackmachine/_types.py +268 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_uploads.py +9 -8
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_utils.py +7 -5
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/resources/_shared.py +3 -2
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/resources/apps.py +39 -26
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/resources/deployments.py +27 -20
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/resources/domains.py +19 -16
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/resources/files.py +8 -8
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/resources/ssh.py +57 -41
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/resources/versions.py +20 -12
- {stackmachine-0.3.0 → stackmachine-0.3.1}/tests/test_package.py +20 -3
- stackmachine-0.3.0/src/stackmachine/__init__.py +0 -72
- stackmachine-0.3.0/src/stackmachine/_client.py +0 -120
- {stackmachine-0.3.0 → stackmachine-0.3.1}/.gitignore +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/examples/async_usage.py +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/examples/basic_usage.py +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/examples/deploy_app.py +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/examples/list_apps.py +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_errors.py +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_graphql/__init__.py +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_graphql/operations.py +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/_models.py +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/py.typed +0 -0
- {stackmachine-0.3.0 → stackmachine-0.3.1}/src/stackmachine/resources/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stackmachine
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Python SDK for StackMachine.
|
|
5
5
|
Project-URL: Homepage, https://github.com/stackmachine/sdks/tree/main/python
|
|
6
6
|
Project-URL: Repository, https://github.com/stackmachine/sdks
|
|
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
15
15
|
Classifier: Typing :: Typed
|
|
16
16
|
Requires-Python: >=3.9
|
|
17
17
|
Requires-Dist: httpx<1,>=0.27
|
|
18
|
+
Requires-Dist: typing-extensions<5,>=4.10
|
|
18
19
|
Requires-Dist: websocket-client<2,>=1.8
|
|
19
20
|
Requires-Dist: websockets<16,>=12
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
@@ -177,6 +178,7 @@ app = stackmachine.apps.retrieve(
|
|
|
177
178
|
cd python
|
|
178
179
|
uv sync --dev
|
|
179
180
|
uv run ruff check src examples tests
|
|
181
|
+
uv run mypy
|
|
180
182
|
uv run pytest
|
|
181
183
|
uv build --no-sources
|
|
182
184
|
```
|
|
@@ -4,12 +4,13 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "stackmachine"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "Python SDK for StackMachine."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"httpx>=0.27,<1",
|
|
13
|
+
"typing-extensions>=4.10,<5",
|
|
13
14
|
"websocket-client>=1.8,<2",
|
|
14
15
|
"websockets>=12,<16",
|
|
15
16
|
]
|
|
@@ -31,6 +32,7 @@ Issues = "https://github.com/stackmachine/sdks/issues"
|
|
|
31
32
|
|
|
32
33
|
[dependency-groups]
|
|
33
34
|
dev = [
|
|
35
|
+
"mypy>=1.13,<2",
|
|
34
36
|
"pytest>=8.0",
|
|
35
37
|
"pytest-asyncio>=0.24",
|
|
36
38
|
"ruff>=0.8",
|
|
@@ -43,6 +45,17 @@ target-version = "py39"
|
|
|
43
45
|
[tool.ruff.lint]
|
|
44
46
|
select = ["E", "F", "I", "B"]
|
|
45
47
|
|
|
48
|
+
[tool.mypy]
|
|
49
|
+
python_version = "3.9"
|
|
50
|
+
files = ["src", "examples", "tests"]
|
|
51
|
+
pretty = true
|
|
52
|
+
show_error_codes = true
|
|
53
|
+
warn_unused_ignores = true
|
|
54
|
+
|
|
55
|
+
[[tool.mypy.overrides]]
|
|
56
|
+
module = ["pytest", "pytest.*"]
|
|
57
|
+
follow_imports = "skip"
|
|
58
|
+
|
|
46
59
|
[tool.pytest.ini_options]
|
|
47
60
|
testpaths = ["tests"]
|
|
48
61
|
asyncio_mode = "auto"
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""StackMachine Python SDK."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
from ._async_client import AsyncStackMachine
|
|
6
|
+
from ._client import StackMachine
|
|
7
|
+
from ._config import RequestOptions
|
|
8
|
+
from ._errors import (
|
|
9
|
+
StackMachineAPIError,
|
|
10
|
+
StackMachineAuthenticationError,
|
|
11
|
+
StackMachineConnectionError,
|
|
12
|
+
StackMachineError,
|
|
13
|
+
StackMachineGraphQLError,
|
|
14
|
+
StackMachineInvalidRequestError,
|
|
15
|
+
StackMachinePermissionError,
|
|
16
|
+
StackMachineRateLimitError,
|
|
17
|
+
StackMachineValidationError,
|
|
18
|
+
is_stackmachine_error,
|
|
19
|
+
)
|
|
20
|
+
from ._models import (
|
|
21
|
+
AppAlias,
|
|
22
|
+
AppSshServer,
|
|
23
|
+
DeployApp,
|
|
24
|
+
DeployAppKindWordPress,
|
|
25
|
+
DeployAppVersion,
|
|
26
|
+
DeploymentProgress,
|
|
27
|
+
ExpectedDNSRecord,
|
|
28
|
+
Log,
|
|
29
|
+
SshAuthorizedKey,
|
|
30
|
+
SshUser,
|
|
31
|
+
UploadProgress,
|
|
32
|
+
Viewer,
|
|
33
|
+
)
|
|
34
|
+
from ._pagination import AsyncStackMachineList, StackMachineList
|
|
35
|
+
from ._types import (
|
|
36
|
+
AppAliasSortBy,
|
|
37
|
+
AppsDomainsCreateInput,
|
|
38
|
+
AppsDomainsListInput,
|
|
39
|
+
AppsSshAuthorizedKeysCreateInput,
|
|
40
|
+
AppsSshAuthorizedKeysDeleteInput,
|
|
41
|
+
AppsSshAuthorizedKeysListInput,
|
|
42
|
+
AppsSshServerUpdateInput,
|
|
43
|
+
AppsSshUsersListInput,
|
|
44
|
+
AppsSshUsersUpdateInput,
|
|
45
|
+
AppsVersionsListInput,
|
|
46
|
+
AppsVersionsLogsListInput,
|
|
47
|
+
AsyncStackMachineInitSettings,
|
|
48
|
+
CreateZipFiles,
|
|
49
|
+
DeployAppAutobuildExtraData,
|
|
50
|
+
DeployAppAutobuildInput,
|
|
51
|
+
DeployAppEnvVarInput,
|
|
52
|
+
DeployAppJobDefinitionInput,
|
|
53
|
+
DeployAppsListInput,
|
|
54
|
+
DeployAppsSortBy,
|
|
55
|
+
DeployAppVersionsSortBy,
|
|
56
|
+
DeployAppWordPressExtraData,
|
|
57
|
+
DeploymentProgressCallback,
|
|
58
|
+
FileInput,
|
|
59
|
+
Headers,
|
|
60
|
+
LogStream,
|
|
61
|
+
PaginationOptions,
|
|
62
|
+
Readable,
|
|
63
|
+
RequestOptionsInput,
|
|
64
|
+
RequestOptionsLike,
|
|
65
|
+
SshAuthenticationMethod,
|
|
66
|
+
SshTokenCreateResult,
|
|
67
|
+
SshUserPasswordRevealResult,
|
|
68
|
+
SshUserPasswordRotateResult,
|
|
69
|
+
StackMachineInitSettings,
|
|
70
|
+
UploadProgressCallback,
|
|
71
|
+
)
|
|
72
|
+
from ._uploads import create_zip
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
__version__ = version("stackmachine")
|
|
76
|
+
except PackageNotFoundError:
|
|
77
|
+
__version__ = "0.3.1"
|
|
78
|
+
|
|
79
|
+
__all__ = [
|
|
80
|
+
"AppAlias",
|
|
81
|
+
"AppAliasSortBy",
|
|
82
|
+
"AppSshServer",
|
|
83
|
+
"AppsDomainsCreateInput",
|
|
84
|
+
"AppsDomainsListInput",
|
|
85
|
+
"AppsSshAuthorizedKeysCreateInput",
|
|
86
|
+
"AppsSshAuthorizedKeysDeleteInput",
|
|
87
|
+
"AppsSshAuthorizedKeysListInput",
|
|
88
|
+
"AppsSshServerUpdateInput",
|
|
89
|
+
"AppsSshUsersListInput",
|
|
90
|
+
"AppsSshUsersUpdateInput",
|
|
91
|
+
"AppsVersionsListInput",
|
|
92
|
+
"AppsVersionsLogsListInput",
|
|
93
|
+
"AsyncStackMachine",
|
|
94
|
+
"AsyncStackMachineInitSettings",
|
|
95
|
+
"AsyncStackMachineList",
|
|
96
|
+
"CreateZipFiles",
|
|
97
|
+
"DeployApp",
|
|
98
|
+
"DeployAppAutobuildExtraData",
|
|
99
|
+
"DeployAppAutobuildInput",
|
|
100
|
+
"DeployAppEnvVarInput",
|
|
101
|
+
"DeployAppJobDefinitionInput",
|
|
102
|
+
"DeployAppKindWordPress",
|
|
103
|
+
"DeployAppVersion",
|
|
104
|
+
"DeployAppVersionsSortBy",
|
|
105
|
+
"DeployAppWordPressExtraData",
|
|
106
|
+
"DeployAppsListInput",
|
|
107
|
+
"DeployAppsSortBy",
|
|
108
|
+
"DeploymentProgress",
|
|
109
|
+
"DeploymentProgressCallback",
|
|
110
|
+
"ExpectedDNSRecord",
|
|
111
|
+
"FileInput",
|
|
112
|
+
"Headers",
|
|
113
|
+
"Log",
|
|
114
|
+
"LogStream",
|
|
115
|
+
"PaginationOptions",
|
|
116
|
+
"Readable",
|
|
117
|
+
"RequestOptions",
|
|
118
|
+
"RequestOptionsInput",
|
|
119
|
+
"RequestOptionsLike",
|
|
120
|
+
"SshAuthenticationMethod",
|
|
121
|
+
"SshAuthorizedKey",
|
|
122
|
+
"SshTokenCreateResult",
|
|
123
|
+
"SshUser",
|
|
124
|
+
"SshUserPasswordRevealResult",
|
|
125
|
+
"SshUserPasswordRotateResult",
|
|
126
|
+
"StackMachine",
|
|
127
|
+
"StackMachineAPIError",
|
|
128
|
+
"StackMachineAuthenticationError",
|
|
129
|
+
"StackMachineConnectionError",
|
|
130
|
+
"StackMachineError",
|
|
131
|
+
"StackMachineGraphQLError",
|
|
132
|
+
"StackMachineInvalidRequestError",
|
|
133
|
+
"StackMachineList",
|
|
134
|
+
"StackMachineInitSettings",
|
|
135
|
+
"StackMachinePermissionError",
|
|
136
|
+
"StackMachineRateLimitError",
|
|
137
|
+
"StackMachineValidationError",
|
|
138
|
+
"UploadProgress",
|
|
139
|
+
"UploadProgressCallback",
|
|
140
|
+
"Viewer",
|
|
141
|
+
"__version__",
|
|
142
|
+
"create_zip",
|
|
143
|
+
"is_stackmachine_error",
|
|
144
|
+
]
|
|
@@ -13,6 +13,7 @@ from ._config import (
|
|
|
13
13
|
from ._graphql import operations as gql
|
|
14
14
|
from ._models import Viewer
|
|
15
15
|
from ._transport import AsyncTransport
|
|
16
|
+
from ._types import AsyncStackMachineInitSettings, Headers, RequestOptionsLike
|
|
16
17
|
from ._uploads import AsyncUploader
|
|
17
18
|
from .resources.apps import AsyncDeployAppsResource
|
|
18
19
|
from .resources.deployments import AsyncDeploymentsResource
|
|
@@ -25,7 +26,7 @@ class AsyncStackMachine:
|
|
|
25
26
|
api_key: str,
|
|
26
27
|
*,
|
|
27
28
|
api_url: str = DEFAULT_API_URL,
|
|
28
|
-
headers: Optional[
|
|
29
|
+
headers: Optional[Headers] = None,
|
|
29
30
|
timeout: float = DEFAULT_TIMEOUT,
|
|
30
31
|
max_network_retries: int = DEFAULT_MAX_NETWORK_RETRIES,
|
|
31
32
|
http_client: Optional[httpx.AsyncClient] = None,
|
|
@@ -56,16 +57,79 @@ class AsyncStackMachine:
|
|
|
56
57
|
@classmethod
|
|
57
58
|
def init(
|
|
58
59
|
cls,
|
|
59
|
-
settings: Optional[
|
|
60
|
-
|
|
60
|
+
settings: Optional[AsyncStackMachineInitSettings] = None,
|
|
61
|
+
*,
|
|
62
|
+
api_key: Optional[str] = None,
|
|
63
|
+
apiKey: Optional[str] = None,
|
|
64
|
+
token: Optional[str] = None,
|
|
65
|
+
api_url: Optional[str] = None,
|
|
66
|
+
apiUrl: Optional[str] = None,
|
|
67
|
+
headers: Optional[Headers] = None,
|
|
68
|
+
timeout: Optional[float] = None,
|
|
69
|
+
max_network_retries: Optional[int] = None,
|
|
70
|
+
maxNetworkRetries: Optional[int] = None,
|
|
71
|
+
http_client: Optional[httpx.AsyncClient] = None,
|
|
72
|
+
http_transport: Optional[httpx.AsyncBaseTransport] = None,
|
|
61
73
|
) -> "AsyncStackMachine":
|
|
62
|
-
values = {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
values: AsyncStackMachineInitSettings = {} if settings is None else settings
|
|
75
|
+
resolved_api_key = (
|
|
76
|
+
api_key
|
|
77
|
+
if api_key is not None
|
|
78
|
+
else apiKey
|
|
79
|
+
if apiKey is not None
|
|
80
|
+
else token
|
|
81
|
+
if token is not None
|
|
82
|
+
else values.get("api_key")
|
|
83
|
+
or values.get("apiKey")
|
|
84
|
+
or values.get("token")
|
|
85
|
+
or ""
|
|
86
|
+
)
|
|
87
|
+
settings_timeout = values.get("timeout")
|
|
88
|
+
resolved_timeout = (
|
|
89
|
+
timeout
|
|
90
|
+
if timeout is not None
|
|
91
|
+
else settings_timeout
|
|
92
|
+
if settings_timeout is not None
|
|
93
|
+
else DEFAULT_TIMEOUT
|
|
94
|
+
)
|
|
95
|
+
resolved_api_url = (
|
|
96
|
+
api_url
|
|
97
|
+
if api_url is not None
|
|
98
|
+
else apiUrl
|
|
99
|
+
if apiUrl is not None
|
|
100
|
+
else values.get("api_url")
|
|
101
|
+
or values.get("apiUrl")
|
|
102
|
+
or DEFAULT_API_URL
|
|
103
|
+
)
|
|
104
|
+
settings_max_retries = (
|
|
105
|
+
values.get("max_network_retries")
|
|
106
|
+
if values.get("max_network_retries") is not None
|
|
107
|
+
else values.get("maxNetworkRetries")
|
|
108
|
+
)
|
|
109
|
+
resolved_max_retries = (
|
|
110
|
+
max_network_retries
|
|
111
|
+
if max_network_retries is not None
|
|
112
|
+
else maxNetworkRetries
|
|
113
|
+
if maxNetworkRetries is not None
|
|
114
|
+
else settings_max_retries
|
|
115
|
+
if settings_max_retries is not None
|
|
116
|
+
else DEFAULT_MAX_NETWORK_RETRIES
|
|
117
|
+
)
|
|
118
|
+
return cls(
|
|
119
|
+
resolved_api_key,
|
|
120
|
+
api_url=resolved_api_url,
|
|
121
|
+
headers=headers if headers is not None else values.get("headers"),
|
|
122
|
+
timeout=resolved_timeout,
|
|
123
|
+
max_network_retries=resolved_max_retries,
|
|
124
|
+
http_client=(
|
|
125
|
+
http_client if http_client is not None else values.get("http_client")
|
|
126
|
+
),
|
|
127
|
+
http_transport=(
|
|
128
|
+
http_transport
|
|
129
|
+
if http_transport is not None
|
|
130
|
+
else values.get("http_transport")
|
|
131
|
+
),
|
|
132
|
+
)
|
|
69
133
|
|
|
70
134
|
async def close(self) -> None:
|
|
71
135
|
await self._transport.close()
|
|
@@ -81,7 +145,7 @@ class AsyncStackMachine:
|
|
|
81
145
|
query: str,
|
|
82
146
|
variables: Optional[Mapping[str, Any]] = None,
|
|
83
147
|
*,
|
|
84
|
-
request_options: Optional[
|
|
148
|
+
request_options: Optional[RequestOptionsLike] = None,
|
|
85
149
|
) -> Any:
|
|
86
150
|
return await self._transport.execute(
|
|
87
151
|
query,
|
|
@@ -94,7 +158,7 @@ class AsyncStackMachine:
|
|
|
94
158
|
query: str,
|
|
95
159
|
variables: Optional[Mapping[str, Any]] = None,
|
|
96
160
|
*,
|
|
97
|
-
request_options: Optional[
|
|
161
|
+
request_options: Optional[RequestOptionsLike] = None,
|
|
98
162
|
) -> Any:
|
|
99
163
|
return await self._transport.execute(
|
|
100
164
|
query,
|
|
@@ -104,7 +168,7 @@ class AsyncStackMachine:
|
|
|
104
168
|
)
|
|
105
169
|
|
|
106
170
|
def _subscribe_deployment(
|
|
107
|
-
self, build_id: str, request_options: Optional[
|
|
171
|
+
self, build_id: str, request_options: Optional[RequestOptionsLike] = None
|
|
108
172
|
):
|
|
109
173
|
return self._transport.subscribe(
|
|
110
174
|
gql.AUTOBUILD_SUBSCRIPTION,
|
|
@@ -113,7 +177,7 @@ class AsyncStackMachine:
|
|
|
113
177
|
)
|
|
114
178
|
|
|
115
179
|
async def viewer(
|
|
116
|
-
self, *, request_options: Optional[
|
|
180
|
+
self, *, request_options: Optional[RequestOptionsLike] = None
|
|
117
181
|
) -> Optional[Viewer]:
|
|
118
182
|
response = await self._query(
|
|
119
183
|
gql.VIEWER_QUERY, {}, request_options=request_options
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Mapping, Optional
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from ._config import (
|
|
8
|
+
DEFAULT_API_URL,
|
|
9
|
+
DEFAULT_MAX_NETWORK_RETRIES,
|
|
10
|
+
DEFAULT_TIMEOUT,
|
|
11
|
+
ClientConfig,
|
|
12
|
+
)
|
|
13
|
+
from ._graphql import operations as gql
|
|
14
|
+
from ._models import Viewer
|
|
15
|
+
from ._transport import SyncTransport
|
|
16
|
+
from ._types import Headers, RequestOptionsLike, StackMachineInitSettings
|
|
17
|
+
from ._uploads import SyncUploader
|
|
18
|
+
from .resources.apps import DeployAppsResource
|
|
19
|
+
from .resources.deployments import DeploymentsResource
|
|
20
|
+
from .resources.files import FilesResource
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class StackMachine:
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
api_key: str,
|
|
27
|
+
*,
|
|
28
|
+
api_url: str = DEFAULT_API_URL,
|
|
29
|
+
headers: Optional[Headers] = None,
|
|
30
|
+
timeout: float = DEFAULT_TIMEOUT,
|
|
31
|
+
max_network_retries: int = DEFAULT_MAX_NETWORK_RETRIES,
|
|
32
|
+
http_client: Optional[httpx.Client] = None,
|
|
33
|
+
http_transport: Optional[httpx.BaseTransport] = None,
|
|
34
|
+
) -> None:
|
|
35
|
+
self.api_key = api_key
|
|
36
|
+
self.api_url = api_url
|
|
37
|
+
self.apiUrl = api_url
|
|
38
|
+
self.timeout = timeout
|
|
39
|
+
self.max_network_retries = max_network_retries
|
|
40
|
+
self.maxNetworkRetries = max_network_retries
|
|
41
|
+
self._config = ClientConfig(
|
|
42
|
+
api_url=api_url,
|
|
43
|
+
headers=headers,
|
|
44
|
+
timeout=timeout,
|
|
45
|
+
max_network_retries=max_network_retries,
|
|
46
|
+
)
|
|
47
|
+
self._transport = SyncTransport(
|
|
48
|
+
api_key,
|
|
49
|
+
self._config,
|
|
50
|
+
http_client=http_client,
|
|
51
|
+
http_transport=http_transport,
|
|
52
|
+
)
|
|
53
|
+
self.deployments = DeploymentsResource(self)
|
|
54
|
+
self.apps = DeployAppsResource(self, self.deployments)
|
|
55
|
+
self.files = FilesResource(self, SyncUploader(self._transport))
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def init(
|
|
59
|
+
cls,
|
|
60
|
+
settings: Optional[StackMachineInitSettings] = None,
|
|
61
|
+
*,
|
|
62
|
+
api_key: Optional[str] = None,
|
|
63
|
+
apiKey: Optional[str] = None,
|
|
64
|
+
token: Optional[str] = None,
|
|
65
|
+
api_url: Optional[str] = None,
|
|
66
|
+
apiUrl: Optional[str] = None,
|
|
67
|
+
headers: Optional[Headers] = None,
|
|
68
|
+
timeout: Optional[float] = None,
|
|
69
|
+
max_network_retries: Optional[int] = None,
|
|
70
|
+
maxNetworkRetries: Optional[int] = None,
|
|
71
|
+
http_client: Optional[httpx.Client] = None,
|
|
72
|
+
http_transport: Optional[httpx.BaseTransport] = None,
|
|
73
|
+
) -> "StackMachine":
|
|
74
|
+
values: StackMachineInitSettings = {} if settings is None else settings
|
|
75
|
+
resolved_api_key = (
|
|
76
|
+
api_key
|
|
77
|
+
if api_key is not None
|
|
78
|
+
else apiKey
|
|
79
|
+
if apiKey is not None
|
|
80
|
+
else token
|
|
81
|
+
if token is not None
|
|
82
|
+
else values.get("api_key")
|
|
83
|
+
or values.get("apiKey")
|
|
84
|
+
or values.get("token")
|
|
85
|
+
or ""
|
|
86
|
+
)
|
|
87
|
+
settings_timeout = values.get("timeout")
|
|
88
|
+
resolved_timeout = (
|
|
89
|
+
timeout
|
|
90
|
+
if timeout is not None
|
|
91
|
+
else settings_timeout
|
|
92
|
+
if settings_timeout is not None
|
|
93
|
+
else DEFAULT_TIMEOUT
|
|
94
|
+
)
|
|
95
|
+
resolved_api_url = (
|
|
96
|
+
api_url
|
|
97
|
+
if api_url is not None
|
|
98
|
+
else apiUrl
|
|
99
|
+
if apiUrl is not None
|
|
100
|
+
else values.get("api_url")
|
|
101
|
+
or values.get("apiUrl")
|
|
102
|
+
or DEFAULT_API_URL
|
|
103
|
+
)
|
|
104
|
+
settings_max_retries = (
|
|
105
|
+
values.get("max_network_retries")
|
|
106
|
+
if values.get("max_network_retries") is not None
|
|
107
|
+
else values.get("maxNetworkRetries")
|
|
108
|
+
)
|
|
109
|
+
resolved_max_retries = (
|
|
110
|
+
max_network_retries
|
|
111
|
+
if max_network_retries is not None
|
|
112
|
+
else maxNetworkRetries
|
|
113
|
+
if maxNetworkRetries is not None
|
|
114
|
+
else settings_max_retries
|
|
115
|
+
if settings_max_retries is not None
|
|
116
|
+
else DEFAULT_MAX_NETWORK_RETRIES
|
|
117
|
+
)
|
|
118
|
+
return cls(
|
|
119
|
+
resolved_api_key,
|
|
120
|
+
api_url=resolved_api_url,
|
|
121
|
+
headers=headers if headers is not None else values.get("headers"),
|
|
122
|
+
timeout=resolved_timeout,
|
|
123
|
+
max_network_retries=resolved_max_retries,
|
|
124
|
+
http_client=(
|
|
125
|
+
http_client if http_client is not None else values.get("http_client")
|
|
126
|
+
),
|
|
127
|
+
http_transport=(
|
|
128
|
+
http_transport
|
|
129
|
+
if http_transport is not None
|
|
130
|
+
else values.get("http_transport")
|
|
131
|
+
),
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def close(self) -> None:
|
|
135
|
+
self._transport.close()
|
|
136
|
+
|
|
137
|
+
def __enter__(self) -> "StackMachine":
|
|
138
|
+
return self
|
|
139
|
+
|
|
140
|
+
def __exit__(self, *exc_info: object) -> None:
|
|
141
|
+
self.close()
|
|
142
|
+
|
|
143
|
+
def _query(
|
|
144
|
+
self,
|
|
145
|
+
query: str,
|
|
146
|
+
variables: Optional[Mapping[str, Any]] = None,
|
|
147
|
+
*,
|
|
148
|
+
request_options: Optional[RequestOptionsLike] = None,
|
|
149
|
+
) -> Any:
|
|
150
|
+
return self._transport.execute(
|
|
151
|
+
query,
|
|
152
|
+
variables,
|
|
153
|
+
request_options=request_options,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
def _mutation(
|
|
157
|
+
self,
|
|
158
|
+
query: str,
|
|
159
|
+
variables: Optional[Mapping[str, Any]] = None,
|
|
160
|
+
*,
|
|
161
|
+
request_options: Optional[RequestOptionsLike] = None,
|
|
162
|
+
) -> Any:
|
|
163
|
+
return self._transport.execute(
|
|
164
|
+
query,
|
|
165
|
+
variables,
|
|
166
|
+
request_options=request_options,
|
|
167
|
+
mutation=True,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
def _subscribe_deployment(
|
|
171
|
+
self, build_id: str, request_options: Optional[RequestOptionsLike] = None
|
|
172
|
+
):
|
|
173
|
+
return self._transport.subscribe(
|
|
174
|
+
gql.AUTOBUILD_SUBSCRIPTION,
|
|
175
|
+
{"buildId": build_id},
|
|
176
|
+
request_options=request_options,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
def viewer(
|
|
180
|
+
self, *, request_options: Optional[RequestOptionsLike] = None
|
|
181
|
+
) -> Optional[Viewer]:
|
|
182
|
+
response = self._query(gql.VIEWER_QUERY, {}, request_options=request_options)
|
|
183
|
+
viewer = response.get("viewer") if response else None
|
|
184
|
+
return Viewer(username=viewer["username"]) if viewer else None
|
|
@@ -11,11 +11,15 @@ DEFAULT_MAX_NETWORK_RETRIES = 1
|
|
|
11
11
|
@dataclass
|
|
12
12
|
class RequestOptions:
|
|
13
13
|
api_key: Optional[str] = None
|
|
14
|
+
apiKey: Optional[str] = None
|
|
14
15
|
headers: Optional[Mapping[str, str]] = None
|
|
15
16
|
timeout: Optional[float] = None
|
|
16
17
|
max_network_retries: Optional[int] = None
|
|
18
|
+
maxNetworkRetries: Optional[int] = None
|
|
17
19
|
idempotency_key: Optional[str] = None
|
|
20
|
+
idempotencyKey: Optional[str] = None
|
|
18
21
|
client_mutation_id: Optional[str] = None
|
|
22
|
+
clientMutationId: Optional[str] = None
|
|
19
23
|
force: Optional[bool] = None
|
|
20
24
|
|
|
21
25
|
|
|
@@ -12,6 +12,7 @@ from typing import (
|
|
|
12
12
|
Mapping,
|
|
13
13
|
Optional,
|
|
14
14
|
TypeVar,
|
|
15
|
+
cast,
|
|
15
16
|
)
|
|
16
17
|
|
|
17
18
|
from ._errors import StackMachineValidationError
|
|
@@ -299,7 +300,7 @@ class AsyncStackMachineList(Generic[T]):
|
|
|
299
300
|
async for item in self:
|
|
300
301
|
result = handler(item)
|
|
301
302
|
if hasattr(result, "__await__"):
|
|
302
|
-
result = await
|
|
303
|
+
result = await cast(Awaitable[Optional[bool]], result)
|
|
303
304
|
if result is False:
|
|
304
305
|
return
|
|
305
306
|
|