Skip to content

Commit d7cd8b8

Browse files
authored
Merge pull request #3 from miruml/release-please--branches--main--changes--next
release: 0.4.1-beta.1
2 parents 2bbd706 + 7f85464 commit d7cd8b8

21 files changed

+318
-68
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.4.1-beta.0"
2+
".": "0.4.1-beta.1"
33
}

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 14
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/miru-ml%2Fmiru-server-7d0dd143c8ea9bc230d9810d8cfb3fde8b1d4eb48295ebf2db7ea67916fb96c3.yml
3-
openapi_spec_hash: b6667a2e80a356a67bab83f8d5f6e51a
4-
config_hash: 78c50efd3bbfb4969846973cb0609eff
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/miru-ml%2Fmiru-server-1187ba20c7bd5d91919c6e65f71201c9997541aae5ea6b3068b2e8094b4b8d0c.yml
3+
openapi_spec_hash: fd892348c3cd6e7ec5bdce4d8134bf14
4+
config_hash: c47912de5d58c4db1a9ed9e3f82a24a0

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 0.4.1-beta.1 (2025-10-05)
4+
5+
Full Changelog: [v0.4.1-beta.0...v0.4.1-beta.1](https://github.com/miruml/python-server-sdk/compare/v0.4.1-beta.0...v0.4.1-beta.1)
6+
7+
### Features
8+
9+
* **api:** manual updates ([1f24c3f](https://github.com/miruml/python-server-sdk/commit/1f24c3f238e13344e158a909a8444fe6a02534ec))
10+
* **api:** manual updates ([616466d](https://github.com/miruml/python-server-sdk/commit/616466d196871cb65ad48ecccf292be3596043b1))
11+
312
## 0.4.1-beta.0 (2025-10-05)
413

514
Full Changelog: [v0.4.0...v0.4.1-beta.0](https://github.com/miruml/python-server-sdk/compare/v0.4.0...v0.4.1-beta.0)

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ It is generated with [Stainless](https://www.stainless.com/).
1111

1212
## Documentation
1313

14-
The full API of this library can be found in [api.md](api.md).
14+
The REST API documentation can be found on [docs.miruml.com](https://docs.miruml.com). The full API of this library can be found in [api.md](api.md).
1515

1616
## Installation
1717

@@ -30,6 +30,8 @@ from miru_server_sdk import Miru
3030

3131
client = Miru(
3232
api_key=os.environ.get("MIRU_SERVER_API_KEY"), # This is the default and can be omitted
33+
# or 'production' | 'local'; defaults to "production".
34+
environment="staging",
3335
)
3436

3537
config_instance = client.config_instances.retrieve(
@@ -54,6 +56,8 @@ from miru_server_sdk import AsyncMiru
5456

5557
client = AsyncMiru(
5658
api_key=os.environ.get("MIRU_SERVER_API_KEY"), # This is the default and can be omitted
59+
# or 'production' | 'local'; defaults to "production".
60+
environment="staging",
5761
)
5862

5963

SECURITY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ before making any information public.
1818
If you encounter security issues that are not directly related to SDKs but pertain to the services
1919
or products provided by Miru, please follow the respective company's security reporting guidelines.
2020

21+
### Miru Terms and Policies
22+
23+
Please contact [email protected] for any questions or concerns regarding the security of our services.
24+
2125
---
2226

2327
Thank you for helping us keep the SDKs and systems they interact with secure.

api.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,11 @@ Methods:
6767

6868
- <code title="get /releases/{release_id}">client.releases.<a href="./src/miru_server_sdk/resources/releases.py">retrieve</a>(release_id, \*\*<a href="src/miru_server_sdk/types/release_retrieve_params.py">params</a>) -> <a href="./src/miru_server_sdk/types/release.py">Release</a></code>
6969
- <code title="get /releases">client.releases.<a href="./src/miru_server_sdk/resources/releases.py">list</a>(\*\*<a href="src/miru_server_sdk/types/release_list_params.py">params</a>) -> <a href="./src/miru_server_sdk/types/release_list_response.py">ReleaseListResponse</a></code>
70+
71+
# Webhooks
72+
73+
Types:
74+
75+
```python
76+
from miru_server_sdk.types import DeploymentValidateWebhookEvent, UnwrapWebhookEvent
77+
```

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[project]
22
name = "miru_server_sdk"
3-
version = "0.4.1-beta.0"
3+
version = "0.4.1-beta.1"
44
description = "The official Python library for the miru API"
55
dynamic = ["readme"]
66
license = "MIT"
77
authors = [
8-
{ name = "Miru", email = "" },
8+
{ name = "Miru", email = "[email protected]" },
99
]
1010
dependencies = [
1111
"httpx>=0.23.0, <1",

src/miru_server_sdk/__init__.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,18 @@
55
from . import types
66
from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes, omit, not_given
77
from ._utils import file_from_path
8-
from ._client import Miru, Client, Stream, Timeout, AsyncMiru, Transport, AsyncClient, AsyncStream, RequestOptions
8+
from ._client import (
9+
ENVIRONMENTS,
10+
Miru,
11+
Client,
12+
Stream,
13+
Timeout,
14+
AsyncMiru,
15+
Transport,
16+
AsyncClient,
17+
AsyncStream,
18+
RequestOptions,
19+
)
920
from ._models import BaseModel
1021
from ._version import __title__, __version__
1122
from ._response import APIResponse as APIResponse, AsyncAPIResponse as AsyncAPIResponse
@@ -63,6 +74,7 @@
6374
"AsyncStream",
6475
"Miru",
6576
"AsyncMiru",
77+
"ENVIRONMENTS",
6678
"file_from_path",
6779
"BaseModel",
6880
"DEFAULT_TIMEOUT",

src/miru_server_sdk/_client.py

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
from __future__ import annotations
44

55
import os
6-
from typing import Any, Mapping
7-
from typing_extensions import Self, override
6+
from typing import Any, Dict, Mapping, cast
7+
from typing_extensions import Self, Literal, override
88

99
import httpx
1010

@@ -21,7 +21,7 @@
2121
)
2222
from ._utils import is_given, get_async_library
2323
from ._version import __version__
24-
from .resources import devices, releases, deployments, config_instances
24+
from .resources import devices, releases, webhooks, deployments, config_instances
2525
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
2626
from ._exceptions import MiruError, APIStatusError
2727
from ._base_client import (
@@ -30,14 +30,31 @@
3030
AsyncAPIClient,
3131
)
3232

33-
__all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Miru", "AsyncMiru", "Client", "AsyncClient"]
33+
__all__ = [
34+
"ENVIRONMENTS",
35+
"Timeout",
36+
"Transport",
37+
"ProxiesTypes",
38+
"RequestOptions",
39+
"Miru",
40+
"AsyncMiru",
41+
"Client",
42+
"AsyncClient",
43+
]
44+
45+
ENVIRONMENTS: Dict[str, str] = {
46+
"production": "https://configs.api.miruml.com/v1",
47+
"staging": "https://configs.dev.api.miruml.com/v1",
48+
"local": "http://localhost:8080/v1",
49+
}
3450

3551

3652
class Miru(SyncAPIClient):
3753
config_instances: config_instances.ConfigInstancesResource
3854
deployments: deployments.DeploymentsResource
3955
devices: devices.DevicesResource
4056
releases: releases.ReleasesResource
57+
webhooks: webhooks.WebhooksResource
4158
with_raw_response: MiruWithRawResponse
4259
with_streaming_response: MiruWithStreamedResponse
4360

@@ -46,13 +63,16 @@ class Miru(SyncAPIClient):
4663
host: str
4764
version: str
4865

66+
_environment: Literal["production", "staging", "local"] | NotGiven
67+
4968
def __init__(
5069
self,
5170
*,
5271
api_key: str | None = None,
5372
host: str | None = None,
5473
version: str | None = None,
55-
base_url: str | httpx.URL | None = None,
74+
environment: Literal["production", "staging", "local"] | NotGiven = not_given,
75+
base_url: str | httpx.URL | None | NotGiven = not_given,
5676
timeout: float | Timeout | None | NotGiven = not_given,
5777
max_retries: int = DEFAULT_MAX_RETRIES,
5878
default_headers: Mapping[str, str] | None = None,
@@ -94,10 +114,31 @@ def __init__(
94114
version = os.environ.get("MIRU_SERVER_VERSION") or "v1"
95115
self.version = version
96116

97-
if base_url is None:
98-
base_url = os.environ.get("MIRU_BASE_URL")
99-
if base_url is None:
100-
base_url = f"https://{host}/{version}"
117+
self._environment = environment
118+
119+
base_url_env = os.environ.get("MIRU_BASE_URL")
120+
if is_given(base_url) and base_url is not None:
121+
# cast required because mypy doesn't understand the type narrowing
122+
base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast]
123+
elif is_given(environment):
124+
if base_url_env and base_url is not None:
125+
raise ValueError(
126+
"Ambiguous URL; The `MIRU_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None",
127+
)
128+
129+
try:
130+
base_url = ENVIRONMENTS[environment]
131+
except KeyError as exc:
132+
raise ValueError(f"Unknown environment: {environment}") from exc
133+
elif base_url_env is not None:
134+
base_url = base_url_env
135+
else:
136+
self._environment = environment = "production"
137+
138+
try:
139+
base_url = ENVIRONMENTS[environment]
140+
except KeyError as exc:
141+
raise ValueError(f"Unknown environment: {environment}") from exc
101142

102143
super().__init__(
103144
version=__version__,
@@ -114,6 +155,7 @@ def __init__(
114155
self.deployments = deployments.DeploymentsResource(self)
115156
self.devices = devices.DevicesResource(self)
116157
self.releases = releases.ReleasesResource(self)
158+
self.webhooks = webhooks.WebhooksResource(self)
117159
self.with_raw_response = MiruWithRawResponse(self)
118160
self.with_streaming_response = MiruWithStreamedResponse(self)
119161

@@ -143,6 +185,7 @@ def copy(
143185
api_key: str | None = None,
144186
host: str | None = None,
145187
version: str | None = None,
188+
environment: Literal["production", "staging", "local"] | None = None,
146189
base_url: str | httpx.URL | None = None,
147190
timeout: float | Timeout | None | NotGiven = not_given,
148191
http_client: httpx.Client | None = None,
@@ -180,6 +223,7 @@ def copy(
180223
host=host or self.host,
181224
version=version or self.version,
182225
base_url=base_url or self.base_url,
226+
environment=environment or self._environment,
183227
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
184228
http_client=http_client,
185229
max_retries=max_retries if is_given(max_retries) else self.max_retries,
@@ -231,6 +275,7 @@ class AsyncMiru(AsyncAPIClient):
231275
deployments: deployments.AsyncDeploymentsResource
232276
devices: devices.AsyncDevicesResource
233277
releases: releases.AsyncReleasesResource
278+
webhooks: webhooks.AsyncWebhooksResource
234279
with_raw_response: AsyncMiruWithRawResponse
235280
with_streaming_response: AsyncMiruWithStreamedResponse
236281

@@ -239,13 +284,16 @@ class AsyncMiru(AsyncAPIClient):
239284
host: str
240285
version: str
241286

287+
_environment: Literal["production", "staging", "local"] | NotGiven
288+
242289
def __init__(
243290
self,
244291
*,
245292
api_key: str | None = None,
246293
host: str | None = None,
247294
version: str | None = None,
248-
base_url: str | httpx.URL | None = None,
295+
environment: Literal["production", "staging", "local"] | NotGiven = not_given,
296+
base_url: str | httpx.URL | None | NotGiven = not_given,
249297
timeout: float | Timeout | None | NotGiven = not_given,
250298
max_retries: int = DEFAULT_MAX_RETRIES,
251299
default_headers: Mapping[str, str] | None = None,
@@ -287,10 +335,31 @@ def __init__(
287335
version = os.environ.get("MIRU_SERVER_VERSION") or "v1"
288336
self.version = version
289337

290-
if base_url is None:
291-
base_url = os.environ.get("MIRU_BASE_URL")
292-
if base_url is None:
293-
base_url = f"https://{host}/{version}"
338+
self._environment = environment
339+
340+
base_url_env = os.environ.get("MIRU_BASE_URL")
341+
if is_given(base_url) and base_url is not None:
342+
# cast required because mypy doesn't understand the type narrowing
343+
base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast]
344+
elif is_given(environment):
345+
if base_url_env and base_url is not None:
346+
raise ValueError(
347+
"Ambiguous URL; The `MIRU_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None",
348+
)
349+
350+
try:
351+
base_url = ENVIRONMENTS[environment]
352+
except KeyError as exc:
353+
raise ValueError(f"Unknown environment: {environment}") from exc
354+
elif base_url_env is not None:
355+
base_url = base_url_env
356+
else:
357+
self._environment = environment = "production"
358+
359+
try:
360+
base_url = ENVIRONMENTS[environment]
361+
except KeyError as exc:
362+
raise ValueError(f"Unknown environment: {environment}") from exc
294363

295364
super().__init__(
296365
version=__version__,
@@ -307,6 +376,7 @@ def __init__(
307376
self.deployments = deployments.AsyncDeploymentsResource(self)
308377
self.devices = devices.AsyncDevicesResource(self)
309378
self.releases = releases.AsyncReleasesResource(self)
379+
self.webhooks = webhooks.AsyncWebhooksResource(self)
310380
self.with_raw_response = AsyncMiruWithRawResponse(self)
311381
self.with_streaming_response = AsyncMiruWithStreamedResponse(self)
312382

@@ -336,6 +406,7 @@ def copy(
336406
api_key: str | None = None,
337407
host: str | None = None,
338408
version: str | None = None,
409+
environment: Literal["production", "staging", "local"] | None = None,
339410
base_url: str | httpx.URL | None = None,
340411
timeout: float | Timeout | None | NotGiven = not_given,
341412
http_client: httpx.AsyncClient | None = None,
@@ -373,6 +444,7 @@ def copy(
373444
host=host or self.host,
374445
version=version or self.version,
375446
base_url=base_url or self.base_url,
447+
environment=environment or self._environment,
376448
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
377449
http_client=http_client,
378450
max_retries=max_retries if is_given(max_retries) else self.max_retries,

src/miru_server_sdk/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "miru_server_sdk"
4-
__version__ = "0.4.1-beta.0" # x-release-please-version
4+
__version__ = "0.4.1-beta.1" # x-release-please-version

0 commit comments

Comments
 (0)