Skip to content

Commit 83e1eab

Browse files
committed
feat: full API coverage and auth fix
Stainless-Generated-From: ed2bef8
1 parent 03026bb commit 83e1eab

248 files changed

Lines changed: 27529 additions & 417 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
lint:
1919
timeout-minutes: 10
2020
name: lint
21-
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
21+
runs-on: ubuntu-latest
2222
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
2323
steps:
2424
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -44,7 +44,7 @@ jobs:
4444
permissions:
4545
contents: read
4646
id-token: write
47-
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
47+
runs-on: ubuntu-latest
4848
steps:
4949
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
5050

@@ -61,44 +61,3 @@ jobs:
6161

6262
- name: Run build
6363
run: rye build
64-
65-
- name: Get GitHub OIDC Token
66-
if: |-
67-
github.repository == 'stainless-sdks/brapi-python' &&
68-
!startsWith(github.ref, 'refs/heads/stl/')
69-
id: github-oidc
70-
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
71-
with:
72-
script: core.setOutput('github_token', await core.getIDToken());
73-
74-
- name: Upload tarball
75-
if: |-
76-
github.repository == 'stainless-sdks/brapi-python' &&
77-
!startsWith(github.ref, 'refs/heads/stl/')
78-
env:
79-
URL: https://pkg.stainless.com/s
80-
AUTH: ${{ steps.github-oidc.outputs.github_token }}
81-
SHA: ${{ github.sha }}
82-
run: ./scripts/utils/upload-artifact.sh
83-
84-
test:
85-
timeout-minutes: 10
86-
name: test
87-
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
88-
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
89-
steps:
90-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
91-
92-
- name: Install Rye
93-
run: |
94-
curl -sSf https://rye.astral.sh/get | bash
95-
echo "$HOME/.rye/shims" >> $GITHUB_PATH
96-
env:
97-
RYE_VERSION: '0.44.0'
98-
RYE_INSTALL_OPTION: '--yes'
99-
100-
- name: Bootstrap
101-
run: ./scripts/bootstrap
102-
103-
- name: Run tests
104-
run: ./scripts/test

‎.github/workflows/publish-pypi.yml‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ jobs:
1212
publish:
1313
name: publish
1414
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
id-token: write
1518

1619
steps:
1720
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -27,5 +30,3 @@ jobs:
2730
- name: Publish to PyPI
2831
run: |
2932
bash ./bin/publish-pypi
30-
env:
31-
PYPI_TOKEN: ${{ secrets.BRAPI_PYPI_TOKEN || secrets.PYPI_TOKEN }}

‎.github/workflows/release-doctor.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ jobs:
1818
run: |
1919
bash ./bin/check-release-environment
2020
env:
21-
PYPI_TOKEN: ${{ secrets.BRAPI_PYPI_TOKEN || secrets.PYPI_TOKEN }}
21+
RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Release Please
2+
on:
3+
push:
4+
branches:
5+
- main
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
jobs:
12+
release-please:
13+
if: github.repository == 'brapi-dev/brapi-python'
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
18+
id: release
19+
with:
20+
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}

‎.stats.yml‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
configured_endpoints: 11
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/alisson/brapi-3fbf41dfdf9916a2922ee0527c641ad8e942055ee097262056e0f9d4f4b0b888.yml
3-
openapi_spec_hash: 138b26f2d129db8a8d8d192e0d0d5f55
4-
config_hash: 14da4c1963f3e0764a3e82d626a1d762
1+
configured_endpoints: 78

‎CONTRIBUTING.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ $ pip install ./path-to-wheel-file.whl
8585

8686
## Running tests
8787

