Skip to content

Commit

Permalink
Merge pull request #40 from clear-street/release-please--branches--ma…
Browse files Browse the repository at this point in the history
…in--changes--next

release: 0.1.0-alpha.9
  • Loading branch information
sonicxml authored Sep 5, 2024
2 parents 53eb20d + e409fc3 commit bc987c9
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.0-alpha.8"
".": "0.1.0-alpha.9"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configured_endpoints: 27
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/clear-street%2Fstudio-sdk-cac25d6221de76f03b4e417f9d33f9665f8ed5c2d324693a46d9506212a1fb3e.yml
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/clear-street%2Fstudio-sdk-66efc857b146cfd0808fb37e5913e8ce46ee44fd0eac54154cfbc340d197585d.yml
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## 0.1.0-alpha.9 (2024-09-05)

Full Changelog: [v0.1.0-alpha.8...v0.1.0-alpha.9](https://github.com/clear-street/studio-sdk-python/compare/v0.1.0-alpha.8...v0.1.0-alpha.9)

### Features

* **api:** add sandbox url ([#36](https://github.com/clear-street/studio-sdk-python/issues/36)) ([8a98682](https://github.com/clear-street/studio-sdk-python/commit/8a98682938297f756a7560f3fa76daf083b4cbe8))


### Chores

* pyproject.toml formatting changes ([#37](https://github.com/clear-street/studio-sdk-python/issues/37)) ([927355c](https://github.com/clear-street/studio-sdk-python/commit/927355cf8e5dc6f62a515e1a91b1cf5604d17002))

## 0.1.0-alpha.8 (2024-08-30)

Full Changelog: [v0.1.0-alpha.7...v0.1.0-alpha.8](https://github.com/clear-street/studio-sdk-python/compare/v0.1.0-alpha.7...v0.1.0-alpha.8)
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ from studio_sdk import StudioSDK
client = StudioSDK(
# This is the default and can be omitted
bearer_token=os.environ.get("STUDIO_SDK_BEARER_TOKEN"),
# defaults to "production".
environment="sandbox",
)

entity = client.entities.retrieve(
Expand All @@ -55,6 +57,8 @@ from studio_sdk import AsyncStudioSDK
client = AsyncStudioSDK(
# This is the default and can be omitted
bearer_token=os.environ.get("STUDIO_SDK_BEARER_TOKEN"),
# defaults to "production".
environment="sandbox",
)


Expand Down
6 changes: 1 addition & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "clear-street-studio-sdk"
version = "0.1.0-alpha.8"
version = "0.1.0-alpha.9"
description = "The official Python library for the studio-sdk API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand All @@ -15,7 +15,6 @@ dependencies = [
"distro>=1.7.0, <2",
"sniffio",
"cached-property; python_version < '3.8'",

]
requires-python = ">= 3.7"
classifiers = [
Expand All @@ -36,8 +35,6 @@ classifiers = [
"License :: OSI Approved :: Apache Software License"
]



[project.urls]
Homepage = "https://github.com/clear-street/studio-sdk-python"
Repository = "https://github.com/clear-street/studio-sdk-python"
Expand All @@ -59,7 +56,6 @@ dev-dependencies = [
"dirty-equals>=0.6.0",
"importlib-metadata>=6.7.0",
"rich>=13.7.1",

]

[tool.rye.scripts]
Expand Down
2 changes: 2 additions & 0 deletions src/studio_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from ._types import NOT_GIVEN, NoneType, NotGiven, Transport, ProxiesTypes
from ._utils import file_from_path
from ._client import (
ENVIRONMENTS,
Client,
Stream,
Timeout,
Expand Down Expand Up @@ -68,6 +69,7 @@
"AsyncStream",
"StudioSDK",
"AsyncStudioSDK",
"ENVIRONMENTS",
"file_from_path",
"BaseModel",
"DEFAULT_TIMEOUT",
Expand Down
82 changes: 70 additions & 12 deletions src/studio_sdk/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from __future__ import annotations

import os
from typing import Any, Union, Mapping
from typing_extensions import Self, override
from typing import Any, Dict, Union, Mapping, cast
from typing_extensions import Self, Literal, override

import httpx

Expand Down Expand Up @@ -33,6 +33,7 @@
)

__all__ = [
"ENVIRONMENTS",
"Timeout",
"Transport",
"ProxiesTypes",
Expand All @@ -44,6 +45,11 @@
"AsyncClient",
]

ENVIRONMENTS: Dict[str, str] = {
"production": "https://api.clearstreet.io/studio/v2",
"sandbox": "https://sandbox-api.clearstreet.io/studio/v2",
}


class StudioSDK(SyncAPIClient):
entities: resources.EntitiesResource
Expand All @@ -55,11 +61,14 @@ class StudioSDK(SyncAPIClient):
# client options
bearer_token: str

_environment: Literal["production", "sandbox"] | NotGiven

def __init__(
self,
*,
bearer_token: str | None = None,
base_url: str | httpx.URL | None = None,
environment: Literal["production", "sandbox"] | NotGiven = NOT_GIVEN,
base_url: str | httpx.URL | None | NotGiven = NOT_GIVEN,
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand Down Expand Up @@ -90,10 +99,31 @@ def __init__(
)
self.bearer_token = bearer_token

if base_url is None:
base_url = os.environ.get("STUDIO_SDK_BASE_URL")
if base_url is None:
base_url = f"https://api.clearstreet.io/studio/v2"
self._environment = environment

base_url_env = os.environ.get("STUDIO_SDK_BASE_URL")
if is_given(base_url) and base_url is not None:
# cast required because mypy doesn't understand the type narrowing
base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast]
elif is_given(environment):
if base_url_env and base_url is not None:
raise ValueError(
"Ambiguous URL; The `STUDIO_SDK_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None",
)

try:
base_url = ENVIRONMENTS[environment]
except KeyError as exc:
raise ValueError(f"Unknown environment: {environment}") from exc
elif base_url_env is not None:
base_url = base_url_env
else:
self._environment = environment = "production"

try:
base_url = ENVIRONMENTS[environment]
except KeyError as exc:
raise ValueError(f"Unknown environment: {environment}") from exc

super().__init__(
version=__version__,
Expand Down Expand Up @@ -136,6 +166,7 @@ def copy(
self,
*,
bearer_token: str | None = None,
environment: Literal["production", "sandbox"] | None = None,
base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
http_client: httpx.Client | None = None,
Expand Down Expand Up @@ -171,6 +202,7 @@ def copy(
return self.__class__(
bearer_token=bearer_token or self.bearer_token,
base_url=base_url or self.base_url,
environment=environment or self._environment,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
max_retries=max_retries if is_given(max_retries) else self.max_retries,
Expand Down Expand Up @@ -227,11 +259,14 @@ class AsyncStudioSDK(AsyncAPIClient):
# client options
bearer_token: str

_environment: Literal["production", "sandbox"] | NotGiven

def __init__(
self,
*,
bearer_token: str | None = None,
base_url: str | httpx.URL | None = None,
environment: Literal["production", "sandbox"] | NotGiven = NOT_GIVEN,
base_url: str | httpx.URL | None | NotGiven = NOT_GIVEN,
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
Expand Down Expand Up @@ -262,10 +297,31 @@ def __init__(
)
self.bearer_token = bearer_token

if base_url is None:
base_url = os.environ.get("STUDIO_SDK_BASE_URL")
if base_url is None:
base_url = f"https://api.clearstreet.io/studio/v2"
self._environment = environment

base_url_env = os.environ.get("STUDIO_SDK_BASE_URL")
if is_given(base_url) and base_url is not None:
# cast required because mypy doesn't understand the type narrowing
base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast]
elif is_given(environment):
if base_url_env and base_url is not None:
raise ValueError(
"Ambiguous URL; The `STUDIO_SDK_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None",
)

try:
base_url = ENVIRONMENTS[environment]
except KeyError as exc:
raise ValueError(f"Unknown environment: {environment}") from exc
elif base_url_env is not None:
base_url = base_url_env
else:
self._environment = environment = "production"

try:
base_url = ENVIRONMENTS[environment]
except KeyError as exc:
raise ValueError(f"Unknown environment: {environment}") from exc

super().__init__(
version=__version__,
Expand Down Expand Up @@ -308,6 +364,7 @@ def copy(
self,
*,
bearer_token: str | None = None,
environment: Literal["production", "sandbox"] | None = None,
base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
http_client: httpx.AsyncClient | None = None,
Expand Down Expand Up @@ -343,6 +400,7 @@ def copy(
return self.__class__(
bearer_token=bearer_token or self.bearer_token,
base_url=base_url or self.base_url,
environment=environment or self._environment,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
max_retries=max_retries if is_given(max_retries) else self.max_retries,
Expand Down
2 changes: 1 addition & 1 deletion src/studio_sdk/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "studio_sdk"
__version__ = "0.1.0-alpha.8" # x-release-please-version
__version__ = "0.1.0-alpha.9" # x-release-please-version
20 changes: 20 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,16 @@ def test_base_url_env(self) -> None:
client = StudioSDK(bearer_token=bearer_token, _strict_response_validation=True)
assert client.base_url == "http://localhost:5000/from/env/"

# explicit environment arg requires explicitness
with update_env(STUDIO_SDK_BASE_URL="http://localhost:5000/from/env"):
with pytest.raises(ValueError, match=r"you must pass base_url=None"):
StudioSDK(bearer_token=bearer_token, _strict_response_validation=True, environment="production")

client = StudioSDK(
base_url=None, bearer_token=bearer_token, _strict_response_validation=True, environment="production"
)
assert str(client.base_url).startswith("https://api.clearstreet.io/studio/v2")

@pytest.mark.parametrize(
"client",
[
Expand Down Expand Up @@ -1287,6 +1297,16 @@ def test_base_url_env(self) -> None:
client = AsyncStudioSDK(bearer_token=bearer_token, _strict_response_validation=True)
assert client.base_url == "http://localhost:5000/from/env/"

# explicit environment arg requires explicitness
with update_env(STUDIO_SDK_BASE_URL="http://localhost:5000/from/env"):
with pytest.raises(ValueError, match=r"you must pass base_url=None"):
AsyncStudioSDK(bearer_token=bearer_token, _strict_response_validation=True, environment="production")

client = AsyncStudioSDK(
base_url=None, bearer_token=bearer_token, _strict_response_validation=True, environment="production"
)
assert str(client.base_url).startswith("https://api.clearstreet.io/studio/v2")

@pytest.mark.parametrize(
"client",
[
Expand Down

0 comments on commit bc987c9

Please sign in to comment.