Skip to content

Commit 1659b61

Browse files
release: 0.1.0-alpha.1 (#5)
* feat(api): update via SDK Studio (#4) * release: 0.1.0-alpha.1 --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent 1cbe34b commit 1659b61

8 files changed

Lines changed: 135 additions & 240 deletions

File tree

.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.0.1-alpha.1"
2+
".": "0.1.0-alpha.1"
33
}

CHANGELOG.md

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

3+
## 0.1.0-alpha.1 (2024-11-29)
4+
5+
Full Changelog: [v0.0.1-alpha.1...v0.1.0-alpha.1](https://github.com/makegov/tango-python/compare/v0.0.1-alpha.1...v0.1.0-alpha.1)
6+
7+
### Features
8+
9+
* **api:** update via SDK Studio ([#4](https://github.com/makegov/tango-python/issues/4)) ([53ec9bd](https://github.com/makegov/tango-python/commit/53ec9bd1e1938224f9fd6ff0036fd61f3bbbcc67))
10+
311
## 0.0.1-alpha.1 (2024-11-29)
412

513
Full Changelog: [v0.0.1-alpha.0...v0.0.1-alpha.1](https://github.com/makegov/tango-python/compare/v0.0.1-alpha.0...v0.0.1-alpha.1)

README.md

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,32 @@ pip install --pre tango-python
2424
The full API of this library can be found in [api.md](api.md).
2525

2626
```python
27+
import os
2728
from tango import Tango
2829

2930
client = Tango(
30-
client_id="My Client ID",
31-
client_secret="My Client Secret",
31+
access_token=os.environ.get("TANGO_API_ACCESS_TOKEN"), # This is the default and can be omitted
3232
)
3333

3434
schema = client.schemas.retrieve()
3535
```
3636

37+
While you can provide a `access_token` keyword argument,
38+
we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
39+
to add `TANGO_API_ACCESS_TOKEN="My Access Token"` to your `.env` file
40+
so that your Access Token is not stored in source control.
41+
3742
## Async usage
3843

3944
Simply import `AsyncTango` instead of `Tango` and use `await` with each API call:
4045

4146
```python
47+
import os
4248
import asyncio
4349
from tango import AsyncTango
4450

4551
client = AsyncTango(
46-
client_id="My Client ID",
47-
client_secret="My Client Secret",
52+
access_token=os.environ.get("TANGO_API_ACCESS_TOKEN"), # This is the default and can be omitted
4853
)
4954

5055

@@ -79,10 +84,7 @@ All errors inherit from `tango.APIError`.
7984
import tango
8085
from tango import Tango
8186

82-
client = Tango(
83-
client_id="My Client ID",
84-
client_secret="My Client Secret",
85-
)
87+
client = Tango()
8688

8789
try:
8890
client.schemas.retrieve()
@@ -125,8 +127,6 @@ from tango import Tango
125127
client = Tango(
126128
# default is 2
127129
max_retries=0,
128-
client_id="My Client ID",
129-
client_secret="My Client Secret",
130130
)
131131

132132
# Or, configure per-request:
@@ -145,15 +145,11 @@ from tango import Tango
145145
client = Tango(
146146
# 20 seconds (default is 1 minute)
147147
timeout=20.0,
148-
client_id="My Client ID",
149-
client_secret="My Client Secret",
150148
)
151149

152150
# More granular control:
153151
client = Tango(
154152
timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
155-
client_id="My Client ID",
156-
client_secret="My Client Secret",
157153
)
158154

159155
# Override per-request:
@@ -197,10 +193,7 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
197193
```py
198194
from tango import Tango
199195

200-
client = Tango(
201-
client_id="My Client ID",
202-
client_secret="My Client Secret",
203-
)
196+
client = Tango()
204197
response = client.schemas.with_raw_response.retrieve()
205198
print(response.headers.get('X-My-Header'))
206199

@@ -281,8 +274,6 @@ client = Tango(
281274
proxies="http://my.test.proxy.example.com",
282275
transport=httpx.HTTPTransport(local_address="0.0.0.0"),
283276
),
284-
client_id="My Client ID",
285-
client_secret="My Client Secret",
286277
)
287278
```
288279

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "tango-python"
3-
version = "0.0.1-alpha.1"
3+
version = "0.1.0-alpha.1"
44
description = "The official Python library for the tango API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"

src/tango/_client.py

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,12 @@ class Tango(SyncAPIClient):
6666
with_streaming_response: TangoWithStreamedResponse
6767

6868
# client options
69-
client_id: str
70-
client_secret: str
69+
access_token: str
7170

7271
def __init__(
7372
self,
7473
*,
75-
client_id: str | None = None,
76-
client_secret: str | None = None,
74+
access_token: str | None = None,
7775
base_url: str | httpx.URL | None = None,
7876
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
7977
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -95,25 +93,15 @@ def __init__(
9593
) -> None:
9694
"""Construct a new synchronous tango client instance.
9795
98-
This automatically infers the following arguments from their corresponding environment variables if they are not provided:
99-
- `client_id` from `CLIENT_ID`
100-
- `client_secret` from `CLIENT_SECRET`
96+
This automatically infers the `access_token` argument from the `TANGO_API_ACCESS_TOKEN` environment variable if it is not provided.
10197
"""
102-
if client_id is None:
103-
client_id = os.environ.get("CLIENT_ID")
104-
if client_id is None:
98+
if access_token is None:
99+
access_token = os.environ.get("TANGO_API_ACCESS_TOKEN")
100+
if access_token is None:
105101
raise TangoError(
106-
"The client_id client option must be set either by passing client_id to the client or by setting the CLIENT_ID environment variable"
102+
"The access_token client option must be set either by passing access_token to the client or by setting the TANGO_API_ACCESS_TOKEN environment variable"
107103
)
108-
self.client_id = client_id
109-
110-
if client_secret is None:
111-
client_secret = os.environ.get("CLIENT_SECRET")
112-
if client_secret is None:
113-
raise TangoError(
114-
"The client_secret client option must be set either by passing client_secret to the client or by setting the CLIENT_SECRET environment variable"
115-
)
116-
self.client_secret = client_secret
104+
self.access_token = access_token
117105

118106
if base_url is None:
119107
base_url = os.environ.get("TANGO_BASE_URL")
@@ -155,6 +143,12 @@ def __init__(
155143
def qs(self) -> Querystring:
156144
return Querystring(array_format="comma")
157145

146+
@property
147+
@override
148+
def auth_headers(self) -> dict[str, str]:
149+
access_token = self.access_token
150+
return {"Authorization": f"Bearer {access_token}"}
151+
158152
@property
159153
@override
160154
def default_headers(self) -> dict[str, str | Omit]:
@@ -167,8 +161,7 @@ def default_headers(self) -> dict[str, str | Omit]:
167161
def copy(
168162
self,
169163
*,
170-
client_id: str | None = None,
171-
client_secret: str | None = None,
164+
access_token: str | None = None,
172165
base_url: str | httpx.URL | None = None,
173166
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
174167
http_client: httpx.Client | None = None,
@@ -202,8 +195,7 @@ def copy(
202195

203196
http_client = http_client or self._client
204197
return self.__class__(
205-
client_id=client_id or self.client_id,
206-
client_secret=client_secret or self.client_secret,
198+
access_token=access_token or self.access_token,
207199
base_url=base_url or self.base_url,
208200
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
209201
http_client=http_client,
@@ -272,14 +264,12 @@ class AsyncTango(AsyncAPIClient):
272264
with_streaming_response: AsyncTangoWithStreamedResponse
273265

274266
# client options
275-
client_id: str
276-
client_secret: str
267+
access_token: str
277268

278269
def __init__(
279270
self,
280271
*,
281-
client_id: str | None = None,
282-
client_secret: str | None = None,
272+
access_token: str | None = None,
283273
base_url: str | httpx.URL | None = None,
284274
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
285275
max_retries: int = DEFAULT_MAX_RETRIES,
@@ -301,25 +291,15 @@ def __init__(
301291
) -> None:
302292
"""Construct a new async tango client instance.
303293
304-
This automatically infers the following arguments from their corresponding environment variables if they are not provided:
305-
- `client_id` from `CLIENT_ID`
306-
- `client_secret` from `CLIENT_SECRET`
294+
This automatically infers the `access_token` argument from the `TANGO_API_ACCESS_TOKEN` environment variable if it is not provided.
307295
"""
308-
if client_id is None:
309-
client_id = os.environ.get("CLIENT_ID")
310-
if client_id is None:
296+
if access_token is None:
297+
access_token = os.environ.get("TANGO_API_ACCESS_TOKEN")
298+
if access_token is None:
311299
raise TangoError(
312-
"The client_id client option must be set either by passing client_id to the client or by setting the CLIENT_ID environment variable"
300+
"The access_token client option must be set either by passing access_token to the client or by setting the TANGO_API_ACCESS_TOKEN environment variable"
313301
)
314-
self.client_id = client_id
315-
316-
if client_secret is None:
317-
client_secret = os.environ.get("CLIENT_SECRET")
318-
if client_secret is None:
319-
raise TangoError(
320-
"The client_secret client option must be set either by passing client_secret to the client or by setting the CLIENT_SECRET environment variable"
321-
)
322-
self.client_secret = client_secret
302+
self.access_token = access_token
323303

324304
if base_url is None:
325305
base_url = os.environ.get("TANGO_BASE_URL")
@@ -361,6 +341,12 @@ def __init__(
361341
def qs(self) -> Querystring:
362342
return Querystring(array_format="comma")
363343

344+
@property
345+
@override
346+
def auth_headers(self) -> dict[str, str]:
347+
access_token = self.access_token
348+
return {"Authorization": f"Bearer {access_token}"}
349+
364350
@property
365351
@override
366352
def default_headers(self) -> dict[str, str | Omit]:
@@ -373,8 +359,7 @@ def default_headers(self) -> dict[str, str | Omit]:
373359
def copy(
374360
self,
375361
*,
376-
client_id: str | None = None,
377-
client_secret: str | None = None,
362+
access_token: str | None = None,
378363
base_url: str | httpx.URL | None = None,
379364
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
380365
http_client: httpx.AsyncClient | None = None,
@@ -408,8 +393,7 @@ def copy(
408393

409394
http_client = http_client or self._client
410395
return self.__class__(
411-
client_id=client_id or self.client_id,
412-
client_secret=client_secret or self.client_secret,
396+
access_token=access_token or self.access_token,
413397
base_url=base_url or self.base_url,
414398
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
415399
http_client=http_client,

src/tango/_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__ = "tango"
4-
__version__ = "0.0.1-alpha.1" # x-release-please-version
4+
__version__ = "0.1.0-alpha.1" # x-release-please-version

tests/conftest.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ def pytest_collection_modifyitems(items: list[pytest.Function]) -> None:
2828

2929
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
3030

31-
client_id = "My Client ID"
32-
client_secret = "My Client Secret"
31+
access_token = "My Access Token"
3332

3433

3534
@pytest.fixture(scope="session")
@@ -38,9 +37,7 @@ def client(request: FixtureRequest) -> Iterator[Tango]:
3837
if not isinstance(strict, bool):
3938
raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}")
4039

41-
with Tango(
42-
base_url=base_url, client_id=client_id, client_secret=client_secret, _strict_response_validation=strict
43-
) as client:
40+
with Tango(base_url=base_url, access_token=access_token, _strict_response_validation=strict) as client:
4441
yield client
4542

4643

@@ -50,7 +47,5 @@ async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncTango]:
5047
if not isinstance(strict, bool):
5148
raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}")
5249

53-
async with AsyncTango(
54-
base_url=base_url, client_id=client_id, client_secret=client_secret, _strict_response_validation=strict
55-
) as client:
50+
async with AsyncTango(base_url=base_url, access_token=access_token, _strict_response_validation=strict) as client:
5651
yield client

0 commit comments

Comments
 (0)