88+
Most tests require you to [set up a mock server](https://github.com/dgellow/steady) against the OpenAPI spec to run the tests.
89+
90+
```sh
91+
$ ./scripts/mock
92+
```
93+
8894
```sh
8995
$ ./scripts/test
9096
```

‎README.md‎

Lines changed: 36 additions & 42 deletions
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 REST API documentation can be found on [brapi.dev](https://brapi.dev). The full API of this library can be found in [api.md](api.md).
14+
The REST API documentation can be found on [brapi.dev](https://brapi.dev/docs). The full API of this library can be found in [api.md](api.md).
1515

1616
## Installation
1717

@@ -25,40 +25,43 @@ pip install brapi
2525
The full API of this library can be found in [api.md](api.md).
2626

2727
```python
28+
import os
2829
from brapi import Brapi
2930

3031
client = Brapi(
31-
api_key="My API Key",
32-
# defaults to "production".
33-
environment="environment_1",
32+
api_key=os.environ.get("BRAPI_API_KEY"), # This is the default and can be omitted
3433
)
3534

36-
quote = client.quote.retrieve(
37-
tickers="REPLACE_ME",
35+
response = client.v2.stocks.quote(
36+
symbols="PETR4",
3837
)
39-
print(quote.guidance)
38+
print(response.requested_at)
4039
```
4140

41+
While you can provide an `api_key` keyword argument,
42+
we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
43+
to add `BRAPI_API_KEY="My API Key"` to your `.env` file
44+
so that your API Key is not stored in source control.
45+
4246
## Async usage
4347

4448
Simply import `AsyncBrapi` instead of `Brapi` and use `await` with each API call:
4549

4650
```python
51+
import os
4752
import asyncio
4853
from brapi import AsyncBrapi
4954

5055
client = AsyncBrapi(
51-
api_key="My API Key",
52-
# defaults to "production".
53-
environment="environment_1",
56+
api_key=os.environ.get("BRAPI_API_KEY"), # This is the default and can be omitted
5457
)
5558

5659

5760
async def main() -> None:
58-
quote = await client.quote.retrieve(
59-
tickers="REPLACE_ME",
61+
response = await client.v2.stocks.quote(
62+
symbols="PETR4",
6063
)
61-
print(quote.guidance)
64+
print(response.requested_at)
6265

6366

6467
asyncio.run(main())
@@ -80,20 +83,21 @@ pip install brapi[aiohttp]
8083
Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
8184

8285
```python
86+
import os
8387
import asyncio
8488
from brapi import DefaultAioHttpClient
8589
from brapi import AsyncBrapi
8690

8791

8892
async def main() -> None:
8993
async with AsyncBrapi(
90-
api_key="My API Key",
94+
api_key=os.environ.get("BRAPI_API_KEY"), # This is the default and can be omitted
9195
http_client=DefaultAioHttpClient(),
9296
) as client:
93-
quote = await client.quote.retrieve(
94-
tickers="REPLACE_ME",
97+
response = await client.v2.stocks.quote(
98+
symbols="PETR4",
9599
)
96-
print(quote.guidance)
100+
print(response.requested_at)
97101

98102

99103
asyncio.run(main())
@@ -121,13 +125,11 @@ All errors inherit from `brapi.APIError`.
121125
import brapi
122126
from brapi import Brapi
123127

124-
client = Brapi(
125-
api_key="My API Key",
126-
)
128+
client = Brapi()
127129

128130
try:
129-
client.quote.retrieve(
130-
tickers="REPLACE_ME",
131+
client.v2.stocks.quote(
132+
symbols="PETR4",
131133
)
132134
except brapi.APIConnectionError as e:
133135
print("The server could not be reached")
@@ -166,14 +168,13 @@ from brapi import Brapi
166168

167169
# Configure the default for all requests:
168170
client = Brapi(
169-
api_key="My API Key",
170171
# default is 2
171172
max_retries=0,
172173
)
173174

174175
# Or, configure per-request:
175-
client.with_options(max_retries=5).quote.retrieve(
176-
tickers="REPLACE_ME",
176+
client.with_options(max_retries=5).v2.stocks.quote(
177+
symbols="PETR4",
177178
)
178179
```
179180

@@ -187,20 +188,18 @@ from brapi import Brapi
187188

188189
# Configure the default for all requests:
189190
client = Brapi(
190-
api_key="My API Key",
191191
# 20 seconds (default is 1 minute)
192192
timeout=20.0,
193193
)
194194

195195
# More granular control:
196196
client = Brapi(
197-
api_key="My API Key",
198197
timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
199198
)
200199

201200
# Override per-request:
202-
client.with_options(timeout=5.0).quote.retrieve(
203-
tickers="REPLACE_ME",
201+
client.with_options(timeout=5.0).v2.stocks.quote(
202+
symbols="PETR4",
204203
)
205204
```
206205

@@ -241,16 +240,14 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
241240
```py
242241
from brapi import Brapi
243242

244-
client = Brapi(
245-
api_key="My API Key",
246-
)
247-
response = client.quote.with_raw_response.retrieve(
248-
tickers="REPLACE_ME",
243+
client = Brapi()
244+
response = client.v2.stocks.with_raw_response.quote(
245+
symbols="PETR4",
249246
)
250247
print(response.headers.get('X-My-Header'))
251248

252-
quote = response.parse() # get the object that `quote.retrieve()` would have returned
253-
print(quote.guidance)
249+
stock = response.parse() # get the object that `v2.stocks.quote()` would have returned
250+
print(stock.requested_at)
254251
```
255252

256253
These methods return an [`APIResponse`](https://github.com/brapi-dev/brapi-python/tree/main/src/brapi/_response.py) object.
@@ -264,8 +261,8 @@ The above interface eagerly reads the full response body when you make the reque
264261
To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.
265262

266263
```python
267-
with client.quote.with_streaming_response.retrieve(
268-
tickers="REPLACE_ME",
264+
with client.v2.stocks.with_streaming_response.quote(
265+
symbols="PETR4",
269266
) as response:
270267
print(response.headers.get("X-My-Header"))
271268

@@ -322,7 +319,6 @@ import httpx
322319
from brapi import Brapi, DefaultHttpxClient
323320

324321
client = Brapi(
325-
api_key="My API Key",
326322
# Or use the `BRAPI_BASE_URL` env var
327323
base_url="http://my.test.server.example.com:8083",
328324
http_client=DefaultHttpxClient(
@@ -345,9 +341,7 @@ By default the library closes underlying HTTP connections whenever the client is
345341
```py
346342
from brapi import Brapi
347343

348-
with Brapi(
349-
api_key="My API Key",
350-
) as client:
344+
with Brapi() as client:
351345
# make requests here
352346
...
353347

0 commit comments

Comments
 (0)