diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index bf85fadee..b7512d114 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,12 +1,14 @@
name: CI
on:
push:
- branches-ignore:
- - 'generated'
- - 'codegen/**'
- - 'integrated/**'
- - 'stl-preview-head/**'
- - 'stl-preview-base/**'
+ branches:
+ - '**'
+ - '!integrated/**'
+ - '!stl-preview-head/**'
+ - '!stl-preview-base/**'
+ - '!generated'
+ - '!codegen/**'
+ - 'codegen/stl/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
@@ -17,7 +19,7 @@ jobs:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/structify-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
+ if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@v6
@@ -36,7 +38,7 @@ jobs:
run: ./scripts/lint
build:
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
+ if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
timeout-minutes: 10
name: build
permissions:
@@ -61,14 +63,18 @@ jobs:
run: rye build
- name: Get GitHub OIDC Token
- if: github.repository == 'stainless-sdks/structify-python'
+ if: |-
+ github.repository == 'stainless-sdks/structify-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
uses: actions/github-script@v8
with:
script: core.setOutput('github_token', await core.getIDToken());
- name: Upload tarball
- if: github.repository == 'stainless-sdks/structify-python'
+ if: |-
+ github.repository == 'stainless-sdks/structify-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
diff --git a/.gitignore b/.gitignore
index 95ceb189a..3824f4c48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.prism.log
+.stdy.log
_dev
__pycache__
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 4d3d04fcb..592985c16 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "1.183.0"
+ ".": "1.184.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index fa94e3025..45591bca0 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 234
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/structify%2Fstructify-1e6c4fd0edc3495bc88e8e124a41a7598a682123854f9e9daabc54192f8f976c.yml
-openapi_spec_hash: 8ded4b078445c04fa30d205bcbadc1e5
-config_hash: 165b687c958e22430204bd5ef9094d9a
+configured_endpoints: 257
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/structify%2Fstructify-98b70908fefea6e8700e8b59027706c7243ed385df23a6d9677229bde75d0f66.yml
+openapi_spec_hash: c0683fd6f52b8e1ee90ac4c17a908d88
+config_hash: 5a7e7204a5ad7239167be965bb256616
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f1d6ced3..2385ff3f6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,123 @@
# Changelog
+## 1.184.0 (2026-03-27)
+
+Full Changelog: [v1.183.0...v1.184.0](https://github.com/StructifyAI/structify-python/compare/v1.183.0...v1.184.0)
+
+### Features
+
+* **api:** api update ([60cf087](https://github.com/StructifyAI/structify-python/commit/60cf0874a5e1299c02ca7dea7118ae831c51e6ef))
+* **internal:** implement indices array format for query and form serialization ([6d5a683](https://github.com/StructifyAI/structify-python/commit/6d5a683526efc84586e87f86bf187aed79d2be5b))
+* Update from Structify backend changes ([38c6730](https://github.com/StructifyAI/structify-python/commit/38c67302a084c70b535aa9bbb6594d881e462281))
+* Update from Structify backend changes ([22b7aeb](https://github.com/StructifyAI/structify-python/commit/22b7aeb09997b0d7b8e4320bb5e37860f78874ae))
+* Update from Structify backend changes ([5e74183](https://github.com/StructifyAI/structify-python/commit/5e74183af52a15223e47a86c12e278fa9baae23e))
+* Update from Structify backend changes ([2957a79](https://github.com/StructifyAI/structify-python/commit/2957a7945ff54a0e447255d37665aae07750f368))
+* Update from Structify backend changes ([9c85788](https://github.com/StructifyAI/structify-python/commit/9c8578843117aabfed6c177eef54dd55b32153d4))
+* Update from Structify backend changes ([7300ef1](https://github.com/StructifyAI/structify-python/commit/7300ef146472dae2bc013c407e3dc21806adb8ba))
+* Update from Structify backend changes ([9ccbf40](https://github.com/StructifyAI/structify-python/commit/9ccbf40f09c05630249647b7f4a24ee75de96159))
+* Update from Structify backend changes ([856162a](https://github.com/StructifyAI/structify-python/commit/856162a9e8724dda056be17cf39157a3a2d2b733))
+* Update from Structify backend changes ([0135605](https://github.com/StructifyAI/structify-python/commit/01356050e6b8ca81b73063513a3620830ce2d84f))
+* Update from Structify backend changes ([cb2bde3](https://github.com/StructifyAI/structify-python/commit/cb2bde357153c0bc2d0b145868e0d62915f4f952))
+* Update from Structify backend changes ([a1eb77b](https://github.com/StructifyAI/structify-python/commit/a1eb77bd78add7544ae5bc0d72535d317ee23098))
+* Update from Structify backend changes ([bde5a39](https://github.com/StructifyAI/structify-python/commit/bde5a390b285b282578bb6b4857285b2abd23491))
+* Update from Structify backend changes ([ca4fa72](https://github.com/StructifyAI/structify-python/commit/ca4fa72263d7eb09ba0aa91e2d0e32b1d724bbc1))
+* Update from Structify backend changes ([37cd67f](https://github.com/StructifyAI/structify-python/commit/37cd67f7a018a7d6b37aea2646ca1f9d5559977d))
+* Update from Structify backend changes ([387dd18](https://github.com/StructifyAI/structify-python/commit/387dd1845dfe380e4f36dfa592b57e3131f76fed))
+* Update from Structify backend changes ([d31cd4b](https://github.com/StructifyAI/structify-python/commit/d31cd4b98af129060626b47828b9d99dfae6dbce))
+* Update from Structify backend changes ([da0f0de](https://github.com/StructifyAI/structify-python/commit/da0f0de6d612197df5fd6c85d493e25474f71f1b))
+* Update from Structify backend changes ([2db1ef6](https://github.com/StructifyAI/structify-python/commit/2db1ef601ecc67ffb5696f4cf8cdd6e92e8915bf))
+* Update from Structify backend changes ([ac9f0d5](https://github.com/StructifyAI/structify-python/commit/ac9f0d53b217e035ccbb75d026593634e054f117))
+* Update from Structify backend changes ([5a23230](https://github.com/StructifyAI/structify-python/commit/5a232300a64a4d64671f8167da883d3b80389b9b))
+* Update from Structify backend changes ([234176c](https://github.com/StructifyAI/structify-python/commit/234176cb1e424b08de929ee3445ab3ccf6c85105))
+* Update from Structify backend changes ([9586986](https://github.com/StructifyAI/structify-python/commit/9586986c012ee305ab90de33c7d74ea715becee2))
+* Update from Structify backend changes ([4ec4f4f](https://github.com/StructifyAI/structify-python/commit/4ec4f4f2c97687d23575d9b235ee1a3aefef648d))
+* Update from Structify backend changes ([9c9b785](https://github.com/StructifyAI/structify-python/commit/9c9b785cb118b656322d0614e6602b1f64f25c9b))
+* Update from Structify backend changes ([0175b62](https://github.com/StructifyAI/structify-python/commit/0175b62731b9c9e7cc3a2069b32ed44fae801df2))
+* Update from Structify backend changes ([e8fa6c0](https://github.com/StructifyAI/structify-python/commit/e8fa6c0eee8eef620bd297933c4bbff1da13b798))
+* Update from Structify backend changes ([2d67a15](https://github.com/StructifyAI/structify-python/commit/2d67a154e0b37a1a29e35e21678b059a8cfe1e85))
+* Update from Structify backend changes ([aa26452](https://github.com/StructifyAI/structify-python/commit/aa264524de4459f4977103f5884778d5b3e5200f))
+* Update from Structify backend changes ([6cdb36b](https://github.com/StructifyAI/structify-python/commit/6cdb36ba947a077d7a4ea24ec416da65d2cf4c3f))
+* Update from Structify backend changes ([20ef4cf](https://github.com/StructifyAI/structify-python/commit/20ef4cf65fbf656dec67a065725fc4931a224912))
+* Update from Structify backend changes ([38e454b](https://github.com/StructifyAI/structify-python/commit/38e454b00abe1dbd46adcbcf73e01f0babae4faa))
+* Update from Structify backend changes ([74d1ead](https://github.com/StructifyAI/structify-python/commit/74d1eadcaade7a9bf4f43a968b34a69441647b47))
+* Update from Structify backend changes ([9f87667](https://github.com/StructifyAI/structify-python/commit/9f876676e531c57f0133d2a413bf739d3f7f93cc))
+* Update from Structify backend changes ([e348c2a](https://github.com/StructifyAI/structify-python/commit/e348c2a7b58b48e7c5655757a098bea70033b2b9))
+* Update from Structify backend changes ([c4ccd37](https://github.com/StructifyAI/structify-python/commit/c4ccd37bdf1803dfceb77762fb2c50a960ec4e27))
+* Update from Structify backend changes ([4148cb4](https://github.com/StructifyAI/structify-python/commit/4148cb4b20cbe6cf0ca8371d0d4c602a80f5a764))
+* Update from Structify backend changes ([3536c2c](https://github.com/StructifyAI/structify-python/commit/3536c2cb1daa0eadb86d4966210d1a4bbe45c2c9))
+* Update from Structify backend changes ([95228ad](https://github.com/StructifyAI/structify-python/commit/95228adc1fd74e0ebec420fabceed3d133c2f7be))
+* Update from Structify backend changes ([1df1a86](https://github.com/StructifyAI/structify-python/commit/1df1a867e1490126f24a42ad3c2e16cdc485e92d))
+* Update from Structify backend changes ([59a5760](https://github.com/StructifyAI/structify-python/commit/59a57607f5c573af3639642bfaa20b8bd59f2f8d))
+* Update from Structify backend changes ([761ede8](https://github.com/StructifyAI/structify-python/commit/761ede84e233b966e824ac0aba9bc27b73567f48))
+* Update from Structify backend changes ([bb8b31f](https://github.com/StructifyAI/structify-python/commit/bb8b31f20614a17e816c2ba850429eb0ed71650e))
+* Update from Structify backend changes ([e6f9de0](https://github.com/StructifyAI/structify-python/commit/e6f9de054fb1e15331baa2949f171b9284e83690))
+* Update from Structify backend changes ([74b1b21](https://github.com/StructifyAI/structify-python/commit/74b1b217602570cb51c926fb93057318b4e63a81))
+* Update from Structify backend changes ([27ab73d](https://github.com/StructifyAI/structify-python/commit/27ab73d19b4c16c19c1b95015d3a10cd4d9bd58f))
+* Update from Structify backend changes ([003a774](https://github.com/StructifyAI/structify-python/commit/003a774cb8dd043eda2b550b00acdb9e9e3b5a64))
+* Update from Structify backend changes ([37cc1d9](https://github.com/StructifyAI/structify-python/commit/37cc1d9c7a286de5680f51b9f97125d824022cf1))
+* Update from Structify backend changes ([1e163ca](https://github.com/StructifyAI/structify-python/commit/1e163ca21cb69ea540293df7fa86a2edd74b9c6a))
+* Update from Structify backend changes ([f0e673a](https://github.com/StructifyAI/structify-python/commit/f0e673a1faeef8766e2a3d315c13efea2e1e27fd))
+* Update from Structify backend changes ([06905d3](https://github.com/StructifyAI/structify-python/commit/06905d33be13a97cb80f22d04354695456429e7f))
+* Update from Structify backend changes ([7b2a30a](https://github.com/StructifyAI/structify-python/commit/7b2a30a861fb15068c26b16f4dc6f8fc9de7a59c))
+* Update from Structify backend changes ([11b106e](https://github.com/StructifyAI/structify-python/commit/11b106e4ed0d8d8990206878d403f3462f244b67))
+* Update from Structify backend changes ([657d6aa](https://github.com/StructifyAI/structify-python/commit/657d6aae3f7758ec809f7e41a7805405dfe617b7))
+* Update from Structify backend changes ([e3ad58e](https://github.com/StructifyAI/structify-python/commit/e3ad58e6c063c306aa5e481ec97c74cf4e3ba313))
+* Update from Structify backend changes ([8be62b6](https://github.com/StructifyAI/structify-python/commit/8be62b67db9556a1a8dbd7f7cc5080ae2e164cde))
+* Update from Structify backend changes ([46fc19d](https://github.com/StructifyAI/structify-python/commit/46fc19ded10bfac99a76d2c3a4a3f08d271c25e5))
+* Update from Structify backend changes ([06d6f58](https://github.com/StructifyAI/structify-python/commit/06d6f5872b86da5de923d0657b0c340f312d42ec))
+* Update from Structify backend changes ([d28fc51](https://github.com/StructifyAI/structify-python/commit/d28fc512323f5c7eecd56e086a6894c4e2ea2794))
+* Update from Structify backend changes ([3e01edf](https://github.com/StructifyAI/structify-python/commit/3e01edfbfeb5703f1e52a8d5fd7d7825a49adec3))
+* Update from Structify backend changes ([ffda5ed](https://github.com/StructifyAI/structify-python/commit/ffda5ed618ac602e2e9287512f4b0876c421d741))
+* Update from Structify backend changes ([ef67e88](https://github.com/StructifyAI/structify-python/commit/ef67e8857e56940b6d8f7b7d351ce8bf6d2d6d29))
+* Update from Structify backend changes ([6f8c059](https://github.com/StructifyAI/structify-python/commit/6f8c059edc0ed2a5fb61c805f3a28ece6397f207))
+* Update from Structify backend changes ([ab6c580](https://github.com/StructifyAI/structify-python/commit/ab6c580596d6cb790650173533f43d647651e25a))
+* Update from Structify backend changes ([9091cce](https://github.com/StructifyAI/structify-python/commit/9091cce1f24daa6ec1079c5b313a8c212173f835))
+* Update from Structify backend changes ([fdc379a](https://github.com/StructifyAI/structify-python/commit/fdc379a0fbc2ecc263f473553bded63e671a5640))
+* Update from Structify backend changes ([68e0e5a](https://github.com/StructifyAI/structify-python/commit/68e0e5a43037252590cf8a697d4b78760c4a7260))
+* Update from Structify backend changes ([7822818](https://github.com/StructifyAI/structify-python/commit/782281890bbcb0117c542df7072e167a4b978a1d))
+* Update from Structify backend changes ([5c40f7b](https://github.com/StructifyAI/structify-python/commit/5c40f7b6977787dee2e1d96b1b13a4379229f38a))
+* Update from Structify backend changes ([6cbcd7d](https://github.com/StructifyAI/structify-python/commit/6cbcd7d9e1c0374a9d6780e44f107ba37bea8d4f))
+* Update from Structify backend changes ([f733d2a](https://github.com/StructifyAI/structify-python/commit/f733d2aad89b62c283d279a02d341d2b05a6357e))
+* Update from Structify backend changes ([6c64d5c](https://github.com/StructifyAI/structify-python/commit/6c64d5c8b902b82ef046fafbef03dfbe27fbd05c))
+* Update from Structify backend changes ([454d1dd](https://github.com/StructifyAI/structify-python/commit/454d1ddd7f12b025bb552850da43d381f702fb55))
+* Update from Structify backend changes ([04eadec](https://github.com/StructifyAI/structify-python/commit/04eadec50e082e5ce788917a4d7a7e916c4a6765))
+* Update from Structify backend changes ([248cbcb](https://github.com/StructifyAI/structify-python/commit/248cbcb0cb64809d62173317c07498ad37cd83d2))
+* Update from Structify backend changes ([dade595](https://github.com/StructifyAI/structify-python/commit/dade59552964ae2200022f60dc64f17543d225d3))
+* Update from Structify backend changes ([4c65bf1](https://github.com/StructifyAI/structify-python/commit/4c65bf113a5aeada0e0fa77d46c5cacf50632e7a))
+
+
+### Bug Fixes
+
+* **deps:** bump minimum typing-extensions version ([e948f17](https://github.com/StructifyAI/structify-python/commit/e948f171a34d73a5b6e5f6b334a86b6b98180d4d))
+* **pydantic:** do not pass `by_alias` unless set ([ea00e09](https://github.com/StructifyAI/structify-python/commit/ea00e09a4b072323f1f13c2825773257f638c462))
+* sanitize endpoint path params ([dd440d0](https://github.com/StructifyAI/structify-python/commit/dd440d04c277fee4e8373c09bc51b43a951369a1))
+
+
+### Chores
+
+* **ci:** skip lint on metadata-only changes ([a9b43a6](https://github.com/StructifyAI/structify-python/commit/a9b43a66365028af38669fe38d6a6275e70980c0))
+* **ci:** skip uploading artifacts on stainless-internal branches ([e426d6b](https://github.com/StructifyAI/structify-python/commit/e426d6bf94f57c72581cd3289faf17a8dcd4538e))
+* format all `api.md` files ([fc8a112](https://github.com/StructifyAI/structify-python/commit/fc8a112722cb379d824920e3fde59345fdb4df85))
+* **internal:** add request options to SSE classes ([aa6dc7f](https://github.com/StructifyAI/structify-python/commit/aa6dc7fc0ef92720834578efa70fc6661b4b69a8))
+* **internal:** codegen related update ([206ea94](https://github.com/StructifyAI/structify-python/commit/206ea94f15ea80ed61eca73e32ef753a57b2ede7))
+* **internal:** fix lint error on Python 3.14 ([3a7173f](https://github.com/StructifyAI/structify-python/commit/3a7173f56434bada6297dc0b2b25cd77fa0053cb))
+* **internal:** make `test_proxy_environment_variables` more resilient ([3543b8f](https://github.com/StructifyAI/structify-python/commit/3543b8f5f16df6c661e561ecb5d01d5959fc0f72))
+* **internal:** make `test_proxy_environment_variables` more resilient to env ([42b68e8](https://github.com/StructifyAI/structify-python/commit/42b68e89e75ab91d86ee3b492c2a648acd338ad6))
+* **internal:** tweak CI branches ([92ed8ac](https://github.com/StructifyAI/structify-python/commit/92ed8ac799e16266310bc9e66cb8bbcff3e681aa))
+* **internal:** update gitignore ([60f8dcd](https://github.com/StructifyAI/structify-python/commit/60f8dcd5ac4811c83554ec663bd4d457f33539a5))
+* **test:** do not count install time for mock server timeout ([1563f48](https://github.com/StructifyAI/structify-python/commit/1563f48901ebd6545e8eb594370b12019fb47a30))
+* **tests:** bump steady to v0.19.4 ([15d506e](https://github.com/StructifyAI/structify-python/commit/15d506ee5ea1a4a7bf1a0091237718e1f94edad9))
+* **tests:** bump steady to v0.19.5 ([afa480c](https://github.com/StructifyAI/structify-python/commit/afa480c9b5df39ee202220baf8a7dbf7a367eb39))
+* **tests:** bump steady to v0.19.6 ([4dd5324](https://github.com/StructifyAI/structify-python/commit/4dd53245dca023dac6911d512963d2a14b0155b7))
+* **tests:** bump steady to v0.19.7 ([dc20757](https://github.com/StructifyAI/structify-python/commit/dc20757e4e4ae8250f8468084bc71e638238519c))
+* update mock server docs ([c7ba1b2](https://github.com/StructifyAI/structify-python/commit/c7ba1b2e113db5b1df0282216045997064362d93))
+* update placeholder string ([cfb1da4](https://github.com/StructifyAI/structify-python/commit/cfb1da44851a3714a7096d23413a09abae1ecfc5))
+
+
+### Refactors
+
+* **tests:** switch from prism to steady ([cc504ac](https://github.com/StructifyAI/structify-python/commit/cc504acffcde1581af4c46f697b06ff34dfb4643))
+
## 1.183.0 (2026-02-11)
Full Changelog: [v1.182.0...v1.183.0](https://github.com/StructifyAI/structify-python/compare/v1.182.0...v1.183.0)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 15492f27f..cdb270a71 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -85,11 +85,10 @@ $ pip install ./path-to-wheel-file.whl
## Running tests
-Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
+Most tests require you to [set up a mock server](https://github.com/dgellow/steady) against the OpenAPI spec to run the tests.
```sh
-# you will need npm installed
-$ npx prism mock path/to/your/openapi.yml
+$ ./scripts/mock
```
```sh
diff --git a/README.md b/README.md
index 7c3467649..2a8ad2bb6 100644
--- a/README.md
+++ b/README.md
@@ -120,12 +120,12 @@ from structify import Structify
client = Structify()
-all_teams = []
+all_jobs = []
# Automatically fetches more pages as needed.
-for team in client.admin.teams.list():
- # Do something with team here
- all_teams.append(team)
-print(all_teams)
+for job in client.admin.jobs.list():
+ # Do something with job here
+ all_jobs.append(job)
+print(all_jobs)
```
Or, asynchronously:
@@ -138,11 +138,11 @@ client = AsyncStructify()
async def main() -> None:
- all_teams = []
+ all_jobs = []
# Iterate through items across all pages, issuing requests as needed.
- async for team in client.admin.teams.list():
- all_teams.append(team)
- print(all_teams)
+ async for job in client.admin.jobs.list():
+ all_jobs.append(job)
+ print(all_jobs)
asyncio.run(main())
@@ -151,7 +151,7 @@ asyncio.run(main())
Alternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get_next_page()` methods for more granular control working with pages:
```python
-first_page = await client.admin.teams.list()
+first_page = await client.admin.jobs.list()
if first_page.has_next_page():
print(f"will fetch next page using these details: {first_page.next_page_info()}")
next_page = await first_page.get_next_page()
@@ -163,9 +163,9 @@ if first_page.has_next_page():
Or just work directly with the returned data:
```python
-first_page = await client.admin.teams.list()
-for team in first_page.items:
- print(team)
+first_page = await client.admin.jobs.list()
+for job in first_page.items:
+ print(job.id)
# Remove `await` for non-async usage.
```
@@ -195,10 +195,11 @@ from structify import Structify
client = Structify()
-client.documents.upload(
+client.chat.upload_input_file(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
content=Path("/path/to/file"),
- file_type="Text",
- path=b"raw file contents",
+ content_type="content_type",
+ file_name="file_name",
)
```
diff --git a/api.md b/api.md
index b4715b28a..7bf8b004d 100644
--- a/api.md
+++ b/api.md
@@ -19,9 +19,13 @@ Types:
```python
from structify.types import (
EnrichUserParams,
+ GetOnboardingAnswersResponse,
JwtToAPITokenRequest,
+ OnboardingAnswers,
RefreshSessionRequest,
RefreshSessionResponse,
+ SaveOnboardingAnswersRequest,
+ SaveOnboardingAnswersResponse,
SurveySubmissionRequest,
SurveySubmissionResponse,
TokenResponse,
@@ -36,8 +40,10 @@ Methods:
- client.user.update(\*\*params) -> User
- client.user.enrich(\*\*params) -> None
+- client.user.get_onboarding_answers() -> GetOnboardingAnswersResponse
- client.user.info() -> UserInfo
- client.user.refresh(\*\*params) -> RefreshSessionResponse
+- client.user.save_onboarding_answers(\*\*params) -> SaveOnboardingAnswersResponse
- client.user.survey_submit(\*\*params) -> SurveySubmissionResponse
- client.user.transactions() -> UserTransactionsResponse
- client.user.usage(\*\*params) -> UserUsageResponse
@@ -100,9 +106,11 @@ from structify.types import (
ChatSessionWithMessages,
ChatTemplate,
ChatVisibility,
+ CompressChatResponse,
CopyChatSessionRequest,
CreateChatSessionRequest,
CreateChatSessionResponse,
+ DashboardItem,
DeleteChatSessionResponse,
ErrorResponse,
GetChatSessionResponse,
@@ -110,7 +118,11 @@ from structify.types import (
GrantAdminAccessRequest,
ListChatSessionsResponse,
ListCollaboratorsResponse,
+ ListDashboardsResponse,
Message,
+ SimulatePromptRequest,
+ SimulatePromptResponse,
+ TemplateQuestion,
ToolInvocation,
ToolResult,
UpdateChatSessionFavoriteRequest,
@@ -119,13 +131,16 @@ from structify.types import (
UpdateVisibilityResponse,
ChatAddGitCommitResponse,
ChatCopyNodeOutputByCodeHashResponse,
- ChatDeleteFilesResponse,
+ ChatDeleteInputFileResponse,
ChatGetGitCommitResponse,
ChatGetPartialChatsResponse,
ChatGetSessionTimelineResponse,
+ ChatListInputFilesResponse,
ChatListTemplatesResponse,
ChatLoadFilesResponse,
+ ChatLoadInputFilesResponse,
ChatRevertToCommitResponse,
+ ChatUploadInputFileResponse,
)
```
@@ -133,29 +148,36 @@ Methods:
- client.chat.add_collaborator(chat_id, \*\*params) -> None
- client.chat.add_git_commit(session_id, \*\*params) -> ChatAddGitCommitResponse
-- client.chat.admin_get_chat_prompt(session_id) -> ChatPrompt
- client.chat.admin_issue_found(chat_id, \*\*params) -> AdminIssueFoundResponse
+- client.chat.compress(session_id) -> CompressChatResponse
- client.chat.copy(\*\*params) -> ChatSessionWithMessages
-- client.chat.copy_node_output_by_code_hash(session_id, \*\*params) -> str
+- client.chat.copy_node_output_by_code_hash(session_id, \*\*params) -> ChatCopyNodeOutputByCodeHashResponse
- client.chat.create_session(\*\*params) -> CreateChatSessionResponse
-- client.chat.delete_files(chat_id, \*\*params) -> ChatDeleteFilesResponse
+- client.chat.delete_input_file(chat_id, \*\*params) -> ChatDeleteInputFileResponse
- client.chat.delete_session(session_id) -> DeleteChatSessionResponse
- client.chat.get_dependencies(session_id) -> GetDependenciesResponse
- client.chat.get_git_commit(commit_hash, \*, chat_id) -> ChatGetGitCommitResponse
- client.chat.get_partial_chats(chat_session_id) -> ChatGetPartialChatsResponse
- client.chat.get_session(session_id) -> GetChatSessionResponse
- client.chat.get_session_timeline(session_id) -> ChatGetSessionTimelineResponse
+- client.chat.get_template(template_id) -> ChatTemplate
- client.chat.grant_admin_override(chat_id, \*\*params) -> AdminGrantAccessResponse
- client.chat.list_collaborators(chat_id) -> ListCollaboratorsResponse
+- client.chat.list_dashboards(chat_id, \*\*params) -> ListDashboardsResponse
+- client.chat.list_input_files(chat_id) -> ChatListInputFilesResponse
- client.chat.list_sessions(\*\*params) -> ListChatSessionsResponse
- client.chat.list_templates() -> ChatListTemplatesResponse
- client.chat.load_files(\*\*params) -> ChatLoadFilesResponse
+- client.chat.load_input_file(filename, \*, chat_id) -> BinaryAPIResponse
+- client.chat.load_input_files(chat_id, \*\*params) -> ChatLoadInputFilesResponse
- client.chat.make_permanent(session_id) -> None
- client.chat.remove_collaborator(user_id, \*, chat_id) -> None
- client.chat.revert_to_commit(session_id, \*\*params) -> ChatRevertToCommitResponse
+- client.chat.simulate_prompt(chat_session_id, \*\*params) -> SimulatePromptResponse
- client.chat.update_session(session_id, \*\*params) -> ChatSession
- client.chat.update_session_favorite(session_id, \*\*params) -> ChatSession
- client.chat.update_visibility(session_id, \*\*params) -> UpdateVisibilityResponse
+- client.chat.upload_input_file(chat_id, \*\*params) -> ChatUploadInputFileResponse
# Teams
@@ -258,6 +280,16 @@ Methods:
# Admin
+Types:
+
+```python
+from structify.types import ReportCriticalRequest
+```
+
+Methods:
+
+- client.admin.report_critical(\*\*params) -> None
+
## Teams
Types:
@@ -282,12 +314,13 @@ from structify.types.admin import (
GrantCreditsResponse,
UpdateSeatsOverrideRequest,
UpdateSeatsOverrideResponse,
+ TeamListResponse,
)
```
Methods:
-- client.admin.teams.list(\*\*params) -> SyncJobsList[AdminTeamsListResponse]
+- client.admin.teams.list(\*\*params) -> TeamListResponse
- client.admin.teams.add_member(\*\*params) -> AdminAddMemberResponse
- client.admin.teams.cancel_subscription(\*\*params) -> CancelSubscriptionResponse
- client.admin.teams.create_subscription(\*\*params) -> CreateSubscriptionResponse
@@ -319,14 +352,22 @@ from structify.types.admin import (
AdminDeleteJobsRequest,
AdminDeleteJobsResponse,
AdminListJobsRequestParams,
- AdminListJobsResponse,
+ JobListResponse,
+ JobConcurrencyResponse,
+ JobKillByUserResponse,
+ JobRunningStatsResponse,
+ JobUpdateConcurrencyResponse,
)
```
Methods:
-- client.admin.jobs.list(\*\*params) -> SyncJobsList[AdminListJobsResponse]
+- client.admin.jobs.list(\*\*params) -> SyncJobsList[JobListResponse]
- client.admin.jobs.delete(\*\*params) -> AdminDeleteJobsResponse
+- client.admin.jobs.concurrency() -> JobConcurrencyResponse
+- client.admin.jobs.kill_by_user(\*\*params) -> JobKillByUserResponse
+- client.admin.jobs.running_stats() -> JobRunningStatsResponse
+- client.admin.jobs.update_concurrency(\*\*params) -> JobUpdateConcurrencyResponse
## Sandbox
@@ -406,15 +447,21 @@ Types:
```python
from structify.types.admin import (
+ AdminListConnectorsResponse,
CloneConnectorItem,
CloneConnectorsRequest,
- CloneConnectorsResponse,
+ DatahubIngestionKey,
+ DatahubIngestionType,
+ SetDatahubConfigRequest,
+ ConnectorCloneResponse,
)
```
Methods:
-- client.admin.connector.clone(\*\*params) -> CloneConnectorsResponse
+- client.admin.connector.clone(\*\*params) -> ConnectorCloneResponse
+- client.admin.connector.list_team_connectors(team_id) -> AdminListConnectorsResponse
+- client.admin.connector.set_datahub_config(\*\*params) -> Connector
# Datasets
@@ -503,8 +550,7 @@ from structify.types import (
GetJobEventsResponse,
JobListResponse,
JobCancelResponse,
- JobGetScrapersResponse,
- JobGetSourceEntitiesResponse,
+ JobGetResponse,
JobStatusResponse,
)
```
@@ -513,9 +559,8 @@ Methods:
- client.jobs.list(\*\*params) -> SyncJobsList[JobListResponse]
- client.jobs.cancel(uuid) -> JobCancelResponse
+- client.jobs.get(job_id) -> JobGetResponse
- client.jobs.get_events(job_id) -> GetJobEventsResponse
-- client.jobs.get_scrapers(job_id) -> JobGetScrapersResponse
-- client.jobs.get_source_entities(job_id) -> JobGetSourceEntitiesResponse
- client.jobs.schedule() -> None
- client.jobs.status(\*\*params) -> JobStatusResponse
@@ -550,6 +595,7 @@ from structify.types import (
Dashboard,
DashboardComponent,
DashboardPage,
+ DashboardSpec,
EdgeSpec,
EditNodeOutputRequest,
FinalizeDagRequest,
@@ -561,11 +607,27 @@ from structify.types import (
NodeSpec,
ParquetEdit,
RequestConfirmationRequest,
+ TriggerReviewResponse,
UpdateWorkflowNodeProgressRequest,
UpdateWorkflowNodeRequest,
UploadDashboardLayoutRequest,
UploadNodeVisualizationOutputRequest,
+ VizBooleanControl,
+ VizBooleanControlType,
+ VizControlOption,
+ VizDateControl,
+ VizDateControlType,
+ VizFigure,
+ VizFigureDefinition,
+ VizFigureKind,
+ VizNumberControl,
+ VizNumberControlType,
+ VizParam,
+ VizQuery,
+ VizStringControl,
+ VizStringControlType,
WorkflowDag,
+ WorkflowDashboardItem,
WorkflowNodeExecutionStatus,
WorkflowNodeLog,
WorkflowSession,
@@ -593,6 +655,7 @@ Methods:
- client.sessions.kill_jobs(session_id, \*\*params) -> SessionKillJobsResponse
- client.sessions.mark_errored(session_id, \*\*params) -> WorkflowSession
- client.sessions.request_confirmation(node_id, \*\*params) -> WorkflowSessionNode
+- client.sessions.trigger_review(session_id) -> TriggerReviewResponse
- client.sessions.update_node(node_id, \*\*params) -> WorkflowSessionNode
- client.sessions.update_node_progress(node_id, \*\*params) -> WorkflowSessionNode
- client.sessions.upload_dashboard_layout(session_id, \*\*params) -> WorkflowSession
@@ -651,29 +714,35 @@ from structify.types import (
ConnectorSummariesRequest,
ConnectorSummary,
ConnectorTableInfo,
+ ConnectorTablePathResponse,
ConnectorWithSecrets,
ConnectorWithSnippets,
CreateConnectorRequest,
CreateSecretRequest,
+ DatahubProgress,
+ DatahubSecretMap,
DeleteSchemaObjectRequest,
DeleteSchemaObjectResponse,
ExplorationPhaseID,
+ ExplorationProgress,
ExplorationRun,
ExplorationRunsResponse,
ExplorationStatus,
ExploreConnectorRequest,
- ExploreStatusResponse,
ExplorerChatResponse,
ListTablesResponse,
LlmInformationStore,
+ PhaseActivity,
SchemaObjectID,
UpdateColumnRequest,
UpdateConnectorRequest,
UpdateTableRequest,
UpdateTableResponse,
ConnectorAddSchemaObjectResponse,
+ ConnectorExploreResponse,
ConnectorGetResponse,
ConnectorGetClarificationRequestsResponse,
+ ConnectorListStoresResponse,
ConnectorListWithSnippetsResponse,
ConnectorSearchTablesResponse,
ConnectorSummariesResponse,
@@ -690,20 +759,25 @@ Methods:
- client.connectors.create_secret(connector_id, \*\*params) -> None
- client.connectors.delete_schema_object(connector_id, \*\*params) -> DeleteSchemaObjectResponse
- client.connectors.delete_secret(secret_name, \*, connector_id) -> None
-- client.connectors.explore(connector_id, \*\*params) -> None
+- client.connectors.download_datahub_artifact(kind, \*, connector_id, \*\*params) -> BinaryAPIResponse
+- client.connectors.explore(connector_id, \*\*params) -> ConnectorExploreResponse
- client.connectors.get(connector_id) -> ConnectorGetResponse
+- client.connectors.get_active_exploration_run(connector_id) -> Optional[ExplorationRun]
- client.connectors.get_clarification_requests(connector_id) -> ConnectorGetClarificationRequestsResponse
+- client.connectors.get_exploration_run_progress(run_id, \*, connector_id) -> ExplorationProgress
- client.connectors.get_exploration_runs(connector_id) -> ExplorationRunsResponse
-- client.connectors.get_exploration_status(connector_id) -> ExploreStatusResponse
- client.connectors.get_explorer_chat(connector_id, \*\*params) -> ExplorerChatResponse
- client.connectors.get_store(connector_id) -> ConnectorStoreResponse
+- client.connectors.get_table_path(table_id) -> ConnectorTablePathResponse
+- client.connectors.list_stores() -> ConnectorListStoresResponse
- client.connectors.list_tables(connector_id) -> ListTablesResponse
-- client.connectors.list_with_snippets(\*\*params) -> ConnectorListWithSnippetsResponse
+- client.connectors.list_with_snippets() -> ConnectorListWithSnippetsResponse
- client.connectors.resolve_clarification(clarification_id) -> None
- client.connectors.search_tables(\*\*params) -> ConnectorSearchTablesResponse
- client.connectors.summaries(\*\*params) -> ConnectorSummariesResponse
- client.connectors.update_column(column_id, \*\*params) -> None
- client.connectors.update_table(table_id, \*\*params) -> UpdateTableResponse
+- client.connectors.upload_datahub_artifact(kind, \*, connector_id, \*\*params) -> None
## TypeSnippets
@@ -870,13 +944,19 @@ Methods:
Types:
```python
-from structify.types import GetSandboxRequest, Sandbox, SandboxListResponse
+from structify.types import (
+ GetSandboxRequest,
+ Sandbox,
+ SandboxListResponse,
+ SandboxGetMetricsResponse,
+)
```
Methods:
- client.sandbox.list(chat_id) -> SandboxListResponse
- client.sandbox.get(chat_id, \*\*params) -> Sandbox
+- client.sandbox.get_metrics(sandbox_id) -> SandboxGetMetricsResponse
- client.sandbox.update_status(sandbox_id, \*\*params) -> Sandbox
# Scrape
@@ -902,11 +982,12 @@ Methods:
Types:
```python
-from structify.types import GenerateCodeRequest, InterruptGenerationRequest
+from structify.types import ApplyManualEditRequest, GenerateCodeRequest, InterruptGenerationRequest
```
Methods:
+- client.code.apply_manual_edit(chat_id, \*\*params) -> None
- client.code.generate_code(\*\*params) -> None
- client.code.interrupt_generation(\*\*params) -> None
@@ -918,7 +999,6 @@ Types:
from structify.types import (
ChatPrompt,
SaveRequirement,
- ToolMetadata,
StructureEnhancePropertyResponse,
StructureEnhanceRelationshipResponse,
StructureFindRelationshipResponse,
diff --git a/pyproject.toml b/pyproject.toml
index e1c617e27..ba360bd07 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "structifyai"
-version = "1.183.0"
+version = "1.184.0"
description = "The official Python library for the structify API"
dynamic = ["readme"]
license = "Apache-2.0"
@@ -11,11 +11,12 @@ authors = [
dependencies = [
"httpx>=0.23.0, <1",
"pydantic>=1.9.0, <3",
- "typing-extensions>=4.10, <5",
+ "typing-extensions>=4.14, <5",
"anyio>=3.5.0, <5",
"distro>=1.7.0, <2",
"sniffio",
"polars==1.31.0",
+ "pypdf>=4.0.0,<5.0.0",
"tqdm>=4.66.2,<4.67.0",
]
@@ -72,7 +73,7 @@ format = { chain = [
# run formatting again to fix any inconsistencies when imports are stripped
"format:ruff",
]}
-"format:docs" = "python scripts/utils/ruffen-docs.py README.md api.md"
+"format:docs" = "bash -c 'python scripts/utils/ruffen-docs.py README.md $(find . -type f -name api.md)'"
"format:ruff" = "ruff format"
"lint" = { chain = [
diff --git a/scripts/mock b/scripts/mock
index 0b28f6ea2..290e21b9a 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -19,23 +19,34 @@ fi
echo "==> Starting mock server with URL ${URL}"
-# Run prism mock on the given spec
+# Run steady mock on the given spec
if [ "$1" == "--daemon" ]; then
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
+ # Pre-install the package so the download doesn't eat into the startup timeout
+ npm exec --package=@stdy/cli@0.19.7 -- steady --version
- # Wait for server to come online
+ npm exec --package=@stdy/cli@0.19.7 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
+
+ # Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
- while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do
+ attempts=0
+ while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do
+ if ! kill -0 $! 2>/dev/null; then
+ echo
+ cat .stdy.log
+ exit 1
+ fi
+ attempts=$((attempts + 1))
+ if [ "$attempts" -ge 300 ]; then
+ echo
+ echo "Timed out waiting for Steady server to start"
+ cat .stdy.log
+ exit 1
+ fi
echo -n "."
sleep 0.1
done
- if grep -q "✖ fatal" ".prism.log"; then
- cat .prism.log
- exit 1
- fi
-
echo
else
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL"
+ npm exec --package=@stdy/cli@0.19.7 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
fi
diff --git a/scripts/test b/scripts/test
index dbeda2d21..661f9bf48 100755
--- a/scripts/test
+++ b/scripts/test
@@ -9,8 +9,8 @@ GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
-function prism_is_running() {
- curl --silent "http://localhost:4010" >/dev/null 2>&1
+function steady_is_running() {
+ curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1
}
kill_server_on_port() {
@@ -25,7 +25,7 @@ function is_overriding_api_base_url() {
[ -n "$TEST_API_BASE_URL" ]
}
-if ! is_overriding_api_base_url && ! prism_is_running ; then
+if ! is_overriding_api_base_url && ! steady_is_running ; then
# When we exit this script, make sure to kill the background mock server process
trap 'kill_server_on_port 4010' EXIT
@@ -36,19 +36,19 @@ fi
if is_overriding_api_base_url ; then
echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}"
echo
-elif ! prism_is_running ; then
- echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server"
+elif ! steady_is_running ; then
+ echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Steady server"
echo -e "running against your OpenAPI spec."
echo
echo -e "To run the server, pass in the path or url of your OpenAPI"
- echo -e "spec to the prism command:"
+ echo -e "spec to the steady command:"
echo
- echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}"
+ echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.19.7 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo
exit 1
else
- echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}"
+ echo -e "${GREEN}✔ Mock steady server is running with your OpenAPI spec${NC}"
echo
fi
diff --git a/src/structify/_client.py b/src/structify/_client.py
index 76bd5e434..213456c0c 100644
--- a/src/structify/_client.py
+++ b/src/structify/_client.py
@@ -192,6 +192,7 @@ def __init__(
@cached_property
def whitelabel(self) -> WhitelabelResource:
+ """Whitelabeled service proxy endpoints"""
from .resources.whitelabel import WhitelabelResource
return WhitelabelResource(self)
@@ -216,6 +217,7 @@ def teams(self) -> TeamsResource:
@cached_property
def wiki(self) -> WikiResource:
+ """Team wiki page management endpoints"""
from .resources.wiki import WikiResource
return WikiResource(self)
@@ -228,18 +230,21 @@ def polars(self) -> PolarsResource:
@cached_property
def projects(self) -> ProjectsResource:
+ """Project management endpoints"""
from .resources.projects import ProjectsResource
return ProjectsResource(self)
@cached_property
def admin(self) -> AdminResource:
+ """Admin endpoints"""
from .resources.admin import AdminResource
return AdminResource(self)
@cached_property
def datasets(self) -> DatasetsResource:
+ """Dataset management endpoints"""
from .resources.datasets import DatasetsResource
return DatasetsResource(self)
@@ -312,6 +317,7 @@ def entities(self) -> EntitiesResource:
@cached_property
def sandbox(self) -> SandboxResource:
+ """Sandbox management endpoints"""
from .resources.sandbox import SandboxResource
return SandboxResource(self)
@@ -324,6 +330,7 @@ def scrape(self) -> ScrapeResource:
@cached_property
def code(self) -> CodeResource:
+ """Code generation endpoints"""
from .resources.code import CodeResource
return CodeResource(self)
@@ -579,6 +586,7 @@ def __init__(
@cached_property
def whitelabel(self) -> AsyncWhitelabelResource:
+ """Whitelabeled service proxy endpoints"""
from .resources.whitelabel import AsyncWhitelabelResource
return AsyncWhitelabelResource(self)
@@ -603,24 +611,28 @@ def teams(self) -> AsyncTeamsResource:
@cached_property
def wiki(self) -> AsyncWikiResource:
+ """Team wiki page management endpoints"""
from .resources.wiki import AsyncWikiResource
return AsyncWikiResource(self)
@cached_property
def projects(self) -> AsyncProjectsResource:
+ """Project management endpoints"""
from .resources.projects import AsyncProjectsResource
return AsyncProjectsResource(self)
@cached_property
def admin(self) -> AsyncAdminResource:
+ """Admin endpoints"""
from .resources.admin import AsyncAdminResource
return AsyncAdminResource(self)
@cached_property
def datasets(self) -> AsyncDatasetsResource:
+ """Dataset management endpoints"""
from .resources.datasets import AsyncDatasetsResource
return AsyncDatasetsResource(self)
@@ -693,6 +705,7 @@ def entities(self) -> AsyncEntitiesResource:
@cached_property
def sandbox(self) -> AsyncSandboxResource:
+ """Sandbox management endpoints"""
from .resources.sandbox import AsyncSandboxResource
return AsyncSandboxResource(self)
@@ -705,6 +718,7 @@ def scrape(self) -> AsyncScrapeResource:
@cached_property
def code(self) -> AsyncCodeResource:
+ """Code generation endpoints"""
from .resources.code import AsyncCodeResource
return AsyncCodeResource(self)
@@ -883,6 +897,7 @@ def __init__(self, client: Structify) -> None:
@cached_property
def whitelabel(self) -> whitelabel.WhitelabelResourceWithRawResponse:
+ """Whitelabeled service proxy endpoints"""
from .resources.whitelabel import WhitelabelResourceWithRawResponse
return WhitelabelResourceWithRawResponse(self._client.whitelabel)
@@ -907,12 +922,14 @@ def teams(self) -> teams.TeamsResourceWithRawResponse:
@cached_property
def wiki(self) -> wiki.WikiResourceWithRawResponse:
+ """Team wiki page management endpoints"""
from .resources.wiki import WikiResourceWithRawResponse
return WikiResourceWithRawResponse(self._client.wiki)
@cached_property
def projects(self) -> projects.ProjectsResourceWithRawResponse:
+ """Project management endpoints"""
from .resources.projects import ProjectsResourceWithRawResponse
return ProjectsResourceWithRawResponse(self._client.projects)
@@ -925,12 +942,14 @@ def polars(self) -> polars.PolarsResourceWithRawResponse:
@cached_property
def admin(self) -> admin.AdminResourceWithRawResponse:
+ """Admin endpoints"""
from .resources.admin import AdminResourceWithRawResponse
return AdminResourceWithRawResponse(self._client.admin)
@cached_property
def datasets(self) -> datasets.DatasetsResourceWithRawResponse:
+ """Dataset management endpoints"""
from .resources.datasets import DatasetsResourceWithRawResponse
return DatasetsResourceWithRawResponse(self._client.datasets)
@@ -1003,6 +1022,7 @@ def entities(self) -> entities.EntitiesResourceWithRawResponse:
@cached_property
def sandbox(self) -> sandbox.SandboxResourceWithRawResponse:
+ """Sandbox management endpoints"""
from .resources.sandbox import SandboxResourceWithRawResponse
return SandboxResourceWithRawResponse(self._client.sandbox)
@@ -1015,6 +1035,7 @@ def scrape(self) -> scrape.ScrapeResourceWithRawResponse:
@cached_property
def code(self) -> code.CodeResourceWithRawResponse:
+ """Code generation endpoints"""
from .resources.code import CodeResourceWithRawResponse
return CodeResourceWithRawResponse(self._client.code)
@@ -1052,6 +1073,7 @@ def __init__(self, client: AsyncStructify) -> None:
@cached_property
def whitelabel(self) -> whitelabel.AsyncWhitelabelResourceWithRawResponse:
+ """Whitelabeled service proxy endpoints"""
from .resources.whitelabel import AsyncWhitelabelResourceWithRawResponse
return AsyncWhitelabelResourceWithRawResponse(self._client.whitelabel)
@@ -1076,24 +1098,28 @@ def teams(self) -> teams.AsyncTeamsResourceWithRawResponse:
@cached_property
def wiki(self) -> wiki.AsyncWikiResourceWithRawResponse:
+ """Team wiki page management endpoints"""
from .resources.wiki import AsyncWikiResourceWithRawResponse
return AsyncWikiResourceWithRawResponse(self._client.wiki)
@cached_property
def projects(self) -> projects.AsyncProjectsResourceWithRawResponse:
+ """Project management endpoints"""
from .resources.projects import AsyncProjectsResourceWithRawResponse
return AsyncProjectsResourceWithRawResponse(self._client.projects)
@cached_property
def admin(self) -> admin.AsyncAdminResourceWithRawResponse:
+ """Admin endpoints"""
from .resources.admin import AsyncAdminResourceWithRawResponse
return AsyncAdminResourceWithRawResponse(self._client.admin)
@cached_property
def datasets(self) -> datasets.AsyncDatasetsResourceWithRawResponse:
+ """Dataset management endpoints"""
from .resources.datasets import AsyncDatasetsResourceWithRawResponse
return AsyncDatasetsResourceWithRawResponse(self._client.datasets)
@@ -1166,6 +1192,7 @@ def entities(self) -> entities.AsyncEntitiesResourceWithRawResponse:
@cached_property
def sandbox(self) -> sandbox.AsyncSandboxResourceWithRawResponse:
+ """Sandbox management endpoints"""
from .resources.sandbox import AsyncSandboxResourceWithRawResponse
return AsyncSandboxResourceWithRawResponse(self._client.sandbox)
@@ -1178,6 +1205,7 @@ def scrape(self) -> scrape.AsyncScrapeResourceWithRawResponse:
@cached_property
def code(self) -> code.AsyncCodeResourceWithRawResponse:
+ """Code generation endpoints"""
from .resources.code import AsyncCodeResourceWithRawResponse
return AsyncCodeResourceWithRawResponse(self._client.code)
@@ -1215,6 +1243,7 @@ def __init__(self, client: Structify) -> None:
@cached_property
def whitelabel(self) -> whitelabel.WhitelabelResourceWithStreamingResponse:
+ """Whitelabeled service proxy endpoints"""
from .resources.whitelabel import WhitelabelResourceWithStreamingResponse
return WhitelabelResourceWithStreamingResponse(self._client.whitelabel)
@@ -1239,12 +1268,14 @@ def teams(self) -> teams.TeamsResourceWithStreamingResponse:
@cached_property
def wiki(self) -> wiki.WikiResourceWithStreamingResponse:
+ """Team wiki page management endpoints"""
from .resources.wiki import WikiResourceWithStreamingResponse
return WikiResourceWithStreamingResponse(self._client.wiki)
@cached_property
def projects(self) -> projects.ProjectsResourceWithStreamingResponse:
+ """Project management endpoints"""
from .resources.projects import ProjectsResourceWithStreamingResponse
return ProjectsResourceWithStreamingResponse(self._client.projects)
@@ -1257,12 +1288,14 @@ def polars(self) -> polars.PolarsResourceWithStreamingResponse:
@cached_property
def admin(self) -> admin.AdminResourceWithStreamingResponse:
+ """Admin endpoints"""
from .resources.admin import AdminResourceWithStreamingResponse
return AdminResourceWithStreamingResponse(self._client.admin)
@cached_property
def datasets(self) -> datasets.DatasetsResourceWithStreamingResponse:
+ """Dataset management endpoints"""
from .resources.datasets import DatasetsResourceWithStreamingResponse
return DatasetsResourceWithStreamingResponse(self._client.datasets)
@@ -1335,6 +1368,7 @@ def entities(self) -> entities.EntitiesResourceWithStreamingResponse:
@cached_property
def sandbox(self) -> sandbox.SandboxResourceWithStreamingResponse:
+ """Sandbox management endpoints"""
from .resources.sandbox import SandboxResourceWithStreamingResponse
return SandboxResourceWithStreamingResponse(self._client.sandbox)
@@ -1347,6 +1381,7 @@ def scrape(self) -> scrape.ScrapeResourceWithStreamingResponse:
@cached_property
def code(self) -> code.CodeResourceWithStreamingResponse:
+ """Code generation endpoints"""
from .resources.code import CodeResourceWithStreamingResponse
return CodeResourceWithStreamingResponse(self._client.code)
@@ -1384,6 +1419,7 @@ def __init__(self, client: AsyncStructify) -> None:
@cached_property
def whitelabel(self) -> whitelabel.AsyncWhitelabelResourceWithStreamingResponse:
+ """Whitelabeled service proxy endpoints"""
from .resources.whitelabel import AsyncWhitelabelResourceWithStreamingResponse
return AsyncWhitelabelResourceWithStreamingResponse(self._client.whitelabel)
@@ -1408,24 +1444,28 @@ def teams(self) -> teams.AsyncTeamsResourceWithStreamingResponse:
@cached_property
def wiki(self) -> wiki.AsyncWikiResourceWithStreamingResponse:
+ """Team wiki page management endpoints"""
from .resources.wiki import AsyncWikiResourceWithStreamingResponse
return AsyncWikiResourceWithStreamingResponse(self._client.wiki)
@cached_property
def projects(self) -> projects.AsyncProjectsResourceWithStreamingResponse:
+ """Project management endpoints"""
from .resources.projects import AsyncProjectsResourceWithStreamingResponse
return AsyncProjectsResourceWithStreamingResponse(self._client.projects)
@cached_property
def admin(self) -> admin.AsyncAdminResourceWithStreamingResponse:
+ """Admin endpoints"""
from .resources.admin import AsyncAdminResourceWithStreamingResponse
return AsyncAdminResourceWithStreamingResponse(self._client.admin)
@cached_property
def datasets(self) -> datasets.AsyncDatasetsResourceWithStreamingResponse:
+ """Dataset management endpoints"""
from .resources.datasets import AsyncDatasetsResourceWithStreamingResponse
return AsyncDatasetsResourceWithStreamingResponse(self._client.datasets)
@@ -1498,6 +1538,7 @@ def entities(self) -> entities.AsyncEntitiesResourceWithStreamingResponse:
@cached_property
def sandbox(self) -> sandbox.AsyncSandboxResourceWithStreamingResponse:
+ """Sandbox management endpoints"""
from .resources.sandbox import AsyncSandboxResourceWithStreamingResponse
return AsyncSandboxResourceWithStreamingResponse(self._client.sandbox)
@@ -1510,6 +1551,7 @@ def scrape(self) -> scrape.AsyncScrapeResourceWithStreamingResponse:
@cached_property
def code(self) -> code.AsyncCodeResourceWithStreamingResponse:
+ """Code generation endpoints"""
from .resources.code import AsyncCodeResourceWithStreamingResponse
return AsyncCodeResourceWithStreamingResponse(self._client.code)
diff --git a/src/structify/_compat.py b/src/structify/_compat.py
index 786ff42ad..e6690a4f2 100644
--- a/src/structify/_compat.py
+++ b/src/structify/_compat.py
@@ -2,7 +2,7 @@
from typing import TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, cast, overload
from datetime import date, datetime
-from typing_extensions import Self, Literal
+from typing_extensions import Self, Literal, TypedDict
import pydantic
from pydantic.fields import FieldInfo
@@ -131,6 +131,10 @@ def model_json(model: pydantic.BaseModel, *, indent: int | None = None) -> str:
return model.model_dump_json(indent=indent)
+class _ModelDumpKwargs(TypedDict, total=False):
+ by_alias: bool
+
+
def model_dump(
model: pydantic.BaseModel,
*,
@@ -142,6 +146,9 @@ def model_dump(
by_alias: bool | None = None,
) -> dict[str, Any]:
if (not PYDANTIC_V1) or hasattr(model, "model_dump"):
+ kwargs: _ModelDumpKwargs = {}
+ if by_alias is not None:
+ kwargs["by_alias"] = by_alias
return model.model_dump(
mode=mode,
exclude=exclude,
@@ -149,7 +156,7 @@ def model_dump(
exclude_defaults=exclude_defaults,
# warnings are not supported in Pydantic v1
warnings=True if PYDANTIC_V1 else warnings,
- by_alias=by_alias,
+ **kwargs,
)
return cast(
"dict[str, Any]",
diff --git a/src/structify/_qs.py b/src/structify/_qs.py
index ada6fd3f7..de8c99bc6 100644
--- a/src/structify/_qs.py
+++ b/src/structify/_qs.py
@@ -101,7 +101,10 @@ def _stringify_item(
items.extend(self._stringify_item(key, item, opts))
return items
elif array_format == "indices":
- raise NotImplementedError("The array indices format is not supported yet")
+ items = []
+ for i, item in enumerate(value):
+ items.extend(self._stringify_item(f"{key}[{i}]", item, opts))
+ return items
elif array_format == "brackets":
items = []
key = key + "[]"
diff --git a/src/structify/_response.py b/src/structify/_response.py
index d9e6c9425..46c56282f 100644
--- a/src/structify/_response.py
+++ b/src/structify/_response.py
@@ -152,6 +152,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
),
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
@@ -162,6 +163,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=extract_stream_chunk_type(self._stream_cls),
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
@@ -175,6 +177,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=cast_to,
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
diff --git a/src/structify/_streaming.py b/src/structify/_streaming.py
index 2eadb0067..da79cc765 100644
--- a/src/structify/_streaming.py
+++ b/src/structify/_streaming.py
@@ -4,7 +4,7 @@
import json
import inspect
from types import TracebackType
-from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, AsyncIterator, cast
+from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, Optional, AsyncIterator, cast
from typing_extensions import Self, Protocol, TypeGuard, override, get_origin, runtime_checkable
import httpx
@@ -13,6 +13,7 @@
if TYPE_CHECKING:
from ._client import Structify, AsyncStructify
+ from ._models import FinalRequestOptions
_T = TypeVar("_T")
@@ -22,7 +23,7 @@ class Stream(Generic[_T]):
"""Provides the core interface to iterate over a synchronous stream response."""
response: httpx.Response
-
+ _options: Optional[FinalRequestOptions] = None
_decoder: SSEBytesDecoder
def __init__(
@@ -31,10 +32,12 @@ def __init__(
cast_to: type[_T],
response: httpx.Response,
client: Structify,
+ options: Optional[FinalRequestOptions] = None,
) -> None:
self.response = response
self._cast_to = cast_to
self._client = client
+ self._options = options
self._decoder = client._make_sse_decoder()
self._iterator = self.__stream__()
@@ -85,7 +88,7 @@ class AsyncStream(Generic[_T]):
"""Provides the core interface to iterate over an asynchronous stream response."""
response: httpx.Response
-
+ _options: Optional[FinalRequestOptions] = None
_decoder: SSEDecoder | SSEBytesDecoder
def __init__(
@@ -94,10 +97,12 @@ def __init__(
cast_to: type[_T],
response: httpx.Response,
client: AsyncStructify,
+ options: Optional[FinalRequestOptions] = None,
) -> None:
self.response = response
self._cast_to = cast_to
self._client = client
+ self._options = options
self._decoder = client._make_sse_decoder()
self._iterator = self.__stream__()
diff --git a/src/structify/_utils/__init__.py b/src/structify/_utils/__init__.py
index dc64e29a1..10cb66d2d 100644
--- a/src/structify/_utils/__init__.py
+++ b/src/structify/_utils/__init__.py
@@ -1,3 +1,4 @@
+from ._path import path_template as path_template
from ._sync import asyncify as asyncify
from ._proxy import LazyProxy as LazyProxy
from ._utils import (
diff --git a/src/structify/_utils/_compat.py b/src/structify/_utils/_compat.py
index dd703233c..2c70b299c 100644
--- a/src/structify/_utils/_compat.py
+++ b/src/structify/_utils/_compat.py
@@ -26,7 +26,7 @@ def is_union(tp: Optional[Type[Any]]) -> bool:
else:
import types
- return tp is Union or tp is types.UnionType
+ return tp is Union or tp is types.UnionType # type: ignore[comparison-overlap]
def is_typeddict(tp: Type[Any]) -> bool:
diff --git a/src/structify/_utils/_path.py b/src/structify/_utils/_path.py
new file mode 100644
index 000000000..4d6e1e4cb
--- /dev/null
+++ b/src/structify/_utils/_path.py
@@ -0,0 +1,127 @@
+from __future__ import annotations
+
+import re
+from typing import (
+ Any,
+ Mapping,
+ Callable,
+)
+from urllib.parse import quote
+
+# Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E).
+_DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$")
+
+_PLACEHOLDER_RE = re.compile(r"\{(\w+)\}")
+
+
+def _quote_path_segment_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI path segment.
+
+ Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
+ """
+ # quote() already treats unreserved characters (letters, digits, and -._~)
+ # as safe, so we only need to add sub-delims, ':', and '@'.
+ # Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted.
+ return quote(value, safe="!$&'()*+,;=:@")
+
+
+def _quote_query_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI query string.
+
+ Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
+ """
+ return quote(value, safe="!$'()*+,;:@/?")
+
+
+def _quote_fragment_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI fragment.
+
+ Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
+ """
+ return quote(value, safe="!$&'()*+,;=:@/?")
+
+
+def _interpolate(
+ template: str,
+ values: Mapping[str, Any],
+ quoter: Callable[[str], str],
+) -> str:
+ """Replace {name} placeholders in `template`, quoting each value with `quoter`.
+
+ Placeholder names are looked up in `values`.
+
+ Raises:
+ KeyError: If a placeholder is not found in `values`.
+ """
+ # re.split with a capturing group returns alternating
+ # [text, name, text, name, ..., text] elements.
+ parts = _PLACEHOLDER_RE.split(template)
+
+ for i in range(1, len(parts), 2):
+ name = parts[i]
+ if name not in values:
+ raise KeyError(f"a value for placeholder {{{name}}} was not provided")
+ val = values[name]
+ if val is None:
+ parts[i] = "null"
+ elif isinstance(val, bool):
+ parts[i] = "true" if val else "false"
+ else:
+ parts[i] = quoter(str(values[name]))
+
+ return "".join(parts)
+
+
+def path_template(template: str, /, **kwargs: Any) -> str:
+ """Interpolate {name} placeholders in `template` from keyword arguments.
+
+ Args:
+ template: The template string containing {name} placeholders.
+ **kwargs: Keyword arguments to interpolate into the template.
+
+ Returns:
+ The template with placeholders interpolated and percent-encoded.
+
+ Safe characters for percent-encoding are dependent on the URI component.
+ Placeholders in path and fragment portions are percent-encoded where the `segment`
+ and `fragment` sets from RFC 3986 respectively are considered safe.
+ Placeholders in the query portion are percent-encoded where the `query` set from
+ RFC 3986 §3.3 is considered safe except for = and & characters.
+
+ Raises:
+ KeyError: If a placeholder is not found in `kwargs`.
+ ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments).
+ """
+ # Split the template into path, query, and fragment portions.
+ fragment_template: str | None = None
+ query_template: str | None = None
+
+ rest = template
+ if "#" in rest:
+ rest, fragment_template = rest.split("#", 1)
+ if "?" in rest:
+ rest, query_template = rest.split("?", 1)
+ path_template = rest
+
+ # Interpolate each portion with the appropriate quoting rules.
+ path_result = _interpolate(path_template, kwargs, _quote_path_segment_part)
+
+ # Reject dot-segments (. and ..) in the final assembled path. The check
+ # runs after interpolation so that adjacent placeholders or a mix of static
+ # text and placeholders that together form a dot-segment are caught.
+ # Also reject percent-encoded dot-segments to protect against incorrectly
+ # implemented normalization in servers/proxies.
+ for segment in path_result.split("/"):
+ if _DOT_SEGMENT_RE.match(segment):
+ raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed")
+
+ result = path_result
+ if query_template is not None:
+ result += "?" + _interpolate(query_template, kwargs, _quote_query_part)
+ if fragment_template is not None:
+ result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part)
+
+ return result
diff --git a/src/structify/_version.py b/src/structify/_version.py
index 8f1fc8183..cd8644a6c 100644
--- a/src/structify/_version.py
+++ b/src/structify/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "structify"
-__version__ = "1.183.0" # x-release-please-version
+__version__ = "1.184.0" # x-release-please-version
diff --git a/src/structify/resources/admin/admin.py b/src/structify/resources/admin/admin.py
index 2f19ae99c..5b46c5a38 100644
--- a/src/structify/resources/admin/admin.py
+++ b/src/structify/resources/admin/admin.py
@@ -2,6 +2,8 @@
from __future__ import annotations
+import httpx
+
from .jobs import (
JobsResource,
AsyncJobsResource,
@@ -26,6 +28,7 @@
UsersResourceWithStreamingResponse,
AsyncUsersResourceWithStreamingResponse,
)
+from ...types import admin_report_critical_params
from .dataset import (
DatasetResource,
AsyncDatasetResource,
@@ -42,6 +45,8 @@
SandboxResourceWithStreamingResponse,
AsyncSandboxResourceWithStreamingResponse,
)
+from ..._types import Body, Query, Headers, NoneType, NotGiven, not_given
+from ..._utils import maybe_transform, async_maybe_transform
from ..._compat import cached_property
from .connector import (
ConnectorResource,
@@ -52,6 +57,13 @@
AsyncConnectorResourceWithStreamingResponse,
)
from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
from .chat_templates import (
ChatTemplatesResource,
AsyncChatTemplatesResource,
@@ -73,36 +85,46 @@
class AdminResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def teams(self) -> TeamsResource:
+ """Admin endpoints"""
return TeamsResource(self._client)
@cached_property
def dataset(self) -> DatasetResource:
+ """Admin endpoints"""
return DatasetResource(self._client)
@cached_property
def jobs(self) -> JobsResource:
+ """Admin endpoints"""
return JobsResource(self._client)
@cached_property
def sandbox(self) -> SandboxResource:
+ """Admin endpoints"""
return SandboxResource(self._client)
@cached_property
def functional_tests(self) -> FunctionalTestsResource:
+ """Admin endpoints"""
return FunctionalTestsResource(self._client)
@cached_property
def users(self) -> UsersResource:
+ """Admin endpoints"""
return UsersResource(self._client)
@cached_property
def chat_templates(self) -> ChatTemplatesResource:
+ """Admin endpoints"""
return ChatTemplatesResource(self._client)
@cached_property
def connector(self) -> ConnectorResource:
+ """Admin endpoints"""
return ConnectorResource(self._client)
@cached_property
@@ -124,38 +146,79 @@ def with_streaming_response(self) -> AdminResourceWithStreamingResponse:
"""
return AdminResourceWithStreamingResponse(self)
+ def report_critical(
+ self,
+ *,
+ message: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._post(
+ "/admin/critical",
+ body=maybe_transform({"message": message}, admin_report_critical_params.AdminReportCriticalParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
class AsyncAdminResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def teams(self) -> AsyncTeamsResource:
+ """Admin endpoints"""
return AsyncTeamsResource(self._client)
@cached_property
def dataset(self) -> AsyncDatasetResource:
+ """Admin endpoints"""
return AsyncDatasetResource(self._client)
@cached_property
def jobs(self) -> AsyncJobsResource:
+ """Admin endpoints"""
return AsyncJobsResource(self._client)
@cached_property
def sandbox(self) -> AsyncSandboxResource:
+ """Admin endpoints"""
return AsyncSandboxResource(self._client)
@cached_property
def functional_tests(self) -> AsyncFunctionalTestsResource:
+ """Admin endpoints"""
return AsyncFunctionalTestsResource(self._client)
@cached_property
def users(self) -> AsyncUsersResource:
+ """Admin endpoints"""
return AsyncUsersResource(self._client)
@cached_property
def chat_templates(self) -> AsyncChatTemplatesResource:
+ """Admin endpoints"""
return AsyncChatTemplatesResource(self._client)
@cached_property
def connector(self) -> AsyncConnectorResource:
+ """Admin endpoints"""
return AsyncConnectorResource(self._client)
@cached_property
@@ -177,41 +240,86 @@ def with_streaming_response(self) -> AsyncAdminResourceWithStreamingResponse:
"""
return AsyncAdminResourceWithStreamingResponse(self)
+ async def report_critical(
+ self,
+ *,
+ message: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._post(
+ "/admin/critical",
+ body=await async_maybe_transform(
+ {"message": message}, admin_report_critical_params.AdminReportCriticalParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
class AdminResourceWithRawResponse:
def __init__(self, admin: AdminResource) -> None:
self._admin = admin
+ self.report_critical = to_raw_response_wrapper(
+ admin.report_critical,
+ )
+
@cached_property
def teams(self) -> TeamsResourceWithRawResponse:
+ """Admin endpoints"""
return TeamsResourceWithRawResponse(self._admin.teams)
@cached_property
def dataset(self) -> DatasetResourceWithRawResponse:
+ """Admin endpoints"""
return DatasetResourceWithRawResponse(self._admin.dataset)
@cached_property
def jobs(self) -> JobsResourceWithRawResponse:
+ """Admin endpoints"""
return JobsResourceWithRawResponse(self._admin.jobs)
@cached_property
def sandbox(self) -> SandboxResourceWithRawResponse:
+ """Admin endpoints"""
return SandboxResourceWithRawResponse(self._admin.sandbox)
@cached_property
def functional_tests(self) -> FunctionalTestsResourceWithRawResponse:
+ """Admin endpoints"""
return FunctionalTestsResourceWithRawResponse(self._admin.functional_tests)
@cached_property
def users(self) -> UsersResourceWithRawResponse:
+ """Admin endpoints"""
return UsersResourceWithRawResponse(self._admin.users)
@cached_property
def chat_templates(self) -> ChatTemplatesResourceWithRawResponse:
+ """Admin endpoints"""
return ChatTemplatesResourceWithRawResponse(self._admin.chat_templates)
@cached_property
def connector(self) -> ConnectorResourceWithRawResponse:
+ """Admin endpoints"""
return ConnectorResourceWithRawResponse(self._admin.connector)
@@ -219,36 +327,48 @@ class AsyncAdminResourceWithRawResponse:
def __init__(self, admin: AsyncAdminResource) -> None:
self._admin = admin
+ self.report_critical = async_to_raw_response_wrapper(
+ admin.report_critical,
+ )
+
@cached_property
def teams(self) -> AsyncTeamsResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncTeamsResourceWithRawResponse(self._admin.teams)
@cached_property
def dataset(self) -> AsyncDatasetResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncDatasetResourceWithRawResponse(self._admin.dataset)
@cached_property
def jobs(self) -> AsyncJobsResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncJobsResourceWithRawResponse(self._admin.jobs)
@cached_property
def sandbox(self) -> AsyncSandboxResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncSandboxResourceWithRawResponse(self._admin.sandbox)
@cached_property
def functional_tests(self) -> AsyncFunctionalTestsResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncFunctionalTestsResourceWithRawResponse(self._admin.functional_tests)
@cached_property
def users(self) -> AsyncUsersResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncUsersResourceWithRawResponse(self._admin.users)
@cached_property
def chat_templates(self) -> AsyncChatTemplatesResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncChatTemplatesResourceWithRawResponse(self._admin.chat_templates)
@cached_property
def connector(self) -> AsyncConnectorResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncConnectorResourceWithRawResponse(self._admin.connector)
@@ -256,36 +376,48 @@ class AdminResourceWithStreamingResponse:
def __init__(self, admin: AdminResource) -> None:
self._admin = admin
+ self.report_critical = to_streamed_response_wrapper(
+ admin.report_critical,
+ )
+
@cached_property
def teams(self) -> TeamsResourceWithStreamingResponse:
+ """Admin endpoints"""
return TeamsResourceWithStreamingResponse(self._admin.teams)
@cached_property
def dataset(self) -> DatasetResourceWithStreamingResponse:
+ """Admin endpoints"""
return DatasetResourceWithStreamingResponse(self._admin.dataset)
@cached_property
def jobs(self) -> JobsResourceWithStreamingResponse:
+ """Admin endpoints"""
return JobsResourceWithStreamingResponse(self._admin.jobs)
@cached_property
def sandbox(self) -> SandboxResourceWithStreamingResponse:
+ """Admin endpoints"""
return SandboxResourceWithStreamingResponse(self._admin.sandbox)
@cached_property
def functional_tests(self) -> FunctionalTestsResourceWithStreamingResponse:
+ """Admin endpoints"""
return FunctionalTestsResourceWithStreamingResponse(self._admin.functional_tests)
@cached_property
def users(self) -> UsersResourceWithStreamingResponse:
+ """Admin endpoints"""
return UsersResourceWithStreamingResponse(self._admin.users)
@cached_property
def chat_templates(self) -> ChatTemplatesResourceWithStreamingResponse:
+ """Admin endpoints"""
return ChatTemplatesResourceWithStreamingResponse(self._admin.chat_templates)
@cached_property
def connector(self) -> ConnectorResourceWithStreamingResponse:
+ """Admin endpoints"""
return ConnectorResourceWithStreamingResponse(self._admin.connector)
@@ -293,34 +425,46 @@ class AsyncAdminResourceWithStreamingResponse:
def __init__(self, admin: AsyncAdminResource) -> None:
self._admin = admin
+ self.report_critical = async_to_streamed_response_wrapper(
+ admin.report_critical,
+ )
+
@cached_property
def teams(self) -> AsyncTeamsResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncTeamsResourceWithStreamingResponse(self._admin.teams)
@cached_property
def dataset(self) -> AsyncDatasetResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncDatasetResourceWithStreamingResponse(self._admin.dataset)
@cached_property
def jobs(self) -> AsyncJobsResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncJobsResourceWithStreamingResponse(self._admin.jobs)
@cached_property
def sandbox(self) -> AsyncSandboxResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncSandboxResourceWithStreamingResponse(self._admin.sandbox)
@cached_property
def functional_tests(self) -> AsyncFunctionalTestsResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncFunctionalTestsResourceWithStreamingResponse(self._admin.functional_tests)
@cached_property
def users(self) -> AsyncUsersResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncUsersResourceWithStreamingResponse(self._admin.users)
@cached_property
def chat_templates(self) -> AsyncChatTemplatesResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncChatTemplatesResourceWithStreamingResponse(self._admin.chat_templates)
@cached_property
def connector(self) -> AsyncConnectorResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncConnectorResourceWithStreamingResponse(self._admin.connector)
diff --git a/src/structify/resources/admin/chat_templates.py b/src/structify/resources/admin/chat_templates.py
index 6ecc7daed..618e4344f 100644
--- a/src/structify/resources/admin/chat_templates.py
+++ b/src/structify/resources/admin/chat_templates.py
@@ -2,12 +2,12 @@
from __future__ import annotations
-from typing import Optional
+from typing import Iterable, Optional
import httpx
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -19,12 +19,15 @@
from ...types.admin import chat_template_list_params, chat_template_create_params, chat_template_update_params
from ..._base_client import make_request_options
from ...types.chat_template import ChatTemplate
+from ...types.template_question_param import TemplateQuestionParam
from ...types.admin.chat_template_list_response import ChatTemplateListResponse
__all__ = ["ChatTemplatesResource", "AsyncChatTemplatesResource"]
class ChatTemplatesResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> ChatTemplatesResourceWithRawResponse:
"""
@@ -52,6 +55,7 @@ def create(
display_order: int,
image_url: str,
is_active: bool,
+ questions: Iterable[TemplateQuestionParam],
title: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -79,6 +83,7 @@ def create(
"display_order": display_order,
"image_url": image_url,
"is_active": is_active,
+ "questions": questions,
"title": title,
},
chat_template_create_params.ChatTemplateCreateParams,
@@ -97,6 +102,7 @@ def update(
display_order: Optional[int] | Omit = omit,
image_url: Optional[str] | Omit = omit,
is_active: Optional[bool] | Omit = omit,
+ questions: Optional[Iterable[TemplateQuestionParam]] | Omit = omit,
title: Optional[str] | Omit = omit,
updated_by: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -119,13 +125,14 @@ def update(
if not template_id:
raise ValueError(f"Expected a non-empty value for `template_id` but received {template_id!r}")
return self._patch(
- f"/admin/chat/templates/{template_id}",
+ path_template("/admin/chat/templates/{template_id}", template_id=template_id),
body=maybe_transform(
{
"description": description,
"display_order": display_order,
"image_url": image_url,
"is_active": is_active,
+ "questions": questions,
"title": title,
"updated_by": updated_by,
},
@@ -174,6 +181,8 @@ def list(
class AsyncChatTemplatesResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncChatTemplatesResourceWithRawResponse:
"""
@@ -201,6 +210,7 @@ async def create(
display_order: int,
image_url: str,
is_active: bool,
+ questions: Iterable[TemplateQuestionParam],
title: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -228,6 +238,7 @@ async def create(
"display_order": display_order,
"image_url": image_url,
"is_active": is_active,
+ "questions": questions,
"title": title,
},
chat_template_create_params.ChatTemplateCreateParams,
@@ -246,6 +257,7 @@ async def update(
display_order: Optional[int] | Omit = omit,
image_url: Optional[str] | Omit = omit,
is_active: Optional[bool] | Omit = omit,
+ questions: Optional[Iterable[TemplateQuestionParam]] | Omit = omit,
title: Optional[str] | Omit = omit,
updated_by: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -268,13 +280,14 @@ async def update(
if not template_id:
raise ValueError(f"Expected a non-empty value for `template_id` but received {template_id!r}")
return await self._patch(
- f"/admin/chat/templates/{template_id}",
+ path_template("/admin/chat/templates/{template_id}", template_id=template_id),
body=await async_maybe_transform(
{
"description": description,
"display_order": display_order,
"image_url": image_url,
"is_active": is_active,
+ "questions": questions,
"title": title,
"updated_by": updated_by,
},
diff --git a/src/structify/resources/admin/connector.py b/src/structify/resources/admin/connector.py
index 85e094b90..0c05e7d0b 100644
--- a/src/structify/resources/admin/connector.py
+++ b/src/structify/resources/admin/connector.py
@@ -2,12 +2,12 @@
from __future__ import annotations
-from typing import Iterable
+from typing import Iterable, Optional
import httpx
-from ..._types import Body, Query, Headers, NotGiven, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -16,15 +16,21 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ...types.admin import connector_clone_params
+from ...types.admin import DatahubIngestionType, connector_clone_params, connector_set_datahub_config_params
from ..._base_client import make_request_options
-from ...types.admin.clone_connectors_response import CloneConnectorsResponse
+from ...types.connector import Connector
+from ...types.datahub_secret_map_param import DatahubSecretMapParam
+from ...types.admin.datahub_ingestion_type import DatahubIngestionType
+from ...types.admin.connector_clone_response import ConnectorCloneResponse
from ...types.admin.clone_connector_item_param import CloneConnectorItemParam
+from ...types.admin.admin_list_connectors_response import AdminListConnectorsResponse
__all__ = ["ConnectorResource", "AsyncConnectorResource"]
class ConnectorResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> ConnectorResourceWithRawResponse:
"""
@@ -48,6 +54,8 @@ def clone(
self,
*,
connectors: Iterable[CloneConnectorItemParam],
+ source_membership_id: str,
+ source_team_id: str,
target_team_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -55,7 +63,7 @@ def clone(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> CloneConnectorsResponse:
+ ) -> ConnectorCloneResponse:
"""
Args:
extra_headers: Send extra headers
@@ -71,6 +79,8 @@ def clone(
body=maybe_transform(
{
"connectors": connectors,
+ "source_membership_id": source_membership_id,
+ "source_team_id": source_team_id,
"target_team_id": target_team_id,
},
connector_clone_params.ConnectorCloneParams,
@@ -78,11 +88,86 @@ def clone(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=CloneConnectorsResponse,
+ cast_to=ConnectorCloneResponse,
+ )
+
+ def list_team_connectors(
+ self,
+ team_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AdminListConnectorsResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not team_id:
+ raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
+ return self._get(
+ path_template("/admin/connector/team/{team_id}", team_id=team_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AdminListConnectorsResponse,
+ )
+
+ def set_datahub_config(
+ self,
+ *,
+ connector_id: str,
+ datahub_ingestion_type: Optional[DatahubIngestionType] | Omit = omit,
+ datahub_secret_map: Optional[DatahubSecretMapParam] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Connector:
+ """
+ Args:
+ datahub_secret_map: Maps DatahubIngestionKey to the name of the connector secret that holds the
+ value.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/admin/connector/datahub-config",
+ body=maybe_transform(
+ {
+ "connector_id": connector_id,
+ "datahub_ingestion_type": datahub_ingestion_type,
+ "datahub_secret_map": datahub_secret_map,
+ },
+ connector_set_datahub_config_params.ConnectorSetDatahubConfigParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Connector,
)
class AsyncConnectorResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncConnectorResourceWithRawResponse:
"""
@@ -106,6 +191,8 @@ async def clone(
self,
*,
connectors: Iterable[CloneConnectorItemParam],
+ source_membership_id: str,
+ source_team_id: str,
target_team_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -113,7 +200,7 @@ async def clone(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> CloneConnectorsResponse:
+ ) -> ConnectorCloneResponse:
"""
Args:
extra_headers: Send extra headers
@@ -129,6 +216,8 @@ async def clone(
body=await async_maybe_transform(
{
"connectors": connectors,
+ "source_membership_id": source_membership_id,
+ "source_team_id": source_team_id,
"target_team_id": target_team_id,
},
connector_clone_params.ConnectorCloneParams,
@@ -136,7 +225,80 @@ async def clone(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=CloneConnectorsResponse,
+ cast_to=ConnectorCloneResponse,
+ )
+
+ async def list_team_connectors(
+ self,
+ team_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AdminListConnectorsResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not team_id:
+ raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
+ return await self._get(
+ path_template("/admin/connector/team/{team_id}", team_id=team_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AdminListConnectorsResponse,
+ )
+
+ async def set_datahub_config(
+ self,
+ *,
+ connector_id: str,
+ datahub_ingestion_type: Optional[DatahubIngestionType] | Omit = omit,
+ datahub_secret_map: Optional[DatahubSecretMapParam] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Connector:
+ """
+ Args:
+ datahub_secret_map: Maps DatahubIngestionKey to the name of the connector secret that holds the
+ value.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/admin/connector/datahub-config",
+ body=await async_maybe_transform(
+ {
+ "connector_id": connector_id,
+ "datahub_ingestion_type": datahub_ingestion_type,
+ "datahub_secret_map": datahub_secret_map,
+ },
+ connector_set_datahub_config_params.ConnectorSetDatahubConfigParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Connector,
)
@@ -147,6 +309,12 @@ def __init__(self, connector: ConnectorResource) -> None:
self.clone = to_raw_response_wrapper(
connector.clone,
)
+ self.list_team_connectors = to_raw_response_wrapper(
+ connector.list_team_connectors,
+ )
+ self.set_datahub_config = to_raw_response_wrapper(
+ connector.set_datahub_config,
+ )
class AsyncConnectorResourceWithRawResponse:
@@ -156,6 +324,12 @@ def __init__(self, connector: AsyncConnectorResource) -> None:
self.clone = async_to_raw_response_wrapper(
connector.clone,
)
+ self.list_team_connectors = async_to_raw_response_wrapper(
+ connector.list_team_connectors,
+ )
+ self.set_datahub_config = async_to_raw_response_wrapper(
+ connector.set_datahub_config,
+ )
class ConnectorResourceWithStreamingResponse:
@@ -165,6 +339,12 @@ def __init__(self, connector: ConnectorResource) -> None:
self.clone = to_streamed_response_wrapper(
connector.clone,
)
+ self.list_team_connectors = to_streamed_response_wrapper(
+ connector.list_team_connectors,
+ )
+ self.set_datahub_config = to_streamed_response_wrapper(
+ connector.set_datahub_config,
+ )
class AsyncConnectorResourceWithStreamingResponse:
@@ -174,3 +354,9 @@ def __init__(self, connector: AsyncConnectorResource) -> None:
self.clone = async_to_streamed_response_wrapper(
connector.clone,
)
+ self.list_team_connectors = async_to_streamed_response_wrapper(
+ connector.list_team_connectors,
+ )
+ self.set_datahub_config = async_to_streamed_response_wrapper(
+ connector.set_datahub_config,
+ )
diff --git a/src/structify/resources/admin/dataset.py b/src/structify/resources/admin/dataset.py
index cf49a6553..aee899163 100644
--- a/src/structify/resources/admin/dataset.py
+++ b/src/structify/resources/admin/dataset.py
@@ -22,6 +22,8 @@
class DatasetResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> DatasetResourceWithRawResponse:
"""
@@ -78,6 +80,8 @@ def get_by_id(
class AsyncDatasetResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncDatasetResourceWithRawResponse:
"""
diff --git a/src/structify/resources/admin/functional_tests.py b/src/structify/resources/admin/functional_tests.py
index 2cec2b8d0..2497a10df 100644
--- a/src/structify/resources/admin/functional_tests.py
+++ b/src/structify/resources/admin/functional_tests.py
@@ -31,6 +31,8 @@
class FunctionalTestsResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> FunctionalTestsResourceWithRawResponse:
"""
@@ -268,6 +270,8 @@ def update_results(
class AsyncFunctionalTestsResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncFunctionalTestsResourceWithRawResponse:
"""
diff --git a/src/structify/resources/admin/jobs.py b/src/structify/resources/admin/jobs.py
index 63173942d..424b118db 100644
--- a/src/structify/resources/admin/jobs.py
+++ b/src/structify/resources/admin/jobs.py
@@ -2,8 +2,7 @@
from __future__ import annotations
-from typing import Union, Optional
-from datetime import datetime
+from typing import Optional
from typing_extensions import Literal
import httpx
@@ -19,15 +18,21 @@
async_to_streamed_response_wrapper,
)
from ...pagination import SyncJobsList, AsyncJobsList
-from ...types.admin import job_list_params, job_delete_params
+from ...types.admin import job_list_params, job_delete_params, job_kill_by_user_params, job_update_concurrency_params
from ..._base_client import AsyncPaginator, make_request_options
-from ...types.admin.admin_list_jobs_response import AdminListJobsResponse
+from ...types.admin.job_list_response import JobListResponse
+from ...types.admin.job_concurrency_response import JobConcurrencyResponse
+from ...types.admin.job_kill_by_user_response import JobKillByUserResponse
from ...types.admin.admin_delete_jobs_response import AdminDeleteJobsResponse
+from ...types.admin.job_running_stats_response import JobRunningStatsResponse
+from ...types.admin.job_update_concurrency_response import JobUpdateConcurrencyResponse
__all__ = ["JobsResource", "AsyncJobsResource"]
class JobsResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> JobsResourceWithRawResponse:
"""
@@ -50,41 +55,21 @@ def with_streaming_response(self) -> JobsResourceWithStreamingResponse:
def list(
self,
*,
- filter_test_users: bool,
- limit: int,
- offset: int,
- dataset_id: Optional[str] | Omit = omit,
- seeded_kg_search_term: Optional[str] | Omit = omit,
- since: Union[str, datetime, None] | Omit = omit,
+ job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]]
+ | Omit = omit,
+ limit: int | Omit = omit,
+ offset: int | Omit = omit,
status: Optional[Literal["Queued", "Running", "Completed", "Failed"]] | Omit = omit,
+ user_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncJobsList[AdminListJobsResponse]:
+ ) -> SyncJobsList[JobListResponse]:
"""
- This endpoint allows admins to list jobs from all users without user ownership
- restrictions. Optionally filter out test users (users with functional_test
- feature flag or debug permission).
-
Args:
- filter_test_users: Filter out jobs from test users (users with functional_test feature flag or
- debug permission)
-
- limit: Number of results to return
-
- offset: Pagination offset
-
- dataset_id: Dataset ID to optionally filter jobs by
-
- seeded_kg_search_term: Seeded kg search term
-
- since: List since a specific timestamp
-
- status: Status to optionally filter jobs by
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -95,7 +80,7 @@ def list(
"""
return self._get_api_list(
"/admin/jobs/list",
- page=SyncJobsList[AdminListJobsResponse],
+ page=SyncJobsList[JobListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -103,18 +88,16 @@ def list(
timeout=timeout,
query=maybe_transform(
{
- "filter_test_users": filter_test_users,
+ "job_type": job_type,
"limit": limit,
"offset": offset,
- "dataset_id": dataset_id,
- "seeded_kg_search_term": seeded_kg_search_term,
- "since": since,
"status": status,
+ "user_id": user_id,
},
job_list_params.JobListParams,
),
),
- model=AdminListJobsResponse,
+ model=JobListResponse,
)
def delete(
@@ -147,8 +130,123 @@ def delete(
cast_to=AdminDeleteJobsResponse,
)
+ def concurrency(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> JobConcurrencyResponse:
+ return self._get(
+ "/admin/jobs/concurrency_limits",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=JobConcurrencyResponse,
+ )
+
+ def kill_by_user(
+ self,
+ *,
+ user_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> JobKillByUserResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/admin/jobs/kill_by_user",
+ body=maybe_transform({"user_id": user_id}, job_kill_by_user_params.JobKillByUserParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=JobKillByUserResponse,
+ )
+
+ def running_stats(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> JobRunningStatsResponse:
+ return self._get(
+ "/admin/jobs/running_stats",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=JobRunningStatsResponse,
+ )
+
+ def update_concurrency(
+ self,
+ *,
+ max_connector_explore_jobs: Optional[int] | Omit = omit,
+ max_derive_jobs: Optional[int] | Omit = omit,
+ max_match_jobs: Optional[int] | Omit = omit,
+ max_pdf_jobs: Optional[int] | Omit = omit,
+ max_scrape_jobs: Optional[int] | Omit = omit,
+ max_total_jobs: Optional[int] | Omit = omit,
+ max_web_jobs: Optional[int] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> JobUpdateConcurrencyResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._put(
+ "/admin/jobs/concurrency_limits",
+ body=maybe_transform(
+ {
+ "max_connector_explore_jobs": max_connector_explore_jobs,
+ "max_derive_jobs": max_derive_jobs,
+ "max_match_jobs": max_match_jobs,
+ "max_pdf_jobs": max_pdf_jobs,
+ "max_scrape_jobs": max_scrape_jobs,
+ "max_total_jobs": max_total_jobs,
+ "max_web_jobs": max_web_jobs,
+ },
+ job_update_concurrency_params.JobUpdateConcurrencyParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=JobUpdateConcurrencyResponse,
+ )
+
class AsyncJobsResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncJobsResourceWithRawResponse:
"""
@@ -171,41 +269,21 @@ def with_streaming_response(self) -> AsyncJobsResourceWithStreamingResponse:
def list(
self,
*,
- filter_test_users: bool,
- limit: int,
- offset: int,
- dataset_id: Optional[str] | Omit = omit,
- seeded_kg_search_term: Optional[str] | Omit = omit,
- since: Union[str, datetime, None] | Omit = omit,
+ job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]]
+ | Omit = omit,
+ limit: int | Omit = omit,
+ offset: int | Omit = omit,
status: Optional[Literal["Queued", "Running", "Completed", "Failed"]] | Omit = omit,
+ user_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[AdminListJobsResponse, AsyncJobsList[AdminListJobsResponse]]:
+ ) -> AsyncPaginator[JobListResponse, AsyncJobsList[JobListResponse]]:
"""
- This endpoint allows admins to list jobs from all users without user ownership
- restrictions. Optionally filter out test users (users with functional_test
- feature flag or debug permission).
-
Args:
- filter_test_users: Filter out jobs from test users (users with functional_test feature flag or
- debug permission)
-
- limit: Number of results to return
-
- offset: Pagination offset
-
- dataset_id: Dataset ID to optionally filter jobs by
-
- seeded_kg_search_term: Seeded kg search term
-
- since: List since a specific timestamp
-
- status: Status to optionally filter jobs by
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -216,7 +294,7 @@ def list(
"""
return self._get_api_list(
"/admin/jobs/list",
- page=AsyncJobsList[AdminListJobsResponse],
+ page=AsyncJobsList[JobListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -224,18 +302,16 @@ def list(
timeout=timeout,
query=maybe_transform(
{
- "filter_test_users": filter_test_users,
+ "job_type": job_type,
"limit": limit,
"offset": offset,
- "dataset_id": dataset_id,
- "seeded_kg_search_term": seeded_kg_search_term,
- "since": since,
"status": status,
+ "user_id": user_id,
},
job_list_params.JobListParams,
),
),
- model=AdminListJobsResponse,
+ model=JobListResponse,
)
async def delete(
@@ -268,6 +344,119 @@ async def delete(
cast_to=AdminDeleteJobsResponse,
)
+ async def concurrency(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> JobConcurrencyResponse:
+ return await self._get(
+ "/admin/jobs/concurrency_limits",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=JobConcurrencyResponse,
+ )
+
+ async def kill_by_user(
+ self,
+ *,
+ user_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> JobKillByUserResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/admin/jobs/kill_by_user",
+ body=await async_maybe_transform({"user_id": user_id}, job_kill_by_user_params.JobKillByUserParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=JobKillByUserResponse,
+ )
+
+ async def running_stats(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> JobRunningStatsResponse:
+ return await self._get(
+ "/admin/jobs/running_stats",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=JobRunningStatsResponse,
+ )
+
+ async def update_concurrency(
+ self,
+ *,
+ max_connector_explore_jobs: Optional[int] | Omit = omit,
+ max_derive_jobs: Optional[int] | Omit = omit,
+ max_match_jobs: Optional[int] | Omit = omit,
+ max_pdf_jobs: Optional[int] | Omit = omit,
+ max_scrape_jobs: Optional[int] | Omit = omit,
+ max_total_jobs: Optional[int] | Omit = omit,
+ max_web_jobs: Optional[int] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> JobUpdateConcurrencyResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._put(
+ "/admin/jobs/concurrency_limits",
+ body=await async_maybe_transform(
+ {
+ "max_connector_explore_jobs": max_connector_explore_jobs,
+ "max_derive_jobs": max_derive_jobs,
+ "max_match_jobs": max_match_jobs,
+ "max_pdf_jobs": max_pdf_jobs,
+ "max_scrape_jobs": max_scrape_jobs,
+ "max_total_jobs": max_total_jobs,
+ "max_web_jobs": max_web_jobs,
+ },
+ job_update_concurrency_params.JobUpdateConcurrencyParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=JobUpdateConcurrencyResponse,
+ )
+
class JobsResourceWithRawResponse:
def __init__(self, jobs: JobsResource) -> None:
@@ -279,6 +468,18 @@ def __init__(self, jobs: JobsResource) -> None:
self.delete = to_raw_response_wrapper(
jobs.delete,
)
+ self.concurrency = to_raw_response_wrapper(
+ jobs.concurrency,
+ )
+ self.kill_by_user = to_raw_response_wrapper(
+ jobs.kill_by_user,
+ )
+ self.running_stats = to_raw_response_wrapper(
+ jobs.running_stats,
+ )
+ self.update_concurrency = to_raw_response_wrapper(
+ jobs.update_concurrency,
+ )
class AsyncJobsResourceWithRawResponse:
@@ -291,6 +492,18 @@ def __init__(self, jobs: AsyncJobsResource) -> None:
self.delete = async_to_raw_response_wrapper(
jobs.delete,
)
+ self.concurrency = async_to_raw_response_wrapper(
+ jobs.concurrency,
+ )
+ self.kill_by_user = async_to_raw_response_wrapper(
+ jobs.kill_by_user,
+ )
+ self.running_stats = async_to_raw_response_wrapper(
+ jobs.running_stats,
+ )
+ self.update_concurrency = async_to_raw_response_wrapper(
+ jobs.update_concurrency,
+ )
class JobsResourceWithStreamingResponse:
@@ -303,6 +516,18 @@ def __init__(self, jobs: JobsResource) -> None:
self.delete = to_streamed_response_wrapper(
jobs.delete,
)
+ self.concurrency = to_streamed_response_wrapper(
+ jobs.concurrency,
+ )
+ self.kill_by_user = to_streamed_response_wrapper(
+ jobs.kill_by_user,
+ )
+ self.running_stats = to_streamed_response_wrapper(
+ jobs.running_stats,
+ )
+ self.update_concurrency = to_streamed_response_wrapper(
+ jobs.update_concurrency,
+ )
class AsyncJobsResourceWithStreamingResponse:
@@ -315,3 +540,15 @@ def __init__(self, jobs: AsyncJobsResource) -> None:
self.delete = async_to_streamed_response_wrapper(
jobs.delete,
)
+ self.concurrency = async_to_streamed_response_wrapper(
+ jobs.concurrency,
+ )
+ self.kill_by_user = async_to_streamed_response_wrapper(
+ jobs.kill_by_user,
+ )
+ self.running_stats = async_to_streamed_response_wrapper(
+ jobs.running_stats,
+ )
+ self.update_concurrency = async_to_streamed_response_wrapper(
+ jobs.update_concurrency,
+ )
diff --git a/src/structify/resources/admin/sandbox.py b/src/structify/resources/admin/sandbox.py
index 413ec58f5..141c56569 100644
--- a/src/structify/resources/admin/sandbox.py
+++ b/src/structify/resources/admin/sandbox.py
@@ -25,6 +25,8 @@
class SandboxResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> SandboxResourceWithRawResponse:
"""
@@ -87,6 +89,8 @@ def list(
class AsyncSandboxResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncSandboxResourceWithRawResponse:
"""
diff --git a/src/structify/resources/admin/teams.py b/src/structify/resources/admin/teams.py
index dc9e4e015..5d6c1799c 100644
--- a/src/structify/resources/admin/teams.py
+++ b/src/structify/resources/admin/teams.py
@@ -10,7 +10,7 @@
from ...types import TeamRole
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -19,7 +19,6 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ...pagination import SyncJobsList, AsyncJobsList
from ...types.admin import (
team_list_params,
team_add_member_params,
@@ -31,13 +30,13 @@
team_create_subscription_params,
team_update_seats_override_params,
)
-from ..._base_client import AsyncPaginator, make_request_options
+from ..._base_client import make_request_options
from ...types.team_role import TeamRole
+from ...types.admin.team_list_response import TeamListResponse
from ...types.admin.extend_trial_response import ExtendTrialResponse
from ...types.admin.expire_grants_response import ExpireGrantsResponse
from ...types.admin.grant_credits_response import GrantCreditsResponse
from ...types.admin.admin_add_member_response import AdminAddMemberResponse
-from ...types.admin.admin_teams_list_response import AdminTeamsListResponse
from ...types.admin.admin_list_members_response import AdminListMembersResponse
from ...types.admin.admin_remove_member_response import AdminRemoveMemberResponse
from ...types.admin.cancel_subscription_response import CancelSubscriptionResponse
@@ -48,6 +47,8 @@
class TeamsResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> TeamsResourceWithRawResponse:
"""
@@ -72,17 +73,18 @@ def list(
*,
limit: Optional[int] | Omit = omit,
offset: Optional[int] | Omit = omit,
+ search: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncJobsList[AdminTeamsListResponse]:
+ ) -> TeamListResponse:
"""
Lists teams in the system along with their subscription information, credit
- grants, and member counts. Supports optional pagination via limit and offset
- query parameters.
+ grants, and member counts. Supports optional pagination via limit, offset, and
+ search query parameters.
Args:
extra_headers: Send extra headers
@@ -93,9 +95,8 @@ def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get_api_list(
+ return self._get(
"/admin/team/list",
- page=SyncJobsList[AdminTeamsListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -105,11 +106,12 @@ def list(
{
"limit": limit,
"offset": offset,
+ "search": search,
},
team_list_params.TeamListParams,
),
),
- model=AdminTeamsListResponse,
+ cast_to=TeamListResponse,
)
def add_member(
@@ -373,7 +375,7 @@ def list_members(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._get(
- f"/admin/team/{team_id}/members",
+ path_template("/admin/team/{team_id}/members", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -456,6 +458,8 @@ def update_seats_override(
class AsyncTeamsResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncTeamsResourceWithRawResponse:
"""
@@ -475,22 +479,23 @@ def with_streaming_response(self) -> AsyncTeamsResourceWithStreamingResponse:
"""
return AsyncTeamsResourceWithStreamingResponse(self)
- def list(
+ async def list(
self,
*,
limit: Optional[int] | Omit = omit,
offset: Optional[int] | Omit = omit,
+ search: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[AdminTeamsListResponse, AsyncJobsList[AdminTeamsListResponse]]:
+ ) -> TeamListResponse:
"""
Lists teams in the system along with their subscription information, credit
- grants, and member counts. Supports optional pagination via limit and offset
- query parameters.
+ grants, and member counts. Supports optional pagination via limit, offset, and
+ search query parameters.
Args:
extra_headers: Send extra headers
@@ -501,23 +506,23 @@ def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get_api_list(
+ return await self._get(
"/admin/team/list",
- page=AsyncJobsList[AdminTeamsListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- query=maybe_transform(
+ query=await async_maybe_transform(
{
"limit": limit,
"offset": offset,
+ "search": search,
},
team_list_params.TeamListParams,
),
),
- model=AdminTeamsListResponse,
+ cast_to=TeamListResponse,
)
async def add_member(
@@ -783,7 +788,7 @@ async def list_members(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._get(
- f"/admin/team/{team_id}/members",
+ path_template("/admin/team/{team_id}/members", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/structify/resources/admin/users.py b/src/structify/resources/admin/users.py
index 7b17e7ff6..8ff3d38cb 100644
--- a/src/structify/resources/admin/users.py
+++ b/src/structify/resources/admin/users.py
@@ -29,6 +29,8 @@
class UsersResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> UsersResourceWithRawResponse:
"""
@@ -206,6 +208,8 @@ def impersonate(
class AsyncUsersResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncUsersResourceWithRawResponse:
"""
diff --git a/src/structify/resources/chat.py b/src/structify/resources/chat.py
index 0c8d58d2f..1d29f7dbb 100644
--- a/src/structify/resources/chat.py
+++ b/src/structify/resources/chat.py
@@ -2,7 +2,9 @@
from __future__ import annotations
-from typing import Optional
+from typing import Union, Mapping, Optional, cast
+from datetime import datetime
+from typing_extensions import Literal
import httpx
@@ -11,39 +13,54 @@
ChatSessionRole,
chat_copy_params,
chat_load_files_params,
- chat_delete_files_params,
chat_list_sessions_params,
chat_add_git_commit_params,
chat_create_session_params,
chat_update_session_params,
+ chat_list_dashboards_params,
+ chat_simulate_prompt_params,
chat_add_collaborator_params,
+ chat_load_input_files_params,
chat_revert_to_commit_params,
chat_admin_issue_found_params,
+ chat_delete_input_file_params,
chat_update_visibility_params,
+ chat_upload_input_file_params,
chat_grant_admin_override_params,
chat_update_session_favorite_params,
chat_copy_node_output_by_code_hash_params,
)
-from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, FileTypes, SequenceNotStr, omit, not_given
+from .._utils import extract_files, path_template, maybe_transform, deepcopy_minimal, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
+ to_custom_raw_response_wrapper,
async_to_streamed_response_wrapper,
+ to_custom_streamed_response_wrapper,
+ async_to_custom_raw_response_wrapper,
+ async_to_custom_streamed_response_wrapper,
)
from .._base_client import make_request_options
-from ..types.chat_prompt import ChatPrompt
from ..types.chat_session import ChatSession
+from ..types.chat_template import ChatTemplate
from ..types.chat_visibility import ChatVisibility
+from ..types.chat_prompt_param import ChatPromptParam
from ..types.chat_session_role import ChatSessionRole
+from ..types.compress_chat_response import CompressChatResponse
from ..types.chat_load_files_response import ChatLoadFilesResponse
+from ..types.list_dashboards_response import ListDashboardsResponse
+from ..types.simulate_prompt_response import SimulatePromptResponse
from ..types.get_chat_session_response import GetChatSessionResponse
from ..types.get_dependencies_response import GetDependenciesResponse
from ..types.admin_issue_found_response import AdminIssueFoundResponse
-from ..types.chat_delete_files_response import ChatDeleteFilesResponse
from ..types.chat_session_with_messages import ChatSessionWithMessages
from ..types.update_visibility_response import UpdateVisibilityResponse
from ..types.admin_grant_access_response import AdminGrantAccessResponse
@@ -54,9 +71,14 @@
from ..types.chat_list_templates_response import ChatListTemplatesResponse
from ..types.create_chat_session_response import CreateChatSessionResponse
from ..types.delete_chat_session_response import DeleteChatSessionResponse
+from ..types.chat_list_input_files_response import ChatListInputFilesResponse
+from ..types.chat_load_input_files_response import ChatLoadInputFilesResponse
from ..types.chat_revert_to_commit_response import ChatRevertToCommitResponse
+from ..types.chat_delete_input_file_response import ChatDeleteInputFileResponse
from ..types.chat_get_partial_chats_response import ChatGetPartialChatsResponse
+from ..types.chat_upload_input_file_response import ChatUploadInputFileResponse
from ..types.chat_get_session_timeline_response import ChatGetSessionTimelineResponse
+from ..types.chat_copy_node_output_by_code_hash_response import ChatCopyNodeOutputByCodeHashResponse
__all__ = ["ChatResource", "AsyncChatResource"]
@@ -108,7 +130,7 @@ def add_collaborator(
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- f"/chat/sessions/{chat_id}/collaborators",
+ path_template("/chat/sessions/{chat_id}/collaborators", chat_id=chat_id),
body=maybe_transform(
{
"email": email,
@@ -151,7 +173,7 @@ def add_git_commit(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._post(
- f"/chat/sessions/{session_id}/commits",
+ path_template("/chat/sessions/{session_id}/commits", session_id=session_id),
body=maybe_transform({"commit_hash": commit_hash}, chat_add_git_commit_params.ChatAddGitCommitParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -159,20 +181,21 @@ def add_git_commit(
cast_to=ChatAddGitCommitResponse,
)
- def admin_get_chat_prompt(
+ def admin_issue_found(
self,
- session_id: str,
+ chat_id: str,
*,
+ message: str,
+ title: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ChatPrompt:
+ ) -> AdminIssueFoundResponse:
"""
- Get the actual chat prompt that the LLM will see on its next message (admin
- only)
+ Add an IssueFound tool call as an admin-only auto-review message
Args:
extra_headers: Send extra headers
@@ -183,32 +206,35 @@ def admin_get_chat_prompt(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not session_id:
- raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
- return self._get(
- f"/chat/sessions/{session_id}/admin/chat_prompt",
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return self._post(
+ path_template("/chat/sessions/{chat_id}/admin/issue_found", chat_id=chat_id),
+ body=maybe_transform(
+ {
+ "message": message,
+ "title": title,
+ },
+ chat_admin_issue_found_params.ChatAdminIssueFoundParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ChatPrompt,
+ cast_to=AdminIssueFoundResponse,
)
- def admin_issue_found(
+ def compress(
self,
- chat_id: str,
+ session_id: str,
*,
- message: str,
- title: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdminIssueFoundResponse:
+ ) -> CompressChatResponse:
"""
- Add an IssueFound tool call as an admin-only auto-review message
-
Args:
extra_headers: Send extra headers
@@ -218,21 +244,14 @@ def admin_issue_found(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not chat_id:
- raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ if not session_id:
+ raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._post(
- f"/chat/sessions/{chat_id}/admin/issue_found",
- body=maybe_transform(
- {
- "message": message,
- "title": title,
- },
- chat_admin_issue_found_params.ChatAdminIssueFoundParams,
- ),
+ path_template("/chat/sessions/{session_id}/compress", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdminIssueFoundResponse,
+ cast_to=CompressChatResponse,
)
def copy(
@@ -243,6 +262,7 @@ def copy(
team_id: str,
copy_inputs: bool | Omit = omit,
project_id: Optional[str] | Omit = omit,
+ template_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -271,6 +291,7 @@ def copy(
"team_id": team_id,
"copy_inputs": copy_inputs,
"project_id": project_id,
+ "template_id": template_id,
},
chat_copy_params.ChatCopyParams,
),
@@ -292,7 +313,7 @@ def copy_node_output_by_code_hash(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> str:
+ ) -> ChatCopyNodeOutputByCodeHashResponse:
"""
Args:
extra_headers: Send extra headers
@@ -306,7 +327,7 @@ def copy_node_output_by_code_hash(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._post(
- f"/chat/sessions/{session_id}/nodes/by_code_hash",
+ path_template("/chat/sessions/{session_id}/nodes/by_code_hash", session_id=session_id),
body=maybe_transform(
{
"code_md5_hash": code_md5_hash,
@@ -317,7 +338,7 @@ def copy_node_output_by_code_hash(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=str,
+ cast_to=ChatCopyNodeOutputByCodeHashResponse,
)
def create_session(
@@ -326,7 +347,6 @@ def create_session(
team_id: str,
config: Optional[chat_create_session_params.Config] | Omit = omit,
ephemeral: Optional[bool] | Omit = omit,
- initial_message: Optional[str] | Omit = omit,
project_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -356,7 +376,6 @@ def create_session(
"team_id": team_id,
"config": config,
"ephemeral": ephemeral,
- "initial_message": initial_message,
"project_id": project_id,
},
chat_create_session_params.ChatCreateSessionParams,
@@ -367,20 +386,20 @@ def create_session(
cast_to=CreateChatSessionResponse,
)
- def delete_files(
+ def delete_input_file(
self,
chat_id: str,
*,
- paths: SequenceNotStr[str],
+ filenames: SequenceNotStr[str],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ChatDeleteFilesResponse:
+ ) -> ChatDeleteInputFileResponse:
"""
- Delete files from a chat session's git repository
+ Delete input files from a chat session
Args:
extra_headers: Send extra headers
@@ -394,12 +413,12 @@ def delete_files(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return self._post(
- f"/chat/files/delete/{chat_id}",
- body=maybe_transform({"paths": paths}, chat_delete_files_params.ChatDeleteFilesParams),
+ path_template("/chat/input-files/delete/{chat_id}", chat_id=chat_id),
+ body=maybe_transform({"filenames": filenames}, chat_delete_input_file_params.ChatDeleteInputFileParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ChatDeleteFilesResponse,
+ cast_to=ChatDeleteInputFileResponse,
)
def delete_session(
@@ -428,7 +447,7 @@ def delete_session(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._delete(
- f"/chat/sessions/{session_id}",
+ path_template("/chat/sessions/{session_id}", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -461,7 +480,7 @@ def get_dependencies(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._get(
- f"/chat/sessions/{session_id}/dependencies",
+ path_template("/chat/sessions/{session_id}/dependencies", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -497,7 +516,7 @@ def get_git_commit(
if not commit_hash:
raise ValueError(f"Expected a non-empty value for `commit_hash` but received {commit_hash!r}")
return self._get(
- f"/chat/sessions/{chat_id}/commits/{commit_hash}",
+ path_template("/chat/sessions/{chat_id}/commits/{commit_hash}", chat_id=chat_id, commit_hash=commit_hash),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -530,7 +549,7 @@ def get_partial_chats(
if not chat_session_id:
raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
return self._get(
- f"/chat/{chat_session_id}/partial-chats",
+ path_template("/chat/{chat_session_id}/partial-chats", chat_session_id=chat_session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -563,7 +582,7 @@ def get_session(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._get(
- f"/chat/sessions/{session_id}",
+ path_template("/chat/sessions/{session_id}", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -596,13 +615,44 @@ def get_session_timeline(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._get(
- f"/chat/sessions/{session_id}/timeline",
+ path_template("/chat/sessions/{session_id}/timeline", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ChatGetSessionTimelineResponse,
)
+ def get_template(
+ self,
+ template_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ChatTemplate:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not template_id:
+ raise ValueError(f"Expected a non-empty value for `template_id` but received {template_id!r}")
+ return self._get(
+ path_template("/chat/templates/{template_id}", template_id=template_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatTemplate,
+ )
+
def grant_admin_override(
self,
chat_id: str,
@@ -633,7 +683,7 @@ def grant_admin_override(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return self._post(
- f"/chat/sessions/{chat_id}/admin_override",
+ path_template("/chat/sessions/{chat_id}/admin_override", chat_id=chat_id),
body=maybe_transform(
{
"duration_hours": duration_hours,
@@ -673,19 +723,98 @@ def list_collaborators(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return self._get(
- f"/chat/sessions/{chat_id}/collaborators",
+ path_template("/chat/sessions/{chat_id}/collaborators", chat_id=chat_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ListCollaboratorsResponse,
)
+ def list_dashboards(
+ self,
+ chat_id: str,
+ *,
+ commit_hash: Optional[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ListDashboardsResponse:
+ """
+ List dashboard specs for a chat session at a specific commit hash.
+
+ Args:
+ commit_hash: Optional commit hash. If omitted, uses the chat session latest commit.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return self._get(
+ path_template("/chat/sessions/{chat_id}/dashboards", chat_id=chat_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"commit_hash": commit_hash}, chat_list_dashboards_params.ChatListDashboardsParams
+ ),
+ ),
+ cast_to=ListDashboardsResponse,
+ )
+
+ def list_input_files(
+ self,
+ chat_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ChatListInputFilesResponse:
+ """
+ List input files for a chat session
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return self._get(
+ path_template("/chat/input-files/list/{chat_id}", chat_id=chat_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatListInputFilesResponse,
+ )
+
def list_sessions(
self,
*,
team_id: str,
+ connector_id: Optional[str] | Omit = omit,
limit: Optional[int] | Omit = omit,
+ offset: Optional[int] | Omit = omit,
project_id: Optional[str] | Omit = omit,
+ search: Optional[str] | Omit = omit,
+ tab: Optional[Literal["my_chats", "favorites", "shared", "team", "recents", "from_messaging"]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -700,10 +829,18 @@ def list_sessions(
Args:
team_id: Team ID to filter chat sessions
+ connector_id: Connector ID to filter chat sessions that use this connector
+
limit: Maximum number of sessions to return (default: 50)
+ offset: Number of sessions to skip (default: 0)
+
project_id: Project ID to filter chat sessions
+ search: Search query to filter sessions by name (case-insensitive)
+
+ tab: Tab filter for chat sessions
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -722,8 +859,12 @@ def list_sessions(
query=maybe_transform(
{
"team_id": team_id,
+ "connector_id": connector_id,
"limit": limit,
+ "offset": offset,
"project_id": project_id,
+ "search": search,
+ "tab": tab,
},
chat_list_sessions_params.ChatListSessionsParams,
),
@@ -789,6 +930,83 @@ def load_files(
cast_to=ChatLoadFilesResponse,
)
+ def load_input_file(
+ self,
+ filename: str,
+ *,
+ chat_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> BinaryAPIResponse:
+ """
+ Download a single input file by chat ID and filename
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ if not filename:
+ raise ValueError(f"Expected a non-empty value for `filename` but received {filename!r}")
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
+ return self._get(
+ path_template("/chat/input-files/download/{chat_id}/{filename}", chat_id=chat_id, filename=filename),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=BinaryAPIResponse,
+ )
+
+ def load_input_files(
+ self,
+ chat_id: str,
+ *,
+ since: Union[str, datetime, None] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ChatLoadInputFilesResponse:
+ """
+ Pass `since` query param (RFC 3339 timestamp) to only get files created/updated
+ after that time. The response includes `latest_timestamp` which can be passed as
+ `since` on the next call.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return self._get(
+ path_template("/chat/input-files/download-all/{chat_id}", chat_id=chat_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform({"since": since}, chat_load_input_files_params.ChatLoadInputFilesParams),
+ ),
+ cast_to=ChatLoadInputFilesResponse,
+ )
+
def make_permanent(
self,
session_id: str,
@@ -816,7 +1034,7 @@ def make_permanent(
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._patch(
- f"/chat/sessions/{session_id}/make-permanent",
+ path_template("/chat/sessions/{session_id}/make-permanent", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -851,7 +1069,7 @@ def remove_collaborator(
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/chat/sessions/{chat_id}/collaborators/{user_id}",
+ path_template("/chat/sessions/{chat_id}/collaborators/{user_id}", chat_id=chat_id, user_id=user_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -887,7 +1105,7 @@ def revert_to_commit(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._post(
- f"/chat/sessions/{session_id}/revert",
+ path_template("/chat/sessions/{session_id}/revert", session_id=session_id),
body=maybe_transform({"commit_hash": commit_hash}, chat_revert_to_commit_params.ChatRevertToCommitParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -895,10 +1113,46 @@ def revert_to_commit(
cast_to=ChatRevertToCommitResponse,
)
+ def simulate_prompt(
+ self,
+ chat_session_id: str,
+ *,
+ chat_prompt: ChatPromptParam,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SimulatePromptResponse:
+ """
+ any messages to the database.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_session_id:
+ raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
+ return self._post(
+ path_template("/chat/{chat_session_id}/simulate-prompt", chat_session_id=chat_session_id),
+ body=maybe_transform({"chat_prompt": chat_prompt}, chat_simulate_prompt_params.ChatSimulatePromptParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=SimulatePromptResponse,
+ )
+
def update_session(
self,
session_id: str,
*,
+ message_head: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
project_id: Optional[str] | Omit = omit,
skip_confirmations: Optional[bool] | Omit = omit,
@@ -922,9 +1176,10 @@ def update_session(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._patch(
- f"/chat/sessions/{session_id}",
+ path_template("/chat/sessions/{session_id}", session_id=session_id),
body=maybe_transform(
{
+ "message_head": message_head,
"name": name,
"project_id": project_id,
"skip_confirmations": skip_confirmations,
@@ -962,7 +1217,7 @@ def update_session_favorite(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._patch(
- f"/chat/sessions/{session_id}/favorite",
+ path_template("/chat/sessions/{session_id}/favorite", session_id=session_id),
body=maybe_transform(
{"is_favorite": is_favorite}, chat_update_session_favorite_params.ChatUpdateSessionFavoriteParams
),
@@ -999,7 +1254,7 @@ def update_visibility(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._put(
- f"/chat/sessions/{session_id}/visibility",
+ path_template("/chat/sessions/{session_id}/visibility", session_id=session_id),
body=maybe_transform({"visibility": visibility}, chat_update_visibility_params.ChatUpdateVisibilityParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -1007,6 +1262,56 @@ def update_visibility(
cast_to=UpdateVisibilityResponse,
)
+ def upload_input_file(
+ self,
+ chat_id: str,
+ *,
+ content: FileTypes,
+ content_type: str,
+ file_name: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ChatUploadInputFileResponse:
+ """
+ Upload an input file to a chat session's bucket storage
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ body = deepcopy_minimal(
+ {
+ "content": content,
+ "content_type": content_type,
+ "file_name": file_name,
+ }
+ )
+ files = extract_files(cast(Mapping[str, object], body), paths=[["content"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
+ return self._post(
+ path_template("/chat/input-files/upload/{chat_id}", chat_id=chat_id),
+ body=maybe_transform(body, chat_upload_input_file_params.ChatUploadInputFileParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatUploadInputFileResponse,
+ )
+
class AsyncChatResource(AsyncAPIResource):
@cached_property
@@ -1055,7 +1360,7 @@ async def add_collaborator(
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- f"/chat/sessions/{chat_id}/collaborators",
+ path_template("/chat/sessions/{chat_id}/collaborators", chat_id=chat_id),
body=await async_maybe_transform(
{
"email": email,
@@ -1098,7 +1403,7 @@ async def add_git_commit(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._post(
- f"/chat/sessions/{session_id}/commits",
+ path_template("/chat/sessions/{session_id}/commits", session_id=session_id),
body=await async_maybe_transform(
{"commit_hash": commit_hash}, chat_add_git_commit_params.ChatAddGitCommitParams
),
@@ -1108,20 +1413,21 @@ async def add_git_commit(
cast_to=ChatAddGitCommitResponse,
)
- async def admin_get_chat_prompt(
+ async def admin_issue_found(
self,
- session_id: str,
+ chat_id: str,
*,
+ message: str,
+ title: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ChatPrompt:
+ ) -> AdminIssueFoundResponse:
"""
- Get the actual chat prompt that the LLM will see on its next message (admin
- only)
+ Add an IssueFound tool call as an admin-only auto-review message
Args:
extra_headers: Send extra headers
@@ -1132,32 +1438,35 @@ async def admin_get_chat_prompt(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not session_id:
- raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
- return await self._get(
- f"/chat/sessions/{session_id}/admin/chat_prompt",
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return await self._post(
+ path_template("/chat/sessions/{chat_id}/admin/issue_found", chat_id=chat_id),
+ body=await async_maybe_transform(
+ {
+ "message": message,
+ "title": title,
+ },
+ chat_admin_issue_found_params.ChatAdminIssueFoundParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ChatPrompt,
+ cast_to=AdminIssueFoundResponse,
)
- async def admin_issue_found(
+ async def compress(
self,
- chat_id: str,
+ session_id: str,
*,
- message: str,
- title: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdminIssueFoundResponse:
+ ) -> CompressChatResponse:
"""
- Add an IssueFound tool call as an admin-only auto-review message
-
Args:
extra_headers: Send extra headers
@@ -1167,21 +1476,14 @@ async def admin_issue_found(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not chat_id:
- raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ if not session_id:
+ raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._post(
- f"/chat/sessions/{chat_id}/admin/issue_found",
- body=await async_maybe_transform(
- {
- "message": message,
- "title": title,
- },
- chat_admin_issue_found_params.ChatAdminIssueFoundParams,
- ),
+ path_template("/chat/sessions/{session_id}/compress", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdminIssueFoundResponse,
+ cast_to=CompressChatResponse,
)
async def copy(
@@ -1192,6 +1494,7 @@ async def copy(
team_id: str,
copy_inputs: bool | Omit = omit,
project_id: Optional[str] | Omit = omit,
+ template_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1220,6 +1523,7 @@ async def copy(
"team_id": team_id,
"copy_inputs": copy_inputs,
"project_id": project_id,
+ "template_id": template_id,
},
chat_copy_params.ChatCopyParams,
),
@@ -1241,7 +1545,7 @@ async def copy_node_output_by_code_hash(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> str:
+ ) -> ChatCopyNodeOutputByCodeHashResponse:
"""
Args:
extra_headers: Send extra headers
@@ -1255,7 +1559,7 @@ async def copy_node_output_by_code_hash(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._post(
- f"/chat/sessions/{session_id}/nodes/by_code_hash",
+ path_template("/chat/sessions/{session_id}/nodes/by_code_hash", session_id=session_id),
body=await async_maybe_transform(
{
"code_md5_hash": code_md5_hash,
@@ -1266,7 +1570,7 @@ async def copy_node_output_by_code_hash(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=str,
+ cast_to=ChatCopyNodeOutputByCodeHashResponse,
)
async def create_session(
@@ -1275,7 +1579,6 @@ async def create_session(
team_id: str,
config: Optional[chat_create_session_params.Config] | Omit = omit,
ephemeral: Optional[bool] | Omit = omit,
- initial_message: Optional[str] | Omit = omit,
project_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1305,7 +1608,6 @@ async def create_session(
"team_id": team_id,
"config": config,
"ephemeral": ephemeral,
- "initial_message": initial_message,
"project_id": project_id,
},
chat_create_session_params.ChatCreateSessionParams,
@@ -1316,20 +1618,20 @@ async def create_session(
cast_to=CreateChatSessionResponse,
)
- async def delete_files(
+ async def delete_input_file(
self,
chat_id: str,
*,
- paths: SequenceNotStr[str],
+ filenames: SequenceNotStr[str],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ChatDeleteFilesResponse:
+ ) -> ChatDeleteInputFileResponse:
"""
- Delete files from a chat session's git repository
+ Delete input files from a chat session
Args:
extra_headers: Send extra headers
@@ -1343,12 +1645,14 @@ async def delete_files(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return await self._post(
- f"/chat/files/delete/{chat_id}",
- body=await async_maybe_transform({"paths": paths}, chat_delete_files_params.ChatDeleteFilesParams),
+ path_template("/chat/input-files/delete/{chat_id}", chat_id=chat_id),
+ body=await async_maybe_transform(
+ {"filenames": filenames}, chat_delete_input_file_params.ChatDeleteInputFileParams
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ChatDeleteFilesResponse,
+ cast_to=ChatDeleteInputFileResponse,
)
async def delete_session(
@@ -1377,7 +1681,7 @@ async def delete_session(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._delete(
- f"/chat/sessions/{session_id}",
+ path_template("/chat/sessions/{session_id}", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1410,7 +1714,7 @@ async def get_dependencies(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._get(
- f"/chat/sessions/{session_id}/dependencies",
+ path_template("/chat/sessions/{session_id}/dependencies", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1446,7 +1750,7 @@ async def get_git_commit(
if not commit_hash:
raise ValueError(f"Expected a non-empty value for `commit_hash` but received {commit_hash!r}")
return await self._get(
- f"/chat/sessions/{chat_id}/commits/{commit_hash}",
+ path_template("/chat/sessions/{chat_id}/commits/{commit_hash}", chat_id=chat_id, commit_hash=commit_hash),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1479,7 +1783,7 @@ async def get_partial_chats(
if not chat_session_id:
raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
return await self._get(
- f"/chat/{chat_session_id}/partial-chats",
+ path_template("/chat/{chat_session_id}/partial-chats", chat_session_id=chat_session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1512,7 +1816,7 @@ async def get_session(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._get(
- f"/chat/sessions/{session_id}",
+ path_template("/chat/sessions/{session_id}", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1545,13 +1849,44 @@ async def get_session_timeline(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._get(
- f"/chat/sessions/{session_id}/timeline",
+ path_template("/chat/sessions/{session_id}/timeline", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ChatGetSessionTimelineResponse,
)
+ async def get_template(
+ self,
+ template_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ChatTemplate:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not template_id:
+ raise ValueError(f"Expected a non-empty value for `template_id` but received {template_id!r}")
+ return await self._get(
+ path_template("/chat/templates/{template_id}", template_id=template_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatTemplate,
+ )
+
async def grant_admin_override(
self,
chat_id: str,
@@ -1582,7 +1917,7 @@ async def grant_admin_override(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return await self._post(
- f"/chat/sessions/{chat_id}/admin_override",
+ path_template("/chat/sessions/{chat_id}/admin_override", chat_id=chat_id),
body=await async_maybe_transform(
{
"duration_hours": duration_hours,
@@ -1622,19 +1957,98 @@ async def list_collaborators(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return await self._get(
- f"/chat/sessions/{chat_id}/collaborators",
+ path_template("/chat/sessions/{chat_id}/collaborators", chat_id=chat_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ListCollaboratorsResponse,
)
+ async def list_dashboards(
+ self,
+ chat_id: str,
+ *,
+ commit_hash: Optional[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ListDashboardsResponse:
+ """
+ List dashboard specs for a chat session at a specific commit hash.
+
+ Args:
+ commit_hash: Optional commit hash. If omitted, uses the chat session latest commit.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return await self._get(
+ path_template("/chat/sessions/{chat_id}/dashboards", chat_id=chat_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"commit_hash": commit_hash}, chat_list_dashboards_params.ChatListDashboardsParams
+ ),
+ ),
+ cast_to=ListDashboardsResponse,
+ )
+
+ async def list_input_files(
+ self,
+ chat_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ChatListInputFilesResponse:
+ """
+ List input files for a chat session
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return await self._get(
+ path_template("/chat/input-files/list/{chat_id}", chat_id=chat_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatListInputFilesResponse,
+ )
+
async def list_sessions(
self,
*,
team_id: str,
+ connector_id: Optional[str] | Omit = omit,
limit: Optional[int] | Omit = omit,
+ offset: Optional[int] | Omit = omit,
project_id: Optional[str] | Omit = omit,
+ search: Optional[str] | Omit = omit,
+ tab: Optional[Literal["my_chats", "favorites", "shared", "team", "recents", "from_messaging"]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1649,10 +2063,18 @@ async def list_sessions(
Args:
team_id: Team ID to filter chat sessions
+ connector_id: Connector ID to filter chat sessions that use this connector
+
limit: Maximum number of sessions to return (default: 50)
+ offset: Number of sessions to skip (default: 0)
+
project_id: Project ID to filter chat sessions
+ search: Search query to filter sessions by name (case-insensitive)
+
+ tab: Tab filter for chat sessions
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1671,8 +2093,12 @@ async def list_sessions(
query=await async_maybe_transform(
{
"team_id": team_id,
+ "connector_id": connector_id,
"limit": limit,
+ "offset": offset,
"project_id": project_id,
+ "search": search,
+ "tab": tab,
},
chat_list_sessions_params.ChatListSessionsParams,
),
@@ -1738,6 +2164,85 @@ async def load_files(
cast_to=ChatLoadFilesResponse,
)
+ async def load_input_file(
+ self,
+ filename: str,
+ *,
+ chat_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncBinaryAPIResponse:
+ """
+ Download a single input file by chat ID and filename
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ if not filename:
+ raise ValueError(f"Expected a non-empty value for `filename` but received {filename!r}")
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
+ return await self._get(
+ path_template("/chat/input-files/download/{chat_id}/{filename}", chat_id=chat_id, filename=filename),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AsyncBinaryAPIResponse,
+ )
+
+ async def load_input_files(
+ self,
+ chat_id: str,
+ *,
+ since: Union[str, datetime, None] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ChatLoadInputFilesResponse:
+ """
+ Pass `since` query param (RFC 3339 timestamp) to only get files created/updated
+ after that time. The response includes `latest_timestamp` which can be passed as
+ `since` on the next call.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ return await self._get(
+ path_template("/chat/input-files/download-all/{chat_id}", chat_id=chat_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"since": since}, chat_load_input_files_params.ChatLoadInputFilesParams
+ ),
+ ),
+ cast_to=ChatLoadInputFilesResponse,
+ )
+
async def make_permanent(
self,
session_id: str,
@@ -1765,7 +2270,7 @@ async def make_permanent(
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._patch(
- f"/chat/sessions/{session_id}/make-permanent",
+ path_template("/chat/sessions/{session_id}/make-permanent", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1800,7 +2305,7 @@ async def remove_collaborator(
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/chat/sessions/{chat_id}/collaborators/{user_id}",
+ path_template("/chat/sessions/{chat_id}/collaborators/{user_id}", chat_id=chat_id, user_id=user_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1836,7 +2341,7 @@ async def revert_to_commit(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._post(
- f"/chat/sessions/{session_id}/revert",
+ path_template("/chat/sessions/{session_id}/revert", session_id=session_id),
body=await async_maybe_transform(
{"commit_hash": commit_hash}, chat_revert_to_commit_params.ChatRevertToCommitParams
),
@@ -1846,10 +2351,48 @@ async def revert_to_commit(
cast_to=ChatRevertToCommitResponse,
)
+ async def simulate_prompt(
+ self,
+ chat_session_id: str,
+ *,
+ chat_prompt: ChatPromptParam,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SimulatePromptResponse:
+ """
+ any messages to the database.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_session_id:
+ raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
+ return await self._post(
+ path_template("/chat/{chat_session_id}/simulate-prompt", chat_session_id=chat_session_id),
+ body=await async_maybe_transform(
+ {"chat_prompt": chat_prompt}, chat_simulate_prompt_params.ChatSimulatePromptParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=SimulatePromptResponse,
+ )
+
async def update_session(
self,
session_id: str,
*,
+ message_head: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
project_id: Optional[str] | Omit = omit,
skip_confirmations: Optional[bool] | Omit = omit,
@@ -1873,9 +2416,10 @@ async def update_session(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._patch(
- f"/chat/sessions/{session_id}",
+ path_template("/chat/sessions/{session_id}", session_id=session_id),
body=await async_maybe_transform(
{
+ "message_head": message_head,
"name": name,
"project_id": project_id,
"skip_confirmations": skip_confirmations,
@@ -1913,7 +2457,7 @@ async def update_session_favorite(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._patch(
- f"/chat/sessions/{session_id}/favorite",
+ path_template("/chat/sessions/{session_id}/favorite", session_id=session_id),
body=await async_maybe_transform(
{"is_favorite": is_favorite}, chat_update_session_favorite_params.ChatUpdateSessionFavoriteParams
),
@@ -1950,7 +2494,7 @@ async def update_visibility(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._put(
- f"/chat/sessions/{session_id}/visibility",
+ path_template("/chat/sessions/{session_id}/visibility", session_id=session_id),
body=await async_maybe_transform(
{"visibility": visibility}, chat_update_visibility_params.ChatUpdateVisibilityParams
),
@@ -1960,6 +2504,56 @@ async def update_visibility(
cast_to=UpdateVisibilityResponse,
)
+ async def upload_input_file(
+ self,
+ chat_id: str,
+ *,
+ content: FileTypes,
+ content_type: str,
+ file_name: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ChatUploadInputFileResponse:
+ """
+ Upload an input file to a chat session's bucket storage
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ body = deepcopy_minimal(
+ {
+ "content": content,
+ "content_type": content_type,
+ "file_name": file_name,
+ }
+ )
+ files = extract_files(cast(Mapping[str, object], body), paths=[["content"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
+ return await self._post(
+ path_template("/chat/input-files/upload/{chat_id}", chat_id=chat_id),
+ body=await async_maybe_transform(body, chat_upload_input_file_params.ChatUploadInputFileParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ChatUploadInputFileResponse,
+ )
+
class ChatResourceWithRawResponse:
def __init__(self, chat: ChatResource) -> None:
@@ -1971,12 +2565,12 @@ def __init__(self, chat: ChatResource) -> None:
self.add_git_commit = to_raw_response_wrapper(
chat.add_git_commit,
)
- self.admin_get_chat_prompt = to_raw_response_wrapper(
- chat.admin_get_chat_prompt,
- )
self.admin_issue_found = to_raw_response_wrapper(
chat.admin_issue_found,
)
+ self.compress = to_raw_response_wrapper(
+ chat.compress,
+ )
self.copy = to_raw_response_wrapper(
chat.copy,
)
@@ -1986,8 +2580,8 @@ def __init__(self, chat: ChatResource) -> None:
self.create_session = to_raw_response_wrapper(
chat.create_session,
)
- self.delete_files = to_raw_response_wrapper(
- chat.delete_files,
+ self.delete_input_file = to_raw_response_wrapper(
+ chat.delete_input_file,
)
self.delete_session = to_raw_response_wrapper(
chat.delete_session,
@@ -2007,12 +2601,21 @@ def __init__(self, chat: ChatResource) -> None:
self.get_session_timeline = to_raw_response_wrapper(
chat.get_session_timeline,
)
+ self.get_template = to_raw_response_wrapper(
+ chat.get_template,
+ )
self.grant_admin_override = to_raw_response_wrapper(
chat.grant_admin_override,
)
self.list_collaborators = to_raw_response_wrapper(
chat.list_collaborators,
)
+ self.list_dashboards = to_raw_response_wrapper(
+ chat.list_dashboards,
+ )
+ self.list_input_files = to_raw_response_wrapper(
+ chat.list_input_files,
+ )
self.list_sessions = to_raw_response_wrapper(
chat.list_sessions,
)
@@ -2022,6 +2625,13 @@ def __init__(self, chat: ChatResource) -> None:
self.load_files = to_raw_response_wrapper(
chat.load_files,
)
+ self.load_input_file = to_custom_raw_response_wrapper(
+ chat.load_input_file,
+ BinaryAPIResponse,
+ )
+ self.load_input_files = to_raw_response_wrapper(
+ chat.load_input_files,
+ )
self.make_permanent = to_raw_response_wrapper(
chat.make_permanent,
)
@@ -2031,6 +2641,9 @@ def __init__(self, chat: ChatResource) -> None:
self.revert_to_commit = to_raw_response_wrapper(
chat.revert_to_commit,
)
+ self.simulate_prompt = to_raw_response_wrapper(
+ chat.simulate_prompt,
+ )
self.update_session = to_raw_response_wrapper(
chat.update_session,
)
@@ -2040,6 +2653,9 @@ def __init__(self, chat: ChatResource) -> None:
self.update_visibility = to_raw_response_wrapper(
chat.update_visibility,
)
+ self.upload_input_file = to_raw_response_wrapper(
+ chat.upload_input_file,
+ )
class AsyncChatResourceWithRawResponse:
@@ -2052,12 +2668,12 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.add_git_commit = async_to_raw_response_wrapper(
chat.add_git_commit,
)
- self.admin_get_chat_prompt = async_to_raw_response_wrapper(
- chat.admin_get_chat_prompt,
- )
self.admin_issue_found = async_to_raw_response_wrapper(
chat.admin_issue_found,
)
+ self.compress = async_to_raw_response_wrapper(
+ chat.compress,
+ )
self.copy = async_to_raw_response_wrapper(
chat.copy,
)
@@ -2067,8 +2683,8 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.create_session = async_to_raw_response_wrapper(
chat.create_session,
)
- self.delete_files = async_to_raw_response_wrapper(
- chat.delete_files,
+ self.delete_input_file = async_to_raw_response_wrapper(
+ chat.delete_input_file,
)
self.delete_session = async_to_raw_response_wrapper(
chat.delete_session,
@@ -2088,12 +2704,21 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.get_session_timeline = async_to_raw_response_wrapper(
chat.get_session_timeline,
)
+ self.get_template = async_to_raw_response_wrapper(
+ chat.get_template,
+ )
self.grant_admin_override = async_to_raw_response_wrapper(
chat.grant_admin_override,
)
self.list_collaborators = async_to_raw_response_wrapper(
chat.list_collaborators,
)
+ self.list_dashboards = async_to_raw_response_wrapper(
+ chat.list_dashboards,
+ )
+ self.list_input_files = async_to_raw_response_wrapper(
+ chat.list_input_files,
+ )
self.list_sessions = async_to_raw_response_wrapper(
chat.list_sessions,
)
@@ -2103,6 +2728,13 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.load_files = async_to_raw_response_wrapper(
chat.load_files,
)
+ self.load_input_file = async_to_custom_raw_response_wrapper(
+ chat.load_input_file,
+ AsyncBinaryAPIResponse,
+ )
+ self.load_input_files = async_to_raw_response_wrapper(
+ chat.load_input_files,
+ )
self.make_permanent = async_to_raw_response_wrapper(
chat.make_permanent,
)
@@ -2112,6 +2744,9 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.revert_to_commit = async_to_raw_response_wrapper(
chat.revert_to_commit,
)
+ self.simulate_prompt = async_to_raw_response_wrapper(
+ chat.simulate_prompt,
+ )
self.update_session = async_to_raw_response_wrapper(
chat.update_session,
)
@@ -2121,6 +2756,9 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.update_visibility = async_to_raw_response_wrapper(
chat.update_visibility,
)
+ self.upload_input_file = async_to_raw_response_wrapper(
+ chat.upload_input_file,
+ )
class ChatResourceWithStreamingResponse:
@@ -2133,12 +2771,12 @@ def __init__(self, chat: ChatResource) -> None:
self.add_git_commit = to_streamed_response_wrapper(
chat.add_git_commit,
)
- self.admin_get_chat_prompt = to_streamed_response_wrapper(
- chat.admin_get_chat_prompt,
- )
self.admin_issue_found = to_streamed_response_wrapper(
chat.admin_issue_found,
)
+ self.compress = to_streamed_response_wrapper(
+ chat.compress,
+ )
self.copy = to_streamed_response_wrapper(
chat.copy,
)
@@ -2148,8 +2786,8 @@ def __init__(self, chat: ChatResource) -> None:
self.create_session = to_streamed_response_wrapper(
chat.create_session,
)
- self.delete_files = to_streamed_response_wrapper(
- chat.delete_files,
+ self.delete_input_file = to_streamed_response_wrapper(
+ chat.delete_input_file,
)
self.delete_session = to_streamed_response_wrapper(
chat.delete_session,
@@ -2169,12 +2807,21 @@ def __init__(self, chat: ChatResource) -> None:
self.get_session_timeline = to_streamed_response_wrapper(
chat.get_session_timeline,
)
+ self.get_template = to_streamed_response_wrapper(
+ chat.get_template,
+ )
self.grant_admin_override = to_streamed_response_wrapper(
chat.grant_admin_override,
)
self.list_collaborators = to_streamed_response_wrapper(
chat.list_collaborators,
)
+ self.list_dashboards = to_streamed_response_wrapper(
+ chat.list_dashboards,
+ )
+ self.list_input_files = to_streamed_response_wrapper(
+ chat.list_input_files,
+ )
self.list_sessions = to_streamed_response_wrapper(
chat.list_sessions,
)
@@ -2184,6 +2831,13 @@ def __init__(self, chat: ChatResource) -> None:
self.load_files = to_streamed_response_wrapper(
chat.load_files,
)
+ self.load_input_file = to_custom_streamed_response_wrapper(
+ chat.load_input_file,
+ StreamedBinaryAPIResponse,
+ )
+ self.load_input_files = to_streamed_response_wrapper(
+ chat.load_input_files,
+ )
self.make_permanent = to_streamed_response_wrapper(
chat.make_permanent,
)
@@ -2193,6 +2847,9 @@ def __init__(self, chat: ChatResource) -> None:
self.revert_to_commit = to_streamed_response_wrapper(
chat.revert_to_commit,
)
+ self.simulate_prompt = to_streamed_response_wrapper(
+ chat.simulate_prompt,
+ )
self.update_session = to_streamed_response_wrapper(
chat.update_session,
)
@@ -2202,6 +2859,9 @@ def __init__(self, chat: ChatResource) -> None:
self.update_visibility = to_streamed_response_wrapper(
chat.update_visibility,
)
+ self.upload_input_file = to_streamed_response_wrapper(
+ chat.upload_input_file,
+ )
class AsyncChatResourceWithStreamingResponse:
@@ -2214,12 +2874,12 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.add_git_commit = async_to_streamed_response_wrapper(
chat.add_git_commit,
)
- self.admin_get_chat_prompt = async_to_streamed_response_wrapper(
- chat.admin_get_chat_prompt,
- )
self.admin_issue_found = async_to_streamed_response_wrapper(
chat.admin_issue_found,
)
+ self.compress = async_to_streamed_response_wrapper(
+ chat.compress,
+ )
self.copy = async_to_streamed_response_wrapper(
chat.copy,
)
@@ -2229,8 +2889,8 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.create_session = async_to_streamed_response_wrapper(
chat.create_session,
)
- self.delete_files = async_to_streamed_response_wrapper(
- chat.delete_files,
+ self.delete_input_file = async_to_streamed_response_wrapper(
+ chat.delete_input_file,
)
self.delete_session = async_to_streamed_response_wrapper(
chat.delete_session,
@@ -2250,12 +2910,21 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.get_session_timeline = async_to_streamed_response_wrapper(
chat.get_session_timeline,
)
+ self.get_template = async_to_streamed_response_wrapper(
+ chat.get_template,
+ )
self.grant_admin_override = async_to_streamed_response_wrapper(
chat.grant_admin_override,
)
self.list_collaborators = async_to_streamed_response_wrapper(
chat.list_collaborators,
)
+ self.list_dashboards = async_to_streamed_response_wrapper(
+ chat.list_dashboards,
+ )
+ self.list_input_files = async_to_streamed_response_wrapper(
+ chat.list_input_files,
+ )
self.list_sessions = async_to_streamed_response_wrapper(
chat.list_sessions,
)
@@ -2265,6 +2934,13 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.load_files = async_to_streamed_response_wrapper(
chat.load_files,
)
+ self.load_input_file = async_to_custom_streamed_response_wrapper(
+ chat.load_input_file,
+ AsyncStreamedBinaryAPIResponse,
+ )
+ self.load_input_files = async_to_streamed_response_wrapper(
+ chat.load_input_files,
+ )
self.make_permanent = async_to_streamed_response_wrapper(
chat.make_permanent,
)
@@ -2274,6 +2950,9 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.revert_to_commit = async_to_streamed_response_wrapper(
chat.revert_to_commit,
)
+ self.simulate_prompt = async_to_streamed_response_wrapper(
+ chat.simulate_prompt,
+ )
self.update_session = async_to_streamed_response_wrapper(
chat.update_session,
)
@@ -2283,3 +2962,6 @@ def __init__(self, chat: AsyncChatResource) -> None:
self.update_visibility = async_to_streamed_response_wrapper(
chat.update_visibility,
)
+ self.upload_input_file = async_to_streamed_response_wrapper(
+ chat.upload_input_file,
+ )
diff --git a/src/structify/resources/code.py b/src/structify/resources/code.py
index 8db099382..016dfa512 100644
--- a/src/structify/resources/code.py
+++ b/src/structify/resources/code.py
@@ -6,9 +6,9 @@
import httpx
-from ..types import code_generate_code_params, code_interrupt_generation_params
+from ..types import code_generate_code_params, code_apply_manual_edit_params, code_interrupt_generation_params
from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -23,6 +23,8 @@
class CodeResource(SyncAPIResource):
+ """Code generation endpoints"""
+
@cached_property
def with_raw_response(self) -> CodeResourceWithRawResponse:
"""
@@ -42,6 +44,47 @@ def with_streaming_response(self) -> CodeResourceWithStreamingResponse:
"""
return CodeResourceWithStreamingResponse(self)
+ def apply_manual_edit(
+ self,
+ chat_id: str,
+ *,
+ code: str,
+ filename: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._post(
+ path_template("/code/apply-manual-edit/{chat_id}", chat_id=chat_id),
+ body=maybe_transform(
+ {
+ "code": code,
+ "filename": filename,
+ },
+ code_apply_manual_edit_params.CodeApplyManualEditParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
def generate_code(
self,
*,
@@ -138,6 +181,8 @@ def interrupt_generation(
class AsyncCodeResource(AsyncAPIResource):
+ """Code generation endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncCodeResourceWithRawResponse:
"""
@@ -157,6 +202,47 @@ def with_streaming_response(self) -> AsyncCodeResourceWithStreamingResponse:
"""
return AsyncCodeResourceWithStreamingResponse(self)
+ async def apply_manual_edit(
+ self,
+ chat_id: str,
+ *,
+ code: str,
+ filename: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not chat_id:
+ raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._post(
+ path_template("/code/apply-manual-edit/{chat_id}", chat_id=chat_id),
+ body=await async_maybe_transform(
+ {
+ "code": code,
+ "filename": filename,
+ },
+ code_apply_manual_edit_params.CodeApplyManualEditParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
async def generate_code(
self,
*,
@@ -256,6 +342,9 @@ class CodeResourceWithRawResponse:
def __init__(self, code: CodeResource) -> None:
self._code = code
+ self.apply_manual_edit = to_raw_response_wrapper(
+ code.apply_manual_edit,
+ )
self.generate_code = to_raw_response_wrapper(
code.generate_code,
)
@@ -268,6 +357,9 @@ class AsyncCodeResourceWithRawResponse:
def __init__(self, code: AsyncCodeResource) -> None:
self._code = code
+ self.apply_manual_edit = async_to_raw_response_wrapper(
+ code.apply_manual_edit,
+ )
self.generate_code = async_to_raw_response_wrapper(
code.generate_code,
)
@@ -280,6 +372,9 @@ class CodeResourceWithStreamingResponse:
def __init__(self, code: CodeResource) -> None:
self._code = code
+ self.apply_manual_edit = to_streamed_response_wrapper(
+ code.apply_manual_edit,
+ )
self.generate_code = to_streamed_response_wrapper(
code.generate_code,
)
@@ -292,6 +387,9 @@ class AsyncCodeResourceWithStreamingResponse:
def __init__(self, code: AsyncCodeResource) -> None:
self._code = code
+ self.apply_manual_edit = async_to_streamed_response_wrapper(
+ code.apply_manual_edit,
+ )
self.generate_code = async_to_streamed_response_wrapper(
code.generate_code,
)
diff --git a/src/structify/resources/connector_catalog/admin.py b/src/structify/resources/connector_catalog/admin.py
index 8469388d6..fb245fc6c 100644
--- a/src/structify/resources/connector_catalog/admin.py
+++ b/src/structify/resources/connector_catalog/admin.py
@@ -19,7 +19,7 @@
omit,
not_given,
)
-from ..._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
+from ..._utils import extract_files, path_template, maybe_transform, deepcopy_minimal, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -61,6 +61,8 @@
class AdminResource(SyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AdminResourceWithRawResponse:
"""
@@ -198,6 +200,8 @@ def create_catalog(
slug: str,
categories: SequenceNotStr[str] | Omit = omit,
description: Optional[str] | Omit = omit,
+ enterprise_only: bool | Omit = omit,
+ onboarding_priority: Optional[int] | Omit = omit,
priority: Optional[int] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -226,6 +230,8 @@ def create_catalog(
"slug": slug,
"categories": categories,
"description": description,
+ "enterprise_only": enterprise_only,
+ "onboarding_priority": onboarding_priority,
"priority": priority,
},
admin_create_catalog_params.AdminCreateCatalogParams,
@@ -357,7 +363,7 @@ def delete_catalog(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/admin/connector-catalog/{id}",
+ path_template("/admin/connector-catalog/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -391,7 +397,7 @@ def delete_credential_field(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/admin/connector-catalog/credential-fields/{id}",
+ path_template("/admin/connector-catalog/credential-fields/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -423,7 +429,7 @@ def delete_scope(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/admin/connector-catalog/scopes/{id}",
+ path_template("/admin/connector-catalog/scopes/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -514,7 +520,7 @@ def update_auth_method(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/admin/connector-catalog/auth-methods/{id}",
+ path_template("/admin/connector-catalog/auth-methods/{id}", id=id),
body=maybe_transform(
{
"is_active": is_active,
@@ -535,7 +541,9 @@ def update_catalog(
*,
categories: Optional[SequenceNotStr[str]] | Omit = omit,
description: Optional[str] | Omit = omit,
+ enterprise_only: Optional[bool] | Omit = omit,
name: Optional[str] | Omit = omit,
+ onboarding_priority: Optional[int] | Omit = omit,
priority: Optional[int] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -559,12 +567,14 @@ def update_catalog(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/admin/connector-catalog/{id}",
+ path_template("/admin/connector-catalog/{id}", id=id),
body=maybe_transform(
{
"categories": categories,
"description": description,
+ "enterprise_only": enterprise_only,
"name": name,
+ "onboarding_priority": onboarding_priority,
"priority": priority,
},
admin_update_catalog_params.AdminUpdateCatalogParams,
@@ -609,7 +619,7 @@ def update_credential_field(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/admin/connector-catalog/credential-fields/{id}",
+ path_template("/admin/connector-catalog/credential-fields/{id}", id=id),
body=maybe_transform(
{
"default_value": default_value,
@@ -657,7 +667,7 @@ def update_scope(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/admin/connector-catalog/scopes/{id}",
+ path_template("/admin/connector-catalog/scopes/{id}", id=id),
body=maybe_transform(
{
"is_recommended": is_recommended,
@@ -704,7 +714,7 @@ def upload_logo(
# multipart/form-data; boundary=---abc--
extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
return self._put(
- f"/admin/connector-catalog/{slug}/logo",
+ path_template("/admin/connector-catalog/{slug}/logo", slug=slug),
body=maybe_transform(body, admin_upload_logo_params.AdminUploadLogoParams),
files=files,
options=make_request_options(
@@ -715,6 +725,8 @@ def upload_logo(
class AsyncAdminResource(AsyncAPIResource):
+ """Admin endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncAdminResourceWithRawResponse:
"""
@@ -854,6 +866,8 @@ async def create_catalog(
slug: str,
categories: SequenceNotStr[str] | Omit = omit,
description: Optional[str] | Omit = omit,
+ enterprise_only: bool | Omit = omit,
+ onboarding_priority: Optional[int] | Omit = omit,
priority: Optional[int] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -882,6 +896,8 @@ async def create_catalog(
"slug": slug,
"categories": categories,
"description": description,
+ "enterprise_only": enterprise_only,
+ "onboarding_priority": onboarding_priority,
"priority": priority,
},
admin_create_catalog_params.AdminCreateCatalogParams,
@@ -1013,7 +1029,7 @@ async def delete_catalog(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/admin/connector-catalog/{id}",
+ path_template("/admin/connector-catalog/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1047,7 +1063,7 @@ async def delete_credential_field(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/admin/connector-catalog/credential-fields/{id}",
+ path_template("/admin/connector-catalog/credential-fields/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1079,7 +1095,7 @@ async def delete_scope(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/admin/connector-catalog/scopes/{id}",
+ path_template("/admin/connector-catalog/scopes/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1170,7 +1186,7 @@ async def update_auth_method(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/admin/connector-catalog/auth-methods/{id}",
+ path_template("/admin/connector-catalog/auth-methods/{id}", id=id),
body=await async_maybe_transform(
{
"is_active": is_active,
@@ -1191,7 +1207,9 @@ async def update_catalog(
*,
categories: Optional[SequenceNotStr[str]] | Omit = omit,
description: Optional[str] | Omit = omit,
+ enterprise_only: Optional[bool] | Omit = omit,
name: Optional[str] | Omit = omit,
+ onboarding_priority: Optional[int] | Omit = omit,
priority: Optional[int] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1215,12 +1233,14 @@ async def update_catalog(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/admin/connector-catalog/{id}",
+ path_template("/admin/connector-catalog/{id}", id=id),
body=await async_maybe_transform(
{
"categories": categories,
"description": description,
+ "enterprise_only": enterprise_only,
"name": name,
+ "onboarding_priority": onboarding_priority,
"priority": priority,
},
admin_update_catalog_params.AdminUpdateCatalogParams,
@@ -1265,7 +1285,7 @@ async def update_credential_field(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/admin/connector-catalog/credential-fields/{id}",
+ path_template("/admin/connector-catalog/credential-fields/{id}", id=id),
body=await async_maybe_transform(
{
"default_value": default_value,
@@ -1313,7 +1333,7 @@ async def update_scope(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/admin/connector-catalog/scopes/{id}",
+ path_template("/admin/connector-catalog/scopes/{id}", id=id),
body=await async_maybe_transform(
{
"is_recommended": is_recommended,
@@ -1360,7 +1380,7 @@ async def upload_logo(
# multipart/form-data; boundary=---abc--
extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
return await self._put(
- f"/admin/connector-catalog/{slug}/logo",
+ path_template("/admin/connector-catalog/{slug}/logo", slug=slug),
body=await async_maybe_transform(body, admin_upload_logo_params.AdminUploadLogoParams),
files=files,
options=make_request_options(
diff --git a/src/structify/resources/connector_catalog/connector_catalog.py b/src/structify/resources/connector_catalog/connector_catalog.py
index 955bd4e15..a549b5b1f 100644
--- a/src/structify/resources/connector_catalog/connector_catalog.py
+++ b/src/structify/resources/connector_catalog/connector_catalog.py
@@ -15,8 +15,8 @@
AsyncAdminResourceWithStreamingResponse,
)
from ...types import connector_catalog_list_params
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -43,6 +43,7 @@
class ConnectorCatalogResource(SyncAPIResource):
@cached_property
def admin(self) -> AdminResource:
+ """Admin endpoints"""
return AdminResource(self._client)
@cached_property
@@ -67,6 +68,7 @@ def with_streaming_response(self) -> ConnectorCatalogResourceWithStreamingRespon
def list(
self,
*,
+ categories: SequenceNotStr[str] | Omit = omit,
include_inactive: bool | Omit = omit,
limit: int | Omit = omit,
offset: int | Omit = omit,
@@ -82,6 +84,9 @@ def list(
List all connector catalog entries with their auth methods and logos
Args:
+ categories: Optional category filter (exact match against any element in the categories
+ array)
+
include_inactive: Include inactive auth methods (admin only)
search: Optional search query to filter by name, slug, or category (case-insensitive
@@ -104,6 +109,7 @@ def list(
timeout=timeout,
query=maybe_transform(
{
+ "categories": categories,
"include_inactive": include_inactive,
"limit": limit,
"offset": offset,
@@ -141,7 +147,7 @@ def get(
if not slug:
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
return self._get(
- f"/connector-catalog/{slug}",
+ path_template("/connector-catalog/{slug}", slug=slug),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -173,7 +179,7 @@ def get_logo(
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
return self._get(
- f"/connector-catalog/{slug}/logo",
+ path_template("/connector-catalog/{slug}/logo", slug=slug),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -184,6 +190,7 @@ def get_logo(
class AsyncConnectorCatalogResource(AsyncAPIResource):
@cached_property
def admin(self) -> AsyncAdminResource:
+ """Admin endpoints"""
return AsyncAdminResource(self._client)
@cached_property
@@ -208,6 +215,7 @@ def with_streaming_response(self) -> AsyncConnectorCatalogResourceWithStreamingR
async def list(
self,
*,
+ categories: SequenceNotStr[str] | Omit = omit,
include_inactive: bool | Omit = omit,
limit: int | Omit = omit,
offset: int | Omit = omit,
@@ -223,6 +231,9 @@ async def list(
List all connector catalog entries with their auth methods and logos
Args:
+ categories: Optional category filter (exact match against any element in the categories
+ array)
+
include_inactive: Include inactive auth methods (admin only)
search: Optional search query to filter by name, slug, or category (case-insensitive
@@ -245,6 +256,7 @@ async def list(
timeout=timeout,
query=await async_maybe_transform(
{
+ "categories": categories,
"include_inactive": include_inactive,
"limit": limit,
"offset": offset,
@@ -282,7 +294,7 @@ async def get(
if not slug:
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
return await self._get(
- f"/connector-catalog/{slug}",
+ path_template("/connector-catalog/{slug}", slug=slug),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -314,7 +326,7 @@ async def get_logo(
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
return await self._get(
- f"/connector-catalog/{slug}/logo",
+ path_template("/connector-catalog/{slug}/logo", slug=slug),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -339,6 +351,7 @@ def __init__(self, connector_catalog: ConnectorCatalogResource) -> None:
@cached_property
def admin(self) -> AdminResourceWithRawResponse:
+ """Admin endpoints"""
return AdminResourceWithRawResponse(self._connector_catalog.admin)
@@ -359,6 +372,7 @@ def __init__(self, connector_catalog: AsyncConnectorCatalogResource) -> None:
@cached_property
def admin(self) -> AsyncAdminResourceWithRawResponse:
+ """Admin endpoints"""
return AsyncAdminResourceWithRawResponse(self._connector_catalog.admin)
@@ -379,6 +393,7 @@ def __init__(self, connector_catalog: ConnectorCatalogResource) -> None:
@cached_property
def admin(self) -> AdminResourceWithStreamingResponse:
+ """Admin endpoints"""
return AdminResourceWithStreamingResponse(self._connector_catalog.admin)
@@ -399,4 +414,5 @@ def __init__(self, connector_catalog: AsyncConnectorCatalogResource) -> None:
@cached_property
def admin(self) -> AsyncAdminResourceWithStreamingResponse:
+ """Admin endpoints"""
return AsyncAdminResourceWithStreamingResponse(self._connector_catalog.admin)
diff --git a/src/structify/resources/connectors/connectors.py b/src/structify/resources/connectors/connectors.py
index 4b967eaf7..b169f12fb 100644
--- a/src/structify/resources/connectors/connectors.py
+++ b/src/structify/resources/connectors/connectors.py
@@ -2,12 +2,13 @@
from __future__ import annotations
-from typing import Any, Dict, Optional, cast
+from typing import Any, Dict, Mapping, Optional, cast
from typing_extensions import Literal, overload
import httpx
from ...types import (
+ ConnectorCategory,
connector_list_params,
connector_create_params,
connector_update_params,
@@ -19,18 +20,45 @@
connector_update_column_params,
connector_add_schema_object_params,
connector_get_explorer_chat_params,
- connector_list_with_snippets_params,
connector_delete_schema_object_params,
+ connector_upload_datahub_artifact_params,
+ connector_download_datahub_artifact_params,
+)
+from ..._types import (
+ Body,
+ Omit,
+ Query,
+ Headers,
+ NoneType,
+ NotGiven,
+ FileTypes,
+ SequenceNotStr,
+ omit,
+ not_given,
+)
+from ..._utils import (
+ extract_files,
+ path_template,
+ required_args,
+ maybe_transform,
+ deepcopy_minimal,
+ async_maybe_transform,
)
-from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import required_args, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
+ to_custom_raw_response_wrapper,
async_to_streamed_response_wrapper,
+ to_custom_streamed_response_wrapper,
+ async_to_custom_raw_response_wrapper,
+ async_to_custom_streamed_response_wrapper,
)
from ...pagination import SyncJobsList, AsyncJobsList
from .type_snippets import (
@@ -43,16 +71,22 @@
)
from ..._base_client import AsyncPaginator, make_request_options
from ...types.connector import Connector
+from ...types.exploration_run import ExplorationRun
+from ...types.connector_category import ConnectorCategory
+from ...types.exploration_progress import ExplorationProgress
from ...types.list_tables_response import ListTablesResponse
from ...types.update_table_response import UpdateTableResponse
from ...types.connector_get_response import ConnectorGetResponse
from ...types.connector_with_secrets import ConnectorWithSecrets
from ...types.explorer_chat_response import ExplorerChatResponse
-from ...types.explore_status_response import ExploreStatusResponse
from ...types.connector_store_response import ConnectorStoreResponse
+from ...types.datahub_secret_map_param import DatahubSecretMapParam
from ...types.exploration_runs_response import ExplorationRunsResponse
+from ...types.connector_explore_response import ConnectorExploreResponse
from ...types.connector_summaries_response import ConnectorSummariesResponse
+from ...types.connector_table_path_response import ConnectorTablePathResponse
from ...types.delete_schema_object_response import DeleteSchemaObjectResponse
+from ...types.connector_list_stores_response import ConnectorListStoresResponse
from ...types.connector_search_tables_response import ConnectorSearchTablesResponse
from ...types.connector_add_schema_object_response import ConnectorAddSchemaObjectResponse
from ...types.connector_list_with_snippets_response import ConnectorListWithSnippetsResponse
@@ -90,14 +124,8 @@ def create(
*,
known_connector_type: str,
name: str,
- team_id: str,
description: Optional[str] | Omit = omit,
nango_connection_id: Optional[str] | Omit = omit,
- nango_integration_id: Optional[str] | Omit = omit,
- pipedream_account_id: Optional[str] | Omit = omit,
- pipedream_external_id: Optional[str] | Omit = omit,
- pipedream_project_id: Optional[str] | Omit = omit,
- refresh_script: Optional[str] | Omit = omit,
secrets: Dict[str, str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -110,10 +138,6 @@ def create(
Args:
nango_connection_id: Nango connection ID for OAuth token management
- nango_integration_id: Nango integration ID (e.g., "linear", "slack")
-
- pipedream_external_id: Unique external ID for Pipedream routing (required for Pipedream connectors)
-
secrets: Optional secrets/environment variables for the connector
extra_headers: Send extra headers
@@ -130,14 +154,8 @@ def create(
{
"known_connector_type": known_connector_type,
"name": name,
- "team_id": team_id,
"description": description,
"nango_connection_id": nango_connection_id,
- "nango_integration_id": nango_integration_id,
- "pipedream_account_id": pipedream_account_id,
- "pipedream_external_id": pipedream_external_id,
- "pipedream_project_id": pipedream_project_id,
- "refresh_script": refresh_script,
"secrets": secrets,
},
connector_create_params.ConnectorCreateParams,
@@ -152,11 +170,20 @@ def update(
self,
connector_id: str,
*,
+ connector_category: Optional[ConnectorCategory] | Omit = omit,
+ datahub_ingestion_type: Optional[str] | Omit = omit,
+ datahub_secret_map: Optional[DatahubSecretMapParam] | Omit = omit,
+ datahub_urn: Optional[str] | Omit = omit,
description: Optional[str] | Omit = omit,
known_connector_type: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
- refresh_script: Optional[str] | Omit = omit,
+ nango_connection_id: Optional[str] | Omit = omit,
+ oauth_scopes: Optional[SequenceNotStr[Optional[str]]] | Omit = omit,
+ owner_user_id: Optional[str] | Omit = omit,
+ refresh_cron_schedule: Optional[str] | Omit = omit,
+ team_visibility: Optional[Literal["Team", "Private"]] | Omit = omit,
usage_snippet_override: Optional[str] | Omit = omit,
+ user_ids: Optional[SequenceNotStr[str]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -166,6 +193,9 @@ def update(
) -> None:
"""
Args:
+ datahub_secret_map: Maps DatahubIngestionKey to the name of the connector secret that holds the
+ value.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -178,14 +208,23 @@ def update(
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._patch(
- f"/connectors/{connector_id}",
+ path_template("/connectors/{connector_id}", connector_id=connector_id),
body=maybe_transform(
{
+ "connector_category": connector_category,
+ "datahub_ingestion_type": datahub_ingestion_type,
+ "datahub_secret_map": datahub_secret_map,
+ "datahub_urn": datahub_urn,
"description": description,
"known_connector_type": known_connector_type,
"name": name,
- "refresh_script": refresh_script,
+ "nango_connection_id": nango_connection_id,
+ "oauth_scopes": oauth_scopes,
+ "owner_user_id": owner_user_id,
+ "refresh_cron_schedule": refresh_cron_schedule,
+ "team_visibility": team_visibility,
"usage_snippet_override": usage_snippet_override,
+ "user_ids": user_ids,
},
connector_update_params.ConnectorUpdateParams,
),
@@ -198,7 +237,6 @@ def update(
def list(
self,
*,
- team_id: str,
limit: int | Omit = omit,
offset: int | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -210,8 +248,6 @@ def list(
) -> SyncJobsList[ConnectorWithSecrets]:
"""
Args:
- team_id: Team ID to list connectors for
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -230,7 +266,6 @@ def list(
timeout=timeout,
query=maybe_transform(
{
- "team_id": team_id,
"limit": limit,
"offset": offset,
},
@@ -265,7 +300,7 @@ def delete(
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/connectors/{connector_id}",
+ path_template("/connectors/{connector_id}", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -419,7 +454,7 @@ def add_schema_object(
return cast(
ConnectorAddSchemaObjectResponse,
self._post(
- f"/connectors/{connector_id}/schema_object",
+ path_template("/connectors/{connector_id}/schema_object", connector_id=connector_id),
body=maybe_transform(
{
"name": name,
@@ -470,7 +505,7 @@ def create_secret(
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- f"/connectors/{connector_id}/secrets",
+ path_template("/connectors/{connector_id}/secrets", connector_id=connector_id),
body=maybe_transform(
{
"secret_name": secret_name,
@@ -605,7 +640,7 @@ def delete_schema_object(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return self._delete(
- f"/connectors/{connector_id}/schema_object",
+ path_template("/connectors/{connector_id}/schema_object", connector_id=connector_id),
body=maybe_transform(
{
"id": id,
@@ -647,20 +682,67 @@ def delete_secret(
raise ValueError(f"Expected a non-empty value for `secret_name` but received {secret_name!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/connectors/{connector_id}/secrets/{secret_name}",
+ path_template(
+ "/connectors/{connector_id}/secrets/{secret_name}", connector_id=connector_id, secret_name=secret_name
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=NoneType,
)
+ def download_datahub_artifact(
+ self,
+ kind: str,
+ *,
+ connector_id: str,
+ exploration_run_id: Optional[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> BinaryAPIResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not connector_id:
+ raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
+ if not kind:
+ raise ValueError(f"Expected a non-empty value for `kind` but received {kind!r}")
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
+ return self._get(
+ path_template(
+ "/internal/connectors/{connector_id}/datahub-artifacts/{kind}", connector_id=connector_id, kind=kind
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"exploration_run_id": exploration_run_id},
+ connector_download_datahub_artifact_params.ConnectorDownloadDatahubArtifactParams,
+ ),
+ ),
+ cast_to=BinaryAPIResponse,
+ )
+
def explore(
self,
connector_id: str,
*,
database_id: Optional[str] | Omit = omit,
+ only_do_datahub: Optional[bool] | Omit = omit,
schema_id: Optional[str] | Omit = omit,
- stage: Optional[Literal["both", "ingestion", "annotation"]] | Omit = omit,
table_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -668,10 +750,10 @@ def explore(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
+ ) -> ConnectorExploreResponse:
"""
Args:
- stage: Which exploration stage to run
+ only_do_datahub: If true, run only DataHub ingestion without queuing Diego annotation jobs.
extra_headers: Send extra headers
@@ -683,14 +765,13 @@ def explore(
"""
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- f"/connectors/{connector_id}/explore",
+ path_template("/connectors/{connector_id}/explore", connector_id=connector_id),
body=maybe_transform(
{
"database_id": database_id,
+ "only_do_datahub": only_do_datahub,
"schema_id": schema_id,
- "stage": stage,
"table_id": table_id,
},
connector_explore_params.ConnectorExploreParams,
@@ -698,7 +779,7 @@ def explore(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=NoneType,
+ cast_to=ConnectorExploreResponse,
)
def get(
@@ -725,13 +806,44 @@ def get(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return self._get(
- f"/connectors/{connector_id}",
+ path_template("/connectors/{connector_id}", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConnectorGetResponse,
)
+ def get_active_exploration_run(
+ self,
+ connector_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[ExplorationRun]:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not connector_id:
+ raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
+ return self._get(
+ path_template("/connectors/{connector_id}/explore/active-run", connector_id=connector_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ExplorationRun,
+ )
+
def get_clarification_requests(
self,
connector_id: str,
@@ -758,27 +870,26 @@ def get_clarification_requests(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return self._get(
- f"/connectors/{connector_id}/clarification-requests",
+ path_template("/connectors/{connector_id}/clarification-requests", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConnectorGetClarificationRequestsResponse,
)
- def get_exploration_runs(
+ def get_exploration_run_progress(
self,
- connector_id: str,
+ run_id: str,
*,
+ connector_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ExplorationRunsResponse:
+ ) -> ExplorationProgress:
"""
- Get all exploration runs for a connector (requires debug permission)
-
Args:
extra_headers: Send extra headers
@@ -790,15 +901,19 @@ def get_exploration_runs(
"""
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
+ if not run_id:
+ raise ValueError(f"Expected a non-empty value for `run_id` but received {run_id!r}")
return self._get(
- f"/connectors/{connector_id}/explore/runs",
+ path_template(
+ "/connectors/{connector_id}/explore/runs/{run_id}/progress", connector_id=connector_id, run_id=run_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ExplorationRunsResponse,
+ cast_to=ExplorationProgress,
)
- def get_exploration_status(
+ def get_exploration_runs(
self,
connector_id: str,
*,
@@ -808,8 +923,10 @@ def get_exploration_status(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ExploreStatusResponse:
+ ) -> ExplorationRunsResponse:
"""
+ Get all exploration runs for a connector (requires debug permission)
+
Args:
extra_headers: Send extra headers
@@ -822,18 +939,21 @@ def get_exploration_status(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return self._get(
- f"/connectors/{connector_id}/explore/status",
+ path_template("/connectors/{connector_id}/explore/runs", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ExploreStatusResponse,
+ cast_to=ExplorationRunsResponse,
)
def get_explorer_chat(
self,
connector_id: str,
*,
- run_id: str,
+ database_id: Optional[str] | Omit = omit,
+ run_id: Optional[str] | Omit = omit,
+ schema_id: Optional[str] | Omit = omit,
+ table_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -842,12 +962,9 @@ def get_explorer_chat(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ExplorerChatResponse:
"""
- Returns chats for all phases (table discovery, column discovery for each table,
- etc.)
+ Optionally filter by run, database, schema, or table
Args:
- run_id: Exploration run ID (required)
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -859,14 +976,20 @@ def get_explorer_chat(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return self._get(
- f"/connectors/{connector_id}/explore/chat",
+ path_template("/connectors/{connector_id}/explore/chat", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
query=maybe_transform(
- {"run_id": run_id}, connector_get_explorer_chat_params.ConnectorGetExplorerChatParams
+ {
+ "database_id": database_id,
+ "run_id": run_id,
+ "schema_id": schema_id,
+ "table_id": table_id,
+ },
+ connector_get_explorer_chat_params.ConnectorGetExplorerChatParams,
),
),
cast_to=ExplorerChatResponse,
@@ -896,13 +1019,62 @@ def get_store(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return self._get(
- f"/connectors/{connector_id}/store",
+ path_template("/connectors/{connector_id}/store", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConnectorStoreResponse,
)
+ def get_table_path(
+ self,
+ table_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ConnectorTablePathResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not table_id:
+ raise ValueError(f"Expected a non-empty value for `table_id` but received {table_id!r}")
+ return self._get(
+ path_template("/connectors/tables/{table_id}/path", table_id=table_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConnectorTablePathResponse,
+ )
+
+ def list_stores(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ConnectorListStoresResponse:
+ return self._get(
+ "/connectors/stores",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConnectorListStoresResponse,
+ )
+
def list_tables(
self,
connector_id: str,
@@ -931,7 +1103,7 @@ def list_tables(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return self._get(
- f"/connectors/{connector_id}/tables",
+ path_template("/connectors/{connector_id}/tables", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -941,7 +1113,6 @@ def list_tables(
def list_with_snippets(
self,
*,
- team_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -949,28 +1120,10 @@ def list_with_snippets(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectorListWithSnippetsResponse:
- """
- Args:
- team_id: Team ID to list connectors for
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
return self._get(
"/connectors/with-snippets",
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {"team_id": team_id}, connector_list_with_snippets_params.ConnectorListWithSnippetsParams
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConnectorListWithSnippetsResponse,
)
@@ -1002,7 +1155,9 @@ def resolve_clarification(
raise ValueError(f"Expected a non-empty value for `clarification_id` but received {clarification_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._patch(
- f"/connectors/clarification-requests/{clarification_id}/resolve",
+ path_template(
+ "/connectors/clarification-requests/{clarification_id}/resolve", clarification_id=clarification_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1025,7 +1180,7 @@ def search_tables(
Args:
query: Search query string
- team_id: Team ID to search tables for
+ team_id: Team ID to scope table search
extra_headers: Send extra headers
@@ -1057,7 +1212,6 @@ def summaries(
self,
*,
connector_ids: SequenceNotStr[str],
- team_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1077,13 +1231,7 @@ def summaries(
"""
return self._post(
"/connectors/summaries",
- body=maybe_transform(
- {
- "connector_ids": connector_ids,
- "team_id": team_id,
- },
- connector_summaries_params.ConnectorSummariesParams,
- ),
+ body=maybe_transform({"connector_ids": connector_ids}, connector_summaries_params.ConnectorSummariesParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1118,7 +1266,7 @@ def update_column(
raise ValueError(f"Expected a non-empty value for `column_id` but received {column_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._patch(
- f"/connectors/columns/{column_id}",
+ path_template("/connectors/columns/{column_id}", column_id=column_id),
body=maybe_transform({"notes": notes}, connector_update_column_params.ConnectorUpdateColumnParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -1154,7 +1302,7 @@ def update_table(
if not table_id:
raise ValueError(f"Expected a non-empty value for `table_id` but received {table_id!r}")
return self._patch(
- f"/connectors/tables/{table_id}",
+ path_template("/connectors/tables/{table_id}", table_id=table_id),
body=maybe_transform(
{
"description": description,
@@ -1168,6 +1316,60 @@ def update_table(
cast_to=UpdateTableResponse,
)
+ def upload_datahub_artifact(
+ self,
+ kind: str,
+ *,
+ connector_id: str,
+ exploration_run_id: str,
+ file: FileTypes,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not connector_id:
+ raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
+ if not kind:
+ raise ValueError(f"Expected a non-empty value for `kind` but received {kind!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ body = deepcopy_minimal({"file": file})
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers["Content-Type"] = "multipart/form-data"
+ return self._put(
+ path_template(
+ "/internal/connectors/{connector_id}/datahub-artifacts/{kind}", connector_id=connector_id, kind=kind
+ ),
+ body=maybe_transform(body, connector_upload_datahub_artifact_params.ConnectorUploadDatahubArtifactParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"exploration_run_id": exploration_run_id},
+ connector_upload_datahub_artifact_params.ConnectorUploadDatahubArtifactParams,
+ ),
+ ),
+ cast_to=NoneType,
+ )
+
class AsyncConnectorsResource(AsyncAPIResource):
@cached_property
@@ -1198,14 +1400,8 @@ async def create(
*,
known_connector_type: str,
name: str,
- team_id: str,
description: Optional[str] | Omit = omit,
nango_connection_id: Optional[str] | Omit = omit,
- nango_integration_id: Optional[str] | Omit = omit,
- pipedream_account_id: Optional[str] | Omit = omit,
- pipedream_external_id: Optional[str] | Omit = omit,
- pipedream_project_id: Optional[str] | Omit = omit,
- refresh_script: Optional[str] | Omit = omit,
secrets: Dict[str, str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1218,10 +1414,6 @@ async def create(
Args:
nango_connection_id: Nango connection ID for OAuth token management
- nango_integration_id: Nango integration ID (e.g., "linear", "slack")
-
- pipedream_external_id: Unique external ID for Pipedream routing (required for Pipedream connectors)
-
secrets: Optional secrets/environment variables for the connector
extra_headers: Send extra headers
@@ -1238,14 +1430,8 @@ async def create(
{
"known_connector_type": known_connector_type,
"name": name,
- "team_id": team_id,
"description": description,
"nango_connection_id": nango_connection_id,
- "nango_integration_id": nango_integration_id,
- "pipedream_account_id": pipedream_account_id,
- "pipedream_external_id": pipedream_external_id,
- "pipedream_project_id": pipedream_project_id,
- "refresh_script": refresh_script,
"secrets": secrets,
},
connector_create_params.ConnectorCreateParams,
@@ -1260,11 +1446,20 @@ async def update(
self,
connector_id: str,
*,
+ connector_category: Optional[ConnectorCategory] | Omit = omit,
+ datahub_ingestion_type: Optional[str] | Omit = omit,
+ datahub_secret_map: Optional[DatahubSecretMapParam] | Omit = omit,
+ datahub_urn: Optional[str] | Omit = omit,
description: Optional[str] | Omit = omit,
known_connector_type: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
- refresh_script: Optional[str] | Omit = omit,
+ nango_connection_id: Optional[str] | Omit = omit,
+ oauth_scopes: Optional[SequenceNotStr[Optional[str]]] | Omit = omit,
+ owner_user_id: Optional[str] | Omit = omit,
+ refresh_cron_schedule: Optional[str] | Omit = omit,
+ team_visibility: Optional[Literal["Team", "Private"]] | Omit = omit,
usage_snippet_override: Optional[str] | Omit = omit,
+ user_ids: Optional[SequenceNotStr[str]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1274,6 +1469,9 @@ async def update(
) -> None:
"""
Args:
+ datahub_secret_map: Maps DatahubIngestionKey to the name of the connector secret that holds the
+ value.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1286,14 +1484,23 @@ async def update(
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._patch(
- f"/connectors/{connector_id}",
+ path_template("/connectors/{connector_id}", connector_id=connector_id),
body=await async_maybe_transform(
{
+ "connector_category": connector_category,
+ "datahub_ingestion_type": datahub_ingestion_type,
+ "datahub_secret_map": datahub_secret_map,
+ "datahub_urn": datahub_urn,
"description": description,
"known_connector_type": known_connector_type,
"name": name,
- "refresh_script": refresh_script,
+ "nango_connection_id": nango_connection_id,
+ "oauth_scopes": oauth_scopes,
+ "owner_user_id": owner_user_id,
+ "refresh_cron_schedule": refresh_cron_schedule,
+ "team_visibility": team_visibility,
"usage_snippet_override": usage_snippet_override,
+ "user_ids": user_ids,
},
connector_update_params.ConnectorUpdateParams,
),
@@ -1306,7 +1513,6 @@ async def update(
def list(
self,
*,
- team_id: str,
limit: int | Omit = omit,
offset: int | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -1318,8 +1524,6 @@ def list(
) -> AsyncPaginator[ConnectorWithSecrets, AsyncJobsList[ConnectorWithSecrets]]:
"""
Args:
- team_id: Team ID to list connectors for
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1338,7 +1542,6 @@ def list(
timeout=timeout,
query=maybe_transform(
{
- "team_id": team_id,
"limit": limit,
"offset": offset,
},
@@ -1373,7 +1576,7 @@ async def delete(
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/connectors/{connector_id}",
+ path_template("/connectors/{connector_id}", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1527,7 +1730,7 @@ async def add_schema_object(
return cast(
ConnectorAddSchemaObjectResponse,
await self._post(
- f"/connectors/{connector_id}/schema_object",
+ path_template("/connectors/{connector_id}/schema_object", connector_id=connector_id),
body=await async_maybe_transform(
{
"name": name,
@@ -1578,7 +1781,7 @@ async def create_secret(
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- f"/connectors/{connector_id}/secrets",
+ path_template("/connectors/{connector_id}/secrets", connector_id=connector_id),
body=await async_maybe_transform(
{
"secret_name": secret_name,
@@ -1713,7 +1916,7 @@ async def delete_schema_object(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return await self._delete(
- f"/connectors/{connector_id}/schema_object",
+ path_template("/connectors/{connector_id}/schema_object", connector_id=connector_id),
body=await async_maybe_transform(
{
"id": id,
@@ -1755,20 +1958,67 @@ async def delete_secret(
raise ValueError(f"Expected a non-empty value for `secret_name` but received {secret_name!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/connectors/{connector_id}/secrets/{secret_name}",
+ path_template(
+ "/connectors/{connector_id}/secrets/{secret_name}", connector_id=connector_id, secret_name=secret_name
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=NoneType,
)
+ async def download_datahub_artifact(
+ self,
+ kind: str,
+ *,
+ connector_id: str,
+ exploration_run_id: Optional[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncBinaryAPIResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not connector_id:
+ raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
+ if not kind:
+ raise ValueError(f"Expected a non-empty value for `kind` but received {kind!r}")
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
+ return await self._get(
+ path_template(
+ "/internal/connectors/{connector_id}/datahub-artifacts/{kind}", connector_id=connector_id, kind=kind
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"exploration_run_id": exploration_run_id},
+ connector_download_datahub_artifact_params.ConnectorDownloadDatahubArtifactParams,
+ ),
+ ),
+ cast_to=AsyncBinaryAPIResponse,
+ )
+
async def explore(
self,
connector_id: str,
*,
database_id: Optional[str] | Omit = omit,
+ only_do_datahub: Optional[bool] | Omit = omit,
schema_id: Optional[str] | Omit = omit,
- stage: Optional[Literal["both", "ingestion", "annotation"]] | Omit = omit,
table_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1776,10 +2026,10 @@ async def explore(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
+ ) -> ConnectorExploreResponse:
"""
Args:
- stage: Which exploration stage to run
+ only_do_datahub: If true, run only DataHub ingestion without queuing Diego annotation jobs.
extra_headers: Send extra headers
@@ -1791,14 +2041,13 @@ async def explore(
"""
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- f"/connectors/{connector_id}/explore",
+ path_template("/connectors/{connector_id}/explore", connector_id=connector_id),
body=await async_maybe_transform(
{
"database_id": database_id,
+ "only_do_datahub": only_do_datahub,
"schema_id": schema_id,
- "stage": stage,
"table_id": table_id,
},
connector_explore_params.ConnectorExploreParams,
@@ -1806,7 +2055,7 @@ async def explore(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=NoneType,
+ cast_to=ConnectorExploreResponse,
)
async def get(
@@ -1833,13 +2082,44 @@ async def get(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return await self._get(
- f"/connectors/{connector_id}",
+ path_template("/connectors/{connector_id}", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConnectorGetResponse,
)
+ async def get_active_exploration_run(
+ self,
+ connector_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[ExplorationRun]:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not connector_id:
+ raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
+ return await self._get(
+ path_template("/connectors/{connector_id}/explore/active-run", connector_id=connector_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ExplorationRun,
+ )
+
async def get_clarification_requests(
self,
connector_id: str,
@@ -1866,27 +2146,26 @@ async def get_clarification_requests(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return await self._get(
- f"/connectors/{connector_id}/clarification-requests",
+ path_template("/connectors/{connector_id}/clarification-requests", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConnectorGetClarificationRequestsResponse,
)
- async def get_exploration_runs(
+ async def get_exploration_run_progress(
self,
- connector_id: str,
+ run_id: str,
*,
+ connector_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ExplorationRunsResponse:
+ ) -> ExplorationProgress:
"""
- Get all exploration runs for a connector (requires debug permission)
-
Args:
extra_headers: Send extra headers
@@ -1898,15 +2177,19 @@ async def get_exploration_runs(
"""
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
+ if not run_id:
+ raise ValueError(f"Expected a non-empty value for `run_id` but received {run_id!r}")
return await self._get(
- f"/connectors/{connector_id}/explore/runs",
+ path_template(
+ "/connectors/{connector_id}/explore/runs/{run_id}/progress", connector_id=connector_id, run_id=run_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ExplorationRunsResponse,
+ cast_to=ExplorationProgress,
)
- async def get_exploration_status(
+ async def get_exploration_runs(
self,
connector_id: str,
*,
@@ -1916,8 +2199,10 @@ async def get_exploration_status(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> ExploreStatusResponse:
+ ) -> ExplorationRunsResponse:
"""
+ Get all exploration runs for a connector (requires debug permission)
+
Args:
extra_headers: Send extra headers
@@ -1930,18 +2215,21 @@ async def get_exploration_status(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return await self._get(
- f"/connectors/{connector_id}/explore/status",
+ path_template("/connectors/{connector_id}/explore/runs", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=ExploreStatusResponse,
+ cast_to=ExplorationRunsResponse,
)
async def get_explorer_chat(
self,
connector_id: str,
*,
- run_id: str,
+ database_id: Optional[str] | Omit = omit,
+ run_id: Optional[str] | Omit = omit,
+ schema_id: Optional[str] | Omit = omit,
+ table_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1950,12 +2238,9 @@ async def get_explorer_chat(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ExplorerChatResponse:
"""
- Returns chats for all phases (table discovery, column discovery for each table,
- etc.)
+ Optionally filter by run, database, schema, or table
Args:
- run_id: Exploration run ID (required)
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1967,14 +2252,20 @@ async def get_explorer_chat(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return await self._get(
- f"/connectors/{connector_id}/explore/chat",
+ path_template("/connectors/{connector_id}/explore/chat", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
query=await async_maybe_transform(
- {"run_id": run_id}, connector_get_explorer_chat_params.ConnectorGetExplorerChatParams
+ {
+ "database_id": database_id,
+ "run_id": run_id,
+ "schema_id": schema_id,
+ "table_id": table_id,
+ },
+ connector_get_explorer_chat_params.ConnectorGetExplorerChatParams,
),
),
cast_to=ExplorerChatResponse,
@@ -2004,13 +2295,62 @@ async def get_store(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return await self._get(
- f"/connectors/{connector_id}/store",
+ path_template("/connectors/{connector_id}/store", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConnectorStoreResponse,
)
+ async def get_table_path(
+ self,
+ table_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ConnectorTablePathResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not table_id:
+ raise ValueError(f"Expected a non-empty value for `table_id` but received {table_id!r}")
+ return await self._get(
+ path_template("/connectors/tables/{table_id}/path", table_id=table_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConnectorTablePathResponse,
+ )
+
+ async def list_stores(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ConnectorListStoresResponse:
+ return await self._get(
+ "/connectors/stores",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConnectorListStoresResponse,
+ )
+
async def list_tables(
self,
connector_id: str,
@@ -2039,7 +2379,7 @@ async def list_tables(
if not connector_id:
raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
return await self._get(
- f"/connectors/{connector_id}/tables",
+ path_template("/connectors/{connector_id}/tables", connector_id=connector_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -2049,7 +2389,6 @@ async def list_tables(
async def list_with_snippets(
self,
*,
- team_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -2057,28 +2396,10 @@ async def list_with_snippets(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectorListWithSnippetsResponse:
- """
- Args:
- team_id: Team ID to list connectors for
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
return await self._get(
"/connectors/with-snippets",
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {"team_id": team_id}, connector_list_with_snippets_params.ConnectorListWithSnippetsParams
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=ConnectorListWithSnippetsResponse,
)
@@ -2110,7 +2431,9 @@ async def resolve_clarification(
raise ValueError(f"Expected a non-empty value for `clarification_id` but received {clarification_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._patch(
- f"/connectors/clarification-requests/{clarification_id}/resolve",
+ path_template(
+ "/connectors/clarification-requests/{clarification_id}/resolve", clarification_id=clarification_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -2133,7 +2456,7 @@ async def search_tables(
Args:
query: Search query string
- team_id: Team ID to search tables for
+ team_id: Team ID to scope table search
extra_headers: Send extra headers
@@ -2165,7 +2488,6 @@ async def summaries(
self,
*,
connector_ids: SequenceNotStr[str],
- team_id: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -2186,11 +2508,7 @@ async def summaries(
return await self._post(
"/connectors/summaries",
body=await async_maybe_transform(
- {
- "connector_ids": connector_ids,
- "team_id": team_id,
- },
- connector_summaries_params.ConnectorSummariesParams,
+ {"connector_ids": connector_ids}, connector_summaries_params.ConnectorSummariesParams
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -2226,7 +2544,7 @@ async def update_column(
raise ValueError(f"Expected a non-empty value for `column_id` but received {column_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._patch(
- f"/connectors/columns/{column_id}",
+ path_template("/connectors/columns/{column_id}", column_id=column_id),
body=await async_maybe_transform(
{"notes": notes}, connector_update_column_params.ConnectorUpdateColumnParams
),
@@ -2264,7 +2582,7 @@ async def update_table(
if not table_id:
raise ValueError(f"Expected a non-empty value for `table_id` but received {table_id!r}")
return await self._patch(
- f"/connectors/tables/{table_id}",
+ path_template("/connectors/tables/{table_id}", table_id=table_id),
body=await async_maybe_transform(
{
"description": description,
@@ -2278,6 +2596,62 @@ async def update_table(
cast_to=UpdateTableResponse,
)
+ async def upload_datahub_artifact(
+ self,
+ kind: str,
+ *,
+ connector_id: str,
+ exploration_run_id: str,
+ file: FileTypes,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not connector_id:
+ raise ValueError(f"Expected a non-empty value for `connector_id` but received {connector_id!r}")
+ if not kind:
+ raise ValueError(f"Expected a non-empty value for `kind` but received {kind!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ body = deepcopy_minimal({"file": file})
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers["Content-Type"] = "multipart/form-data"
+ return await self._put(
+ path_template(
+ "/internal/connectors/{connector_id}/datahub-artifacts/{kind}", connector_id=connector_id, kind=kind
+ ),
+ body=await async_maybe_transform(
+ body, connector_upload_datahub_artifact_params.ConnectorUploadDatahubArtifactParams
+ ),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"exploration_run_id": exploration_run_id},
+ connector_upload_datahub_artifact_params.ConnectorUploadDatahubArtifactParams,
+ ),
+ ),
+ cast_to=NoneType,
+ )
+
class ConnectorsResourceWithRawResponse:
def __init__(self, connectors: ConnectorsResource) -> None:
@@ -2307,27 +2681,40 @@ def __init__(self, connectors: ConnectorsResource) -> None:
self.delete_secret = to_raw_response_wrapper(
connectors.delete_secret,
)
+ self.download_datahub_artifact = to_custom_raw_response_wrapper(
+ connectors.download_datahub_artifact,
+ BinaryAPIResponse,
+ )
self.explore = to_raw_response_wrapper(
connectors.explore,
)
self.get = to_raw_response_wrapper(
connectors.get,
)
+ self.get_active_exploration_run = to_raw_response_wrapper(
+ connectors.get_active_exploration_run,
+ )
self.get_clarification_requests = to_raw_response_wrapper(
connectors.get_clarification_requests,
)
+ self.get_exploration_run_progress = to_raw_response_wrapper(
+ connectors.get_exploration_run_progress,
+ )
self.get_exploration_runs = to_raw_response_wrapper(
connectors.get_exploration_runs,
)
- self.get_exploration_status = to_raw_response_wrapper(
- connectors.get_exploration_status,
- )
self.get_explorer_chat = to_raw_response_wrapper(
connectors.get_explorer_chat,
)
self.get_store = to_raw_response_wrapper(
connectors.get_store,
)
+ self.get_table_path = to_raw_response_wrapper(
+ connectors.get_table_path,
+ )
+ self.list_stores = to_raw_response_wrapper(
+ connectors.list_stores,
+ )
self.list_tables = to_raw_response_wrapper(
connectors.list_tables,
)
@@ -2349,6 +2736,9 @@ def __init__(self, connectors: ConnectorsResource) -> None:
self.update_table = to_raw_response_wrapper(
connectors.update_table,
)
+ self.upload_datahub_artifact = to_raw_response_wrapper(
+ connectors.upload_datahub_artifact,
+ )
@cached_property
def type_snippets(self) -> TypeSnippetsResourceWithRawResponse:
@@ -2383,27 +2773,40 @@ def __init__(self, connectors: AsyncConnectorsResource) -> None:
self.delete_secret = async_to_raw_response_wrapper(
connectors.delete_secret,
)
+ self.download_datahub_artifact = async_to_custom_raw_response_wrapper(
+ connectors.download_datahub_artifact,
+ AsyncBinaryAPIResponse,
+ )
self.explore = async_to_raw_response_wrapper(
connectors.explore,
)
self.get = async_to_raw_response_wrapper(
connectors.get,
)
+ self.get_active_exploration_run = async_to_raw_response_wrapper(
+ connectors.get_active_exploration_run,
+ )
self.get_clarification_requests = async_to_raw_response_wrapper(
connectors.get_clarification_requests,
)
+ self.get_exploration_run_progress = async_to_raw_response_wrapper(
+ connectors.get_exploration_run_progress,
+ )
self.get_exploration_runs = async_to_raw_response_wrapper(
connectors.get_exploration_runs,
)
- self.get_exploration_status = async_to_raw_response_wrapper(
- connectors.get_exploration_status,
- )
self.get_explorer_chat = async_to_raw_response_wrapper(
connectors.get_explorer_chat,
)
self.get_store = async_to_raw_response_wrapper(
connectors.get_store,
)
+ self.get_table_path = async_to_raw_response_wrapper(
+ connectors.get_table_path,
+ )
+ self.list_stores = async_to_raw_response_wrapper(
+ connectors.list_stores,
+ )
self.list_tables = async_to_raw_response_wrapper(
connectors.list_tables,
)
@@ -2425,6 +2828,9 @@ def __init__(self, connectors: AsyncConnectorsResource) -> None:
self.update_table = async_to_raw_response_wrapper(
connectors.update_table,
)
+ self.upload_datahub_artifact = async_to_raw_response_wrapper(
+ connectors.upload_datahub_artifact,
+ )
@cached_property
def type_snippets(self) -> AsyncTypeSnippetsResourceWithRawResponse:
@@ -2459,27 +2865,40 @@ def __init__(self, connectors: ConnectorsResource) -> None:
self.delete_secret = to_streamed_response_wrapper(
connectors.delete_secret,
)
+ self.download_datahub_artifact = to_custom_streamed_response_wrapper(
+ connectors.download_datahub_artifact,
+ StreamedBinaryAPIResponse,
+ )
self.explore = to_streamed_response_wrapper(
connectors.explore,
)
self.get = to_streamed_response_wrapper(
connectors.get,
)
+ self.get_active_exploration_run = to_streamed_response_wrapper(
+ connectors.get_active_exploration_run,
+ )
self.get_clarification_requests = to_streamed_response_wrapper(
connectors.get_clarification_requests,
)
+ self.get_exploration_run_progress = to_streamed_response_wrapper(
+ connectors.get_exploration_run_progress,
+ )
self.get_exploration_runs = to_streamed_response_wrapper(
connectors.get_exploration_runs,
)
- self.get_exploration_status = to_streamed_response_wrapper(
- connectors.get_exploration_status,
- )
self.get_explorer_chat = to_streamed_response_wrapper(
connectors.get_explorer_chat,
)
self.get_store = to_streamed_response_wrapper(
connectors.get_store,
)
+ self.get_table_path = to_streamed_response_wrapper(
+ connectors.get_table_path,
+ )
+ self.list_stores = to_streamed_response_wrapper(
+ connectors.list_stores,
+ )
self.list_tables = to_streamed_response_wrapper(
connectors.list_tables,
)
@@ -2501,6 +2920,9 @@ def __init__(self, connectors: ConnectorsResource) -> None:
self.update_table = to_streamed_response_wrapper(
connectors.update_table,
)
+ self.upload_datahub_artifact = to_streamed_response_wrapper(
+ connectors.upload_datahub_artifact,
+ )
@cached_property
def type_snippets(self) -> TypeSnippetsResourceWithStreamingResponse:
@@ -2535,27 +2957,40 @@ def __init__(self, connectors: AsyncConnectorsResource) -> None:
self.delete_secret = async_to_streamed_response_wrapper(
connectors.delete_secret,
)
+ self.download_datahub_artifact = async_to_custom_streamed_response_wrapper(
+ connectors.download_datahub_artifact,
+ AsyncStreamedBinaryAPIResponse,
+ )
self.explore = async_to_streamed_response_wrapper(
connectors.explore,
)
self.get = async_to_streamed_response_wrapper(
connectors.get,
)
+ self.get_active_exploration_run = async_to_streamed_response_wrapper(
+ connectors.get_active_exploration_run,
+ )
self.get_clarification_requests = async_to_streamed_response_wrapper(
connectors.get_clarification_requests,
)
+ self.get_exploration_run_progress = async_to_streamed_response_wrapper(
+ connectors.get_exploration_run_progress,
+ )
self.get_exploration_runs = async_to_streamed_response_wrapper(
connectors.get_exploration_runs,
)
- self.get_exploration_status = async_to_streamed_response_wrapper(
- connectors.get_exploration_status,
- )
self.get_explorer_chat = async_to_streamed_response_wrapper(
connectors.get_explorer_chat,
)
self.get_store = async_to_streamed_response_wrapper(
connectors.get_store,
)
+ self.get_table_path = async_to_streamed_response_wrapper(
+ connectors.get_table_path,
+ )
+ self.list_stores = async_to_streamed_response_wrapper(
+ connectors.list_stores,
+ )
self.list_tables = async_to_streamed_response_wrapper(
connectors.list_tables,
)
@@ -2577,6 +3012,9 @@ def __init__(self, connectors: AsyncConnectorsResource) -> None:
self.update_table = async_to_streamed_response_wrapper(
connectors.update_table,
)
+ self.upload_datahub_artifact = async_to_streamed_response_wrapper(
+ connectors.upload_datahub_artifact,
+ )
@cached_property
def type_snippets(self) -> AsyncTypeSnippetsResourceWithStreamingResponse:
diff --git a/src/structify/resources/connectors/type_snippets.py b/src/structify/resources/connectors/type_snippets.py
index 84a1b11a1..d7f8bb234 100644
--- a/src/structify/resources/connectors/type_snippets.py
+++ b/src/structify/resources/connectors/type_snippets.py
@@ -7,7 +7,7 @@
import httpx
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -68,7 +68,7 @@ def upsert(
if not connector_type:
raise ValueError(f"Expected a non-empty value for `connector_type` but received {connector_type!r}")
return self._put(
- f"/connector-type-snippets/{connector_type}",
+ path_template("/connector-type-snippets/{connector_type}", connector_type=connector_type),
body=maybe_transform({"usage_snippet": usage_snippet}, type_snippet_upsert_params.TypeSnippetUpsertParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -122,7 +122,7 @@ async def upsert(
if not connector_type:
raise ValueError(f"Expected a non-empty value for `connector_type` but received {connector_type!r}")
return await self._put(
- f"/connector-type-snippets/{connector_type}",
+ path_template("/connector-type-snippets/{connector_type}", connector_type=connector_type),
body=await async_maybe_transform(
{"usage_snippet": usage_snippet}, type_snippet_upsert_params.TypeSnippetUpsertParams
),
diff --git a/src/structify/resources/datasets/datasets.py b/src/structify/resources/datasets/datasets.py
index 3e122b78a..952b89283 100644
--- a/src/structify/resources/datasets/datasets.py
+++ b/src/structify/resources/datasets/datasets.py
@@ -64,6 +64,8 @@
class DatasetsResource(SyncAPIResource):
+ """Dataset management endpoints"""
+
@cached_property
def evaluate(self) -> EvaluateResource:
return EvaluateResource(self._client)
@@ -844,6 +846,8 @@ def view_tables_with_relationships(
class AsyncDatasetsResource(AsyncAPIResource):
+ """Dataset management endpoints"""
+
@cached_property
def evaluate(self) -> AsyncEvaluateResource:
return AsyncEvaluateResource(self._client)
diff --git a/src/structify/resources/jobs.py b/src/structify/resources/jobs.py
index 974ece2ed..4caf8e80b 100644
--- a/src/structify/resources/jobs.py
+++ b/src/structify/resources/jobs.py
@@ -12,7 +12,7 @@
from ..types import job_list_params, job_status_params
from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -23,12 +23,11 @@
)
from ..pagination import SyncJobsList, AsyncJobsList
from .._base_client import AsyncPaginator, make_request_options
+from ..types.job_get_response import JobGetResponse
from ..types.job_list_response import JobListResponse
from ..types.job_cancel_response import JobCancelResponse
from ..types.job_status_response import JobStatusResponse
from ..types.get_job_events_response import GetJobEventsResponse
-from ..types.job_get_scrapers_response import JobGetScrapersResponse
-from ..types.job_get_source_entities_response import JobGetSourceEntitiesResponse
__all__ = ["JobsResource", "AsyncJobsResource"]
@@ -57,7 +56,8 @@ def list(
self,
*,
dataset: Optional[str] | Omit = omit,
- job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore"]] | Omit = omit,
+ job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]]
+ | Omit = omit,
limit: int | Omit = omit,
node_id: Optional[str] | Omit = omit,
offset: int | Omit = omit,
@@ -146,14 +146,14 @@ def cancel(
if not uuid:
raise ValueError(f"Expected a non-empty value for `uuid` but received {uuid!r}")
return self._post(
- f"/jobs/cancel/{uuid}",
+ path_template("/jobs/cancel/{uuid}", uuid=uuid),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=JobCancelResponse,
)
- def get_events(
+ def get(
self,
job_id: str,
*,
@@ -163,7 +163,7 @@ def get_events(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> GetJobEventsResponse:
+ ) -> JobGetResponse:
"""
Args:
extra_headers: Send extra headers
@@ -177,47 +177,14 @@ def get_events(
if not job_id:
raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}")
return self._get(
- f"/jobs/{job_id}/events",
+ path_template("/jobs/get/{job_id}", job_id=job_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=GetJobEventsResponse,
+ cast_to=JobGetResponse,
)
- def get_scrapers(
- self,
- job_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> JobGetScrapersResponse:
- """
- Retrieve scrapers associated with a job from structify.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not job_id:
- raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}")
- return self._get(
- f"/jobs/get_scrapers/{job_id}",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=JobGetScrapersResponse,
- )
-
- def get_source_entities(
+ def get_events(
self,
job_id: str,
*,
@@ -227,10 +194,8 @@ def get_source_entities(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> JobGetSourceEntitiesResponse:
+ ) -> GetJobEventsResponse:
"""
- Get all source entities and their associated sources for a specific job
-
Args:
extra_headers: Send extra headers
@@ -243,11 +208,11 @@ def get_source_entities(
if not job_id:
raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}")
return self._get(
- f"/jobs/get_source_entities/{job_id}",
+ path_template("/jobs/{job_id}/events", job_id=job_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=JobGetSourceEntitiesResponse,
+ cast_to=GetJobEventsResponse,
)
def schedule(
@@ -410,7 +375,8 @@ def list(
self,
*,
dataset: Optional[str] | Omit = omit,
- job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore"]] | Omit = omit,
+ job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]]
+ | Omit = omit,
limit: int | Omit = omit,
node_id: Optional[str] | Omit = omit,
offset: int | Omit = omit,
@@ -499,45 +465,14 @@ async def cancel(
if not uuid:
raise ValueError(f"Expected a non-empty value for `uuid` but received {uuid!r}")
return await self._post(
- f"/jobs/cancel/{uuid}",
+ path_template("/jobs/cancel/{uuid}", uuid=uuid),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=JobCancelResponse,
)
- async def get_events(
- self,
- job_id: str,
- *,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> GetJobEventsResponse:
- """
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not job_id:
- raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}")
- return await self._get(
- f"/jobs/{job_id}/events",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=GetJobEventsResponse,
- )
-
- async def get_scrapers(
+ async def get(
self,
job_id: str,
*,
@@ -547,10 +482,8 @@ async def get_scrapers(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> JobGetScrapersResponse:
+ ) -> JobGetResponse:
"""
- Retrieve scrapers associated with a job from structify.
-
Args:
extra_headers: Send extra headers
@@ -563,14 +496,14 @@ async def get_scrapers(
if not job_id:
raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}")
return await self._get(
- f"/jobs/get_scrapers/{job_id}",
+ path_template("/jobs/get/{job_id}", job_id=job_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=JobGetScrapersResponse,
+ cast_to=JobGetResponse,
)
- async def get_source_entities(
+ async def get_events(
self,
job_id: str,
*,
@@ -580,10 +513,8 @@ async def get_source_entities(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> JobGetSourceEntitiesResponse:
+ ) -> GetJobEventsResponse:
"""
- Get all source entities and their associated sources for a specific job
-
Args:
extra_headers: Send extra headers
@@ -596,11 +527,11 @@ async def get_source_entities(
if not job_id:
raise ValueError(f"Expected a non-empty value for `job_id` but received {job_id!r}")
return await self._get(
- f"/jobs/get_source_entities/{job_id}",
+ path_template("/jobs/{job_id}/events", job_id=job_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=JobGetSourceEntitiesResponse,
+ cast_to=GetJobEventsResponse,
)
async def schedule(
@@ -682,15 +613,12 @@ def __init__(self, jobs: JobsResource) -> None:
self.cancel = to_raw_response_wrapper(
jobs.cancel,
)
+ self.get = to_raw_response_wrapper(
+ jobs.get,
+ )
self.get_events = to_raw_response_wrapper(
jobs.get_events,
)
- self.get_scrapers = to_raw_response_wrapper(
- jobs.get_scrapers,
- )
- self.get_source_entities = to_raw_response_wrapper(
- jobs.get_source_entities,
- )
self.schedule = to_raw_response_wrapper(
jobs.schedule,
)
@@ -712,15 +640,12 @@ def __init__(self, jobs: AsyncJobsResource) -> None:
self.cancel = async_to_raw_response_wrapper(
jobs.cancel,
)
+ self.get = async_to_raw_response_wrapper(
+ jobs.get,
+ )
self.get_events = async_to_raw_response_wrapper(
jobs.get_events,
)
- self.get_scrapers = async_to_raw_response_wrapper(
- jobs.get_scrapers,
- )
- self.get_source_entities = async_to_raw_response_wrapper(
- jobs.get_source_entities,
- )
self.schedule = async_to_raw_response_wrapper(
jobs.schedule,
)
@@ -739,15 +664,12 @@ def __init__(self, jobs: JobsResource) -> None:
self.cancel = to_streamed_response_wrapper(
jobs.cancel,
)
+ self.get = to_streamed_response_wrapper(
+ jobs.get,
+ )
self.get_events = to_streamed_response_wrapper(
jobs.get_events,
)
- self.get_scrapers = to_streamed_response_wrapper(
- jobs.get_scrapers,
- )
- self.get_source_entities = to_streamed_response_wrapper(
- jobs.get_source_entities,
- )
self.schedule = to_streamed_response_wrapper(
jobs.schedule,
)
@@ -769,15 +691,12 @@ def __init__(self, jobs: AsyncJobsResource) -> None:
self.cancel = async_to_streamed_response_wrapper(
jobs.cancel,
)
+ self.get = async_to_streamed_response_wrapper(
+ jobs.get,
+ )
self.get_events = async_to_streamed_response_wrapper(
jobs.get_events,
)
- self.get_scrapers = async_to_streamed_response_wrapper(
- jobs.get_scrapers,
- )
- self.get_source_entities = async_to_streamed_response_wrapper(
- jobs.get_source_entities,
- )
self.schedule = async_to_streamed_response_wrapper(
jobs.schedule,
)
diff --git a/src/structify/resources/polars.py b/src/structify/resources/polars.py
index 6ae6d9d38..3b6dd3c58 100644
--- a/src/structify/resources/polars.py
+++ b/src/structify/resources/polars.py
@@ -8,10 +8,12 @@
from typing import Any, Dict, List, Tuple, Literal, Optional, cast
from concurrent.futures import Future, ThreadPoolExecutor, as_completed
+import pypdf
import polars as pl
from tqdm import tqdm # type: ignore
from polars import LazyFrame
+from structify import Structify
from structify.types.entity_param import EntityParam
from structify.types.property_type_param import PropertyTypeParam
from structify.types.dataset_create_params import Relationship as CreateRelationshipParam
@@ -36,12 +38,13 @@
STRUCTIFY_JOB_ID_COLUMN = "structify_job_id"
-def _collect_entities_with_job_ids(entities: Any) -> List[Dict[str, Any]]:
- """Collect entity properties with their first job_id."""
+def _collect_entities_with_job_ids(client: Structify, dataset_name: str, table_name: str) -> List[Dict[str, Any]]:
+ """Collect entity properties with their job_id."""
+ entities = client.datasets.view_table(dataset=dataset_name, name=table_name)
results: List[Dict[str, Any]] = []
for entity in entities:
row: Dict[str, Any] = dict(entity.properties)
- row[STRUCTIFY_JOB_ID_COLUMN] = entity.job_ids[0] if entity.job_ids else None
+ row[STRUCTIFY_JOB_ID_COLUMN] = entity.job_id
results.append(row)
return results
@@ -239,14 +242,10 @@ def enhance_entity_property(
else:
property_names = f"{', '.join(property_list[:-1])}, and {property_list[-1]}"
with ThreadPoolExecutor(max_workers=MAX_PARALLEL_REQUESTS) as executor:
- futures: List[Future[None]] = []
- # Iterate through property name at the outer level for queueing so with large requests
- # we can skip later jobs if the earlier ones get extra properties.
- for property_name in property_list:
- futures += [
- executor.submit(enhance_entity_property, entity_id, entity_param, [property_name])
- for entity_id, entity_param in entity_id_to_entity.items()
- ]
+ futures: List[Future[None]] = [
+ executor.submit(enhance_entity_property, entity_id, entity_param, property_list)
+ for entity_id, entity_param in entity_id_to_entity.items()
+ ]
for future in tqdm(
as_completed(futures), total=len(futures), desc=f"Preparing enrichments for {property_names}"
):
@@ -255,9 +254,7 @@ def enhance_entity_property(
title = f"Enriching {property_names} for {dataframe_name}"
self._client.jobs.wait_for_jobs(dataset_name=dataset_name, title=title, node_id=node_id)
# 4. Collect the results with job_ids
- results = _collect_entities_with_job_ids(
- self._client.datasets.view_table(dataset=dataset_name, name=dataframe_name)
- )
+ results = _collect_entities_with_job_ids(self._client, dataset_name, dataframe_name)
# 5. Return the results
return pl.DataFrame(results, schema=expected_schema)
@@ -417,7 +414,7 @@ def enhance_relationship(entity_id: str) -> None:
prop_name if prop_name not in input_schema else f"{prop_name}_{target_table_name}"
) # If the column already exists in the input schema, we need to suffix it with the target table name
result_row[eff] = target_entity.properties.get(prop_name)
- result_row[STRUCTIFY_JOB_ID_COLUMN] = target_entity.job_ids[0] if target_entity.job_ids else None
+ result_row[STRUCTIFY_JOB_ID_COLUMN] = target_entity.job_id
result_rows.append(result_row)
# Handle source rows without relationships
@@ -590,9 +587,7 @@ def scrape_entity_property(entity_id: str) -> None:
self._client.jobs.wait_for_jobs(dataset_name=dataset_name, title=title, node_id=node_id)
# 4. Collect the results with job_id
- results = _collect_entities_with_job_ids(
- self._client.datasets.view_table(dataset=dataset_name, name=dataframe_name)
- )
+ results = _collect_entities_with_job_ids(self._client, dataset_name, dataframe_name)
# 5. Return the results
return pl.DataFrame(results, schema=expected_schema)
@@ -749,9 +744,7 @@ def scrape_entity(entity: Dict[str, Any]) -> None:
result_row: dict[str, Any] = {
**scraped_entity.properties,
url_column: related_entity.properties[url_column],
- STRUCTIFY_JOB_ID_COLUMN: scraped_entity.job_ids[0]
- if scraped_entity.job_ids
- else None,
+ STRUCTIFY_JOB_ID_COLUMN: scraped_entity.job_id,
}
result_rows.append(result_row)
offset += LIMIT
@@ -845,6 +838,24 @@ def structure_pdfs(
table_param = as_table_param(table_name, schema)
+ paths_df = document_paths.collect()
+
+ page_count_map: dict[str, int] = {}
+ if mode == "all_pages":
+ for pdf_path in paths_df[path_column].to_list():
+ if pdf_path is not None:
+ with open(pdf_path, "rb") as f:
+ pdf = pypdf.PdfReader(f)
+ page_count_map[pdf_path] = len(pdf.pages)
+ else:
+ for pdf_path in paths_df[path_column].to_list():
+ # TODO: this is a hack to note that we cost twice as much for single page mode
+ page_count_map[pdf_path] = 2
+
+ total_pages = sum(page_count_map.values())
+ if not request_cost_confirmation_if_needed(self._client, total_pages, "pdf"):
+ raise Exception(f"User cancelled PDF extraction for {table_name}")
+
# Create dataset for this PDF
dataset_name = f"structure_pdfs_{table_name}_{uuid.uuid4().hex}"
self._client.datasets.create(
@@ -865,7 +876,6 @@ def structure_pdfs(
"model must be in format 'provider.model_name' (e.g. 'bedrock.claude-sonnet-4-bedrock')"
)
- paths_df = document_paths.collect()
instructions_list: list[str | None] = []
if instructions is not None and not isinstance(instructions, str):
@@ -874,42 +884,50 @@ def structure_pdfs(
raise ValueError(f"instructions shape {instr_df.shape} != document_paths shape {paths_df.shape}")
instructions_list = cast(List[Optional[str]], instr_df[instr_df.columns[0]].to_list())
- # Request cost confirmation before dispatching costly PDF extraction jobs
- if not request_cost_confirmation_if_needed(self._client, paths_df.shape[0], "pdf"):
- raise Exception(f"User cancelled PDF extraction for {table_name}")
-
job_to_pdf_path: dict[str, str] = {}
# Process each PDF document
- def process_pdf(pdf_path: str, instructions: str | None) -> Tuple[List[str], str]:
+ def upload_pdf(pdf_path: str) -> None:
# Upload the PDF document
- unique_pdf_name = f"{uuid.uuid4().hex}.pdf"
with open(pdf_path, "rb") as pdf_file:
try:
self._client.documents.upload(
content=pdf_file,
file_type="PDF",
dataset=dataset_name,
- path=unique_pdf_name.encode(),
+ path=pdf_path.encode(),
)
except Exception as e:
if "Document already exists" not in str(e):
raise e
+ with ThreadPoolExecutor(max_workers=MAX_PARALLEL_REQUESTS) as executor:
+ upload_futures: List[Future[None]] = []
+ for pdf_path in paths_df[path_column].to_list():
+ if isinstance(pdf_path, str):
+ upload_futures.append(executor.submit(upload_pdf, pdf_path))
+ for future in tqdm(as_completed(upload_futures), total=len(upload_futures), desc="Uploading PDFs"):
+ future.result()
+
+ def structure_pdf(pdf_path: str, instructions: str | None) -> Tuple[List[str], str]:
+ pages: List[int] | None = None
+ if mode == "all_pages":
+ pages = list(range(page_count_map[pdf_path]))
+
job_ids = self._client.structure.pdf(
dataset=dataset_name,
- path=unique_pdf_name,
+ path=pdf_path,
node_id=node_id,
instructions=instructions,
- mode="Single" if mode == "single" else "Batch",
model=model,
+ pages=pages,
).job_ids
return job_ids, pdf_path
with ThreadPoolExecutor(max_workers=MAX_PARALLEL_REQUESTS) as executor:
futures: List[Future[Tuple[List[str], str]]] = []
for i in range(paths_df.shape[0]):
- path: str | None = paths_df[path_column][i]
+ path = paths_df[path_column][i]
pdf_instructions: str | None = None
if isinstance(instructions, str):
pdf_instructions = instructions
@@ -917,21 +935,21 @@ def process_pdf(pdf_path: str, instructions: str | None) -> Tuple[List[str], str
pdf_instructions = instructions_list[i]
if pdf_instructions is None and conditioning:
pdf_instructions = conditioning
- if path is not None:
- futures.append(executor.submit(process_pdf, path, pdf_instructions))
- for future in tqdm(as_completed(futures), total=len(futures), desc="Preparing PDFs"):
+ if isinstance(path, str):
+ futures.append(executor.submit(structure_pdf, path, pdf_instructions))
+ for future in tqdm(as_completed(futures), total=len(futures), desc="Submitting PDFs for parsing"):
job_ids, pdf_path = future.result()
for job_id in job_ids:
job_to_pdf_path[job_id] = pdf_path
# Wait for all PDF processing jobs to complete
- self._client.jobs.wait_for_jobs(dataset_name=dataset_name, title=f"Parsing PDFs", node_id=node_id)
+ self._client.jobs.wait_for_jobs(dataset_name=dataset_name, title=f"Parsing PDF pages", node_id=node_id)
# Get all of the entities with their job_ids
entities = self._client.datasets.view_table(dataset=dataset_name, name=table_name)
structured_results: List[Dict[str, Any]] = []
for entity in entities:
- job_id = entity.job_ids[0] if entity.job_ids else None
+ job_id = entity.job_id
result_row: Dict[str, Any] = {
**entity.properties,
path_column: job_to_pdf_path.get(job_id) if job_id else None,
@@ -1032,9 +1050,7 @@ def tag(
# 3. Collect the results with job_ids
title = f"Tagging {new_property_name} for {dataframe_name}"
self._client.jobs.wait_for_jobs(dataset_name=dataset_name, title=title, node_id=node_id)
- results = _collect_entities_with_job_ids(
- self._client.datasets.view_table(dataset=dataset_name, name=dataframe_name)
- )
+ results = _collect_entities_with_job_ids(self._client, dataset_name, dataframe_name)
# 4. Return the results
return pl.DataFrame(results, schema=expected_schema).lazy()
diff --git a/src/structify/resources/projects.py b/src/structify/resources/projects.py
index 658eadbd2..98eb1c2b5 100644
--- a/src/structify/resources/projects.py
+++ b/src/structify/resources/projects.py
@@ -8,7 +8,7 @@
from ..types import ProjectVisibility, project_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -28,6 +28,8 @@
class ProjectsResource(SyncAPIResource):
+ """Project management endpoints"""
+
@cached_property
def with_raw_response(self) -> ProjectsResourceWithRawResponse:
"""
@@ -78,7 +80,7 @@ def update(
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
return self._patch(
- f"/team/{team_id}/project/{project_id}",
+ path_template("/team/{team_id}/project/{project_id}", team_id=team_id, project_id=project_id),
body=maybe_transform(
{
"collaborators": collaborators,
@@ -121,7 +123,7 @@ def delete(
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
return self._delete(
- f"/team/{team_id}/project/{project_id}",
+ path_template("/team/{team_id}/project/{project_id}", team_id=team_id, project_id=project_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -155,7 +157,7 @@ def get(
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
return self._get(
- f"/team/{team_id}/project/{project_id}",
+ path_template("/team/{team_id}/project/{project_id}", team_id=team_id, project_id=project_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -164,6 +166,8 @@ def get(
class AsyncProjectsResource(AsyncAPIResource):
+ """Project management endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncProjectsResourceWithRawResponse:
"""
@@ -214,7 +218,7 @@ async def update(
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
return await self._patch(
- f"/team/{team_id}/project/{project_id}",
+ path_template("/team/{team_id}/project/{project_id}", team_id=team_id, project_id=project_id),
body=await async_maybe_transform(
{
"collaborators": collaborators,
@@ -257,7 +261,7 @@ async def delete(
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
return await self._delete(
- f"/team/{team_id}/project/{project_id}",
+ path_template("/team/{team_id}/project/{project_id}", team_id=team_id, project_id=project_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -291,7 +295,7 @@ async def get(
if not project_id:
raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}")
return await self._get(
- f"/team/{team_id}/project/{project_id}",
+ path_template("/team/{team_id}/project/{project_id}", team_id=team_id, project_id=project_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/structify/resources/public_sessions.py b/src/structify/resources/public_sessions.py
index 65bc52ffc..eb8136ff7 100644
--- a/src/structify/resources/public_sessions.py
+++ b/src/structify/resources/public_sessions.py
@@ -5,6 +5,7 @@
import httpx
from .._types import Body, Query, Headers, NotGiven, not_given
+from .._utils import path_template
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -71,7 +72,7 @@ def get_latest_workflow(
if not chat_session_id:
raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
return self._get(
- f"/public/chat/{chat_session_id}/latest-workflow",
+ path_template("/public/chat/{chat_session_id}/latest-workflow", chat_session_id=chat_session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -103,7 +104,7 @@ def get_node_output_data(
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
return self._get(
- f"/public/nodes/{node_id}/output_data",
+ path_template("/public/nodes/{node_id}/output_data", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -155,7 +156,7 @@ async def get_latest_workflow(
if not chat_session_id:
raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
return await self._get(
- f"/public/chat/{chat_session_id}/latest-workflow",
+ path_template("/public/chat/{chat_session_id}/latest-workflow", chat_session_id=chat_session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -187,7 +188,7 @@ async def get_node_output_data(
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
return await self._get(
- f"/public/nodes/{node_id}/output_data",
+ path_template("/public/nodes/{node_id}/output_data", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/structify/resources/sandbox.py b/src/structify/resources/sandbox.py
index 7f9c9bdfc..1a47e4931 100644
--- a/src/structify/resources/sandbox.py
+++ b/src/structify/resources/sandbox.py
@@ -8,7 +8,7 @@
from ..types import sandbox_get_params, sandbox_update_status_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -20,11 +20,14 @@
from .._base_client import make_request_options
from ..types.sandbox import Sandbox
from ..types.sandbox_list_response import SandboxListResponse
+from ..types.sandbox_get_metrics_response import SandboxGetMetricsResponse
__all__ = ["SandboxResource", "AsyncSandboxResource"]
class SandboxResource(SyncAPIResource):
+ """Sandbox management endpoints"""
+
@cached_property
def with_raw_response(self) -> SandboxResourceWithRawResponse:
"""
@@ -68,7 +71,7 @@ def list(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return self._get(
- f"/sandbox/list/{chat_id}",
+ path_template("/sandbox/list/{chat_id}", chat_id=chat_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -102,7 +105,7 @@ def get(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return self._post(
- f"/sandbox/live/{chat_id}",
+ path_template("/sandbox/live/{chat_id}", chat_id=chat_id),
body=maybe_transform(
{"modal_control_service_url_override": modal_control_service_url_override},
sandbox_get_params.SandboxGetParams,
@@ -113,6 +116,37 @@ def get(
cast_to=Sandbox,
)
+ def get_metrics(
+ self,
+ sandbox_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SandboxGetMetricsResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not sandbox_id:
+ raise ValueError(f"Expected a non-empty value for `sandbox_id` but received {sandbox_id!r}")
+ return self._get(
+ path_template("/sandbox/{sandbox_id}/metrics", sandbox_id=sandbox_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=SandboxGetMetricsResponse,
+ )
+
def update_status(
self,
sandbox_id: str,
@@ -138,7 +172,7 @@ def update_status(
if not sandbox_id:
raise ValueError(f"Expected a non-empty value for `sandbox_id` but received {sandbox_id!r}")
return self._patch(
- f"/sandbox/{sandbox_id}/status",
+ path_template("/sandbox/{sandbox_id}/status", sandbox_id=sandbox_id),
body=maybe_transform({"status": status}, sandbox_update_status_params.SandboxUpdateStatusParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -148,6 +182,8 @@ def update_status(
class AsyncSandboxResource(AsyncAPIResource):
+ """Sandbox management endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncSandboxResourceWithRawResponse:
"""
@@ -191,7 +227,7 @@ async def list(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return await self._get(
- f"/sandbox/list/{chat_id}",
+ path_template("/sandbox/list/{chat_id}", chat_id=chat_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -225,7 +261,7 @@ async def get(
if not chat_id:
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
return await self._post(
- f"/sandbox/live/{chat_id}",
+ path_template("/sandbox/live/{chat_id}", chat_id=chat_id),
body=await async_maybe_transform(
{"modal_control_service_url_override": modal_control_service_url_override},
sandbox_get_params.SandboxGetParams,
@@ -236,6 +272,37 @@ async def get(
cast_to=Sandbox,
)
+ async def get_metrics(
+ self,
+ sandbox_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SandboxGetMetricsResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not sandbox_id:
+ raise ValueError(f"Expected a non-empty value for `sandbox_id` but received {sandbox_id!r}")
+ return await self._get(
+ path_template("/sandbox/{sandbox_id}/metrics", sandbox_id=sandbox_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=SandboxGetMetricsResponse,
+ )
+
async def update_status(
self,
sandbox_id: str,
@@ -261,7 +328,7 @@ async def update_status(
if not sandbox_id:
raise ValueError(f"Expected a non-empty value for `sandbox_id` but received {sandbox_id!r}")
return await self._patch(
- f"/sandbox/{sandbox_id}/status",
+ path_template("/sandbox/{sandbox_id}/status", sandbox_id=sandbox_id),
body=await async_maybe_transform(
{"status": status}, sandbox_update_status_params.SandboxUpdateStatusParams
),
@@ -282,6 +349,9 @@ def __init__(self, sandbox: SandboxResource) -> None:
self.get = to_raw_response_wrapper(
sandbox.get,
)
+ self.get_metrics = to_raw_response_wrapper(
+ sandbox.get_metrics,
+ )
self.update_status = to_raw_response_wrapper(
sandbox.update_status,
)
@@ -297,6 +367,9 @@ def __init__(self, sandbox: AsyncSandboxResource) -> None:
self.get = async_to_raw_response_wrapper(
sandbox.get,
)
+ self.get_metrics = async_to_raw_response_wrapper(
+ sandbox.get_metrics,
+ )
self.update_status = async_to_raw_response_wrapper(
sandbox.update_status,
)
@@ -312,6 +385,9 @@ def __init__(self, sandbox: SandboxResource) -> None:
self.get = to_streamed_response_wrapper(
sandbox.get,
)
+ self.get_metrics = to_streamed_response_wrapper(
+ sandbox.get_metrics,
+ )
self.update_status = to_streamed_response_wrapper(
sandbox.update_status,
)
@@ -327,6 +403,9 @@ def __init__(self, sandbox: AsyncSandboxResource) -> None:
self.get = async_to_streamed_response_wrapper(
sandbox.get,
)
+ self.get_metrics = async_to_streamed_response_wrapper(
+ sandbox.get_metrics,
+ )
self.update_status = async_to_streamed_response_wrapper(
sandbox.update_status,
)
diff --git a/src/structify/resources/sessions.py b/src/structify/resources/sessions.py
index 658ce3c43..08f675436 100644
--- a/src/structify/resources/sessions.py
+++ b/src/structify/resources/sessions.py
@@ -3,7 +3,7 @@
from __future__ import annotations
from typing import Dict, Mapping, Iterable, Optional, cast
-from typing_extensions import Literal
+from typing_extensions import Literal, overload
import httpx
@@ -25,7 +25,14 @@
session_upload_node_visualization_output_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, FileTypes, omit, not_given
-from .._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
+from .._utils import (
+ extract_files,
+ path_template,
+ required_args,
+ maybe_transform,
+ deepcopy_minimal,
+ async_maybe_transform,
+)
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -54,6 +61,7 @@
from ..types.finalize_dag_response import FinalizeDagResponse
from ..types.workflow_session_node import WorkflowSessionNode
from ..types.get_node_logs_response import GetNodeLogsResponse
+from ..types.trigger_review_response import TriggerReviewResponse
from ..types.session_kill_jobs_response import SessionKillJobsResponse
from ..types.session_get_events_response import SessionGetEventsResponse
from ..types.workflow_node_execution_status import WorkflowNodeExecutionStatus
@@ -108,7 +116,7 @@ def confirm_node(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._post(
- f"/sessions/nodes/{node_id}/confirm",
+ path_template("/sessions/nodes/{node_id}/confirm", node_id=node_id),
body=maybe_transform({"confirmed": confirmed}, session_confirm_node_params.SessionConfirmNodeParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -120,7 +128,7 @@ def create_session(
self,
*,
chat_session_id: str,
- git_commit: str,
+ parent_chat_message_id: Optional[str] | Omit = omit,
workflow_schedule_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -144,7 +152,7 @@ def create_session(
body=maybe_transform(
{
"chat_session_id": chat_session_id,
- "git_commit": git_commit,
+ "parent_chat_message_id": parent_chat_message_id,
"workflow_schedule_id": workflow_schedule_id,
},
session_create_session_params.SessionCreateSessionParams,
@@ -180,7 +188,7 @@ def edit_node_output(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._post(
- f"/sessions/nodes/{node_id}/edit_output",
+ path_template("/sessions/nodes/{node_id}/edit_output", node_id=node_id),
body=maybe_transform({"edits": edits}, session_edit_node_output_params.SessionEditNodeOutputParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -221,7 +229,7 @@ def finalize_dag(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._post(
- f"/sessions/{session_id}/dag_ready",
+ path_template("/sessions/{session_id}/dag_ready", session_id=session_id),
body=maybe_transform(
{
"edges": edges,
@@ -260,7 +268,7 @@ def get_dag(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._get(
- f"/sessions/{session_id}/dag",
+ path_template("/sessions/{session_id}/dag", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -297,7 +305,7 @@ def get_events(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._get(
- f"/sessions/nodes/{node_id}/events",
+ path_template("/sessions/nodes/{node_id}/events", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -340,7 +348,7 @@ def get_node(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._get(
- f"/sessions/nodes/{node_id}",
+ path_template("/sessions/nodes/{node_id}", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -373,7 +381,7 @@ def get_node_logs(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._get(
- f"/sessions/node/{node_id}/logs",
+ path_template("/sessions/node/{node_id}/logs", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -405,7 +413,7 @@ def get_node_output_data(
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
return self._get(
- f"/sessions/nodes/{node_id}/output_data",
+ path_template("/sessions/nodes/{node_id}/output_data", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -436,7 +444,7 @@ def get_node_progress(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._get(
- f"/sessions/nodes/{node_id}/progress",
+ path_template("/sessions/nodes/{node_id}/progress", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -468,7 +476,7 @@ def kill_jobs(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._post(
- f"/sessions/{session_id}/kill_jobs",
+ path_template("/sessions/{session_id}/kill_jobs", session_id=session_id),
body=maybe_transform({"message": message}, session_kill_jobs_params.SessionKillJobsParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -504,7 +512,7 @@ def mark_errored(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._patch(
- f"/sessions/{session_id}/error",
+ path_template("/sessions/{session_id}/error", session_id=session_id),
body=maybe_transform(
{
"error_message": error_message,
@@ -546,7 +554,7 @@ def request_confirmation(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._post(
- f"/sessions/nodes/{node_id}/request_confirmation",
+ path_template("/sessions/nodes/{node_id}/request_confirmation", node_id=node_id),
body=maybe_transform(
{
"operation": operation,
@@ -560,6 +568,37 @@ def request_confirmation(
cast_to=WorkflowSessionNode,
)
+ def trigger_review(
+ self,
+ session_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TriggerReviewResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not session_id:
+ raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
+ return self._post(
+ path_template("/sessions/{session_id}/trigger_review", session_id=session_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TriggerReviewResponse,
+ )
+
def update_node(
self,
node_id: str,
@@ -588,7 +627,7 @@ def update_node(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._patch(
- f"/sessions/nodes/{node_id}",
+ path_template("/sessions/nodes/{node_id}", node_id=node_id),
body=maybe_transform(
{
"execution_status": execution_status,
@@ -632,7 +671,7 @@ def update_node_progress(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._patch(
- f"/sessions/nodes/{node_id}/progress",
+ path_template("/sessions/nodes/{node_id}/progress", node_id=node_id),
body=maybe_transform(
{
"current": current,
@@ -648,6 +687,7 @@ def update_node_progress(
cast_to=WorkflowSessionNode,
)
+ @overload
def upload_dashboard_layout(
self,
session_id: str,
@@ -673,12 +713,57 @@ def upload_dashboard_layout(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ ...
+
+ @overload
+ def upload_dashboard_layout(
+ self,
+ session_id: str,
+ *,
+ dashboard_specs: Iterable[session_upload_dashboard_layout_params.Variant1DashboardSpec],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> WorkflowSession:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @required_args(["layout"], ["dashboard_specs"])
+ def upload_dashboard_layout(
+ self,
+ session_id: str,
+ *,
+ layout: DashboardParam | Omit = omit,
+ dashboard_specs: Iterable[session_upload_dashboard_layout_params.Variant1DashboardSpec] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> WorkflowSession:
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return self._post(
- f"/sessions/{session_id}/dashboard_layout",
+ path_template("/sessions/{session_id}/dashboard_layout", session_id=session_id),
body=maybe_transform(
- {"layout": layout}, session_upload_dashboard_layout_params.SessionUploadDashboardLayoutParams
+ {
+ "layout": layout,
+ "dashboard_specs": dashboard_specs,
+ },
+ session_upload_dashboard_layout_params.SessionUploadDashboardLayoutParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -691,6 +776,12 @@ def upload_node_output_data(
node_id: str,
*,
content: FileTypes,
+ cache_final_rows: Optional[int] | Omit = omit,
+ cache_final_size_bytes: Optional[int] | Omit = omit,
+ cache_max_bytes: Optional[int] | Omit = omit,
+ cache_original_rows: Optional[int] | Omit = omit,
+ cache_original_size_bytes: Optional[int] | Omit = omit,
+ cache_truncated: Optional[bool] | Omit = omit,
output_schema: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -714,6 +805,12 @@ def upload_node_output_data(
body = deepcopy_minimal(
{
"content": content,
+ "cache_final_rows": cache_final_rows,
+ "cache_final_size_bytes": cache_final_size_bytes,
+ "cache_max_bytes": cache_max_bytes,
+ "cache_original_rows": cache_original_rows,
+ "cache_original_size_bytes": cache_original_size_bytes,
+ "cache_truncated": cache_truncated,
"output_schema": output_schema,
}
)
@@ -723,7 +820,7 @@ def upload_node_output_data(
# multipart/form-data; boundary=---abc--
extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
return self._post(
- f"/sessions/nodes/{node_id}/output_data",
+ path_template("/sessions/nodes/{node_id}/output_data", node_id=node_id),
body=maybe_transform(body, session_upload_node_output_data_params.SessionUploadNodeOutputDataParams),
files=files,
options=make_request_options(
@@ -757,7 +854,7 @@ def upload_node_visualization_output(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return self._post(
- f"/sessions/nodes/{node_id}/visualization_output",
+ path_template("/sessions/nodes/{node_id}/visualization_output", node_id=node_id),
body=maybe_transform(
{"visualization_output": visualization_output},
session_upload_node_visualization_output_params.SessionUploadNodeVisualizationOutputParams,
@@ -814,7 +911,7 @@ async def confirm_node(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._post(
- f"/sessions/nodes/{node_id}/confirm",
+ path_template("/sessions/nodes/{node_id}/confirm", node_id=node_id),
body=await async_maybe_transform(
{"confirmed": confirmed}, session_confirm_node_params.SessionConfirmNodeParams
),
@@ -828,7 +925,7 @@ async def create_session(
self,
*,
chat_session_id: str,
- git_commit: str,
+ parent_chat_message_id: Optional[str] | Omit = omit,
workflow_schedule_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -852,7 +949,7 @@ async def create_session(
body=await async_maybe_transform(
{
"chat_session_id": chat_session_id,
- "git_commit": git_commit,
+ "parent_chat_message_id": parent_chat_message_id,
"workflow_schedule_id": workflow_schedule_id,
},
session_create_session_params.SessionCreateSessionParams,
@@ -888,7 +985,7 @@ async def edit_node_output(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._post(
- f"/sessions/nodes/{node_id}/edit_output",
+ path_template("/sessions/nodes/{node_id}/edit_output", node_id=node_id),
body=await async_maybe_transform(
{"edits": edits}, session_edit_node_output_params.SessionEditNodeOutputParams
),
@@ -931,7 +1028,7 @@ async def finalize_dag(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._post(
- f"/sessions/{session_id}/dag_ready",
+ path_template("/sessions/{session_id}/dag_ready", session_id=session_id),
body=await async_maybe_transform(
{
"edges": edges,
@@ -970,7 +1067,7 @@ async def get_dag(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._get(
- f"/sessions/{session_id}/dag",
+ path_template("/sessions/{session_id}/dag", session_id=session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1007,7 +1104,7 @@ async def get_events(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._get(
- f"/sessions/nodes/{node_id}/events",
+ path_template("/sessions/nodes/{node_id}/events", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1050,7 +1147,7 @@ async def get_node(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._get(
- f"/sessions/nodes/{node_id}",
+ path_template("/sessions/nodes/{node_id}", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1083,7 +1180,7 @@ async def get_node_logs(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._get(
- f"/sessions/node/{node_id}/logs",
+ path_template("/sessions/node/{node_id}/logs", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1115,7 +1212,7 @@ async def get_node_output_data(
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
return await self._get(
- f"/sessions/nodes/{node_id}/output_data",
+ path_template("/sessions/nodes/{node_id}/output_data", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1146,7 +1243,7 @@ async def get_node_progress(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._get(
- f"/sessions/nodes/{node_id}/progress",
+ path_template("/sessions/nodes/{node_id}/progress", node_id=node_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1178,7 +1275,7 @@ async def kill_jobs(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._post(
- f"/sessions/{session_id}/kill_jobs",
+ path_template("/sessions/{session_id}/kill_jobs", session_id=session_id),
body=await async_maybe_transform({"message": message}, session_kill_jobs_params.SessionKillJobsParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -1214,7 +1311,7 @@ async def mark_errored(
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._patch(
- f"/sessions/{session_id}/error",
+ path_template("/sessions/{session_id}/error", session_id=session_id),
body=await async_maybe_transform(
{
"error_message": error_message,
@@ -1256,7 +1353,7 @@ async def request_confirmation(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._post(
- f"/sessions/nodes/{node_id}/request_confirmation",
+ path_template("/sessions/nodes/{node_id}/request_confirmation", node_id=node_id),
body=await async_maybe_transform(
{
"operation": operation,
@@ -1270,6 +1367,37 @@ async def request_confirmation(
cast_to=WorkflowSessionNode,
)
+ async def trigger_review(
+ self,
+ session_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TriggerReviewResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not session_id:
+ raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
+ return await self._post(
+ path_template("/sessions/{session_id}/trigger_review", session_id=session_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TriggerReviewResponse,
+ )
+
async def update_node(
self,
node_id: str,
@@ -1298,7 +1426,7 @@ async def update_node(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._patch(
- f"/sessions/nodes/{node_id}",
+ path_template("/sessions/nodes/{node_id}", node_id=node_id),
body=await async_maybe_transform(
{
"execution_status": execution_status,
@@ -1342,7 +1470,7 @@ async def update_node_progress(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._patch(
- f"/sessions/nodes/{node_id}/progress",
+ path_template("/sessions/nodes/{node_id}/progress", node_id=node_id),
body=await async_maybe_transform(
{
"current": current,
@@ -1358,6 +1486,7 @@ async def update_node_progress(
cast_to=WorkflowSessionNode,
)
+ @overload
async def upload_dashboard_layout(
self,
session_id: str,
@@ -1383,12 +1512,57 @@ async def upload_dashboard_layout(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ ...
+
+ @overload
+ async def upload_dashboard_layout(
+ self,
+ session_id: str,
+ *,
+ dashboard_specs: Iterable[session_upload_dashboard_layout_params.Variant1DashboardSpec],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> WorkflowSession:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @required_args(["layout"], ["dashboard_specs"])
+ async def upload_dashboard_layout(
+ self,
+ session_id: str,
+ *,
+ layout: DashboardParam | Omit = omit,
+ dashboard_specs: Iterable[session_upload_dashboard_layout_params.Variant1DashboardSpec] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> WorkflowSession:
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
return await self._post(
- f"/sessions/{session_id}/dashboard_layout",
+ path_template("/sessions/{session_id}/dashboard_layout", session_id=session_id),
body=await async_maybe_transform(
- {"layout": layout}, session_upload_dashboard_layout_params.SessionUploadDashboardLayoutParams
+ {
+ "layout": layout,
+ "dashboard_specs": dashboard_specs,
+ },
+ session_upload_dashboard_layout_params.SessionUploadDashboardLayoutParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -1401,6 +1575,12 @@ async def upload_node_output_data(
node_id: str,
*,
content: FileTypes,
+ cache_final_rows: Optional[int] | Omit = omit,
+ cache_final_size_bytes: Optional[int] | Omit = omit,
+ cache_max_bytes: Optional[int] | Omit = omit,
+ cache_original_rows: Optional[int] | Omit = omit,
+ cache_original_size_bytes: Optional[int] | Omit = omit,
+ cache_truncated: Optional[bool] | Omit = omit,
output_schema: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1424,6 +1604,12 @@ async def upload_node_output_data(
body = deepcopy_minimal(
{
"content": content,
+ "cache_final_rows": cache_final_rows,
+ "cache_final_size_bytes": cache_final_size_bytes,
+ "cache_max_bytes": cache_max_bytes,
+ "cache_original_rows": cache_original_rows,
+ "cache_original_size_bytes": cache_original_size_bytes,
+ "cache_truncated": cache_truncated,
"output_schema": output_schema,
}
)
@@ -1433,7 +1619,7 @@ async def upload_node_output_data(
# multipart/form-data; boundary=---abc--
extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
return await self._post(
- f"/sessions/nodes/{node_id}/output_data",
+ path_template("/sessions/nodes/{node_id}/output_data", node_id=node_id),
body=await async_maybe_transform(
body, session_upload_node_output_data_params.SessionUploadNodeOutputDataParams
),
@@ -1469,7 +1655,7 @@ async def upload_node_visualization_output(
if not node_id:
raise ValueError(f"Expected a non-empty value for `node_id` but received {node_id!r}")
return await self._post(
- f"/sessions/nodes/{node_id}/visualization_output",
+ path_template("/sessions/nodes/{node_id}/visualization_output", node_id=node_id),
body=await async_maybe_transform(
{"visualization_output": visualization_output},
session_upload_node_visualization_output_params.SessionUploadNodeVisualizationOutputParams,
@@ -1525,6 +1711,9 @@ def __init__(self, sessions: SessionsResource) -> None:
self.request_confirmation = to_raw_response_wrapper(
sessions.request_confirmation,
)
+ self.trigger_review = to_raw_response_wrapper(
+ sessions.trigger_review,
+ )
self.update_node = to_raw_response_wrapper(
sessions.update_node,
)
@@ -1586,6 +1775,9 @@ def __init__(self, sessions: AsyncSessionsResource) -> None:
self.request_confirmation = async_to_raw_response_wrapper(
sessions.request_confirmation,
)
+ self.trigger_review = async_to_raw_response_wrapper(
+ sessions.trigger_review,
+ )
self.update_node = async_to_raw_response_wrapper(
sessions.update_node,
)
@@ -1647,6 +1839,9 @@ def __init__(self, sessions: SessionsResource) -> None:
self.request_confirmation = to_streamed_response_wrapper(
sessions.request_confirmation,
)
+ self.trigger_review = to_streamed_response_wrapper(
+ sessions.trigger_review,
+ )
self.update_node = to_streamed_response_wrapper(
sessions.update_node,
)
@@ -1708,6 +1903,9 @@ def __init__(self, sessions: AsyncSessionsResource) -> None:
self.request_confirmation = async_to_streamed_response_wrapper(
sessions.request_confirmation,
)
+ self.trigger_review = async_to_streamed_response_wrapper(
+ sessions.trigger_review,
+ )
self.update_node = async_to_streamed_response_wrapper(
sessions.update_node,
)
diff --git a/src/structify/resources/structure.py b/src/structify/resources/structure.py
index 2581b5794..e004296d8 100644
--- a/src/structify/resources/structure.py
+++ b/src/structify/resources/structure.py
@@ -3,7 +3,6 @@
from __future__ import annotations
from typing import Iterable, Optional
-from typing_extensions import Literal
import httpx
@@ -276,9 +275,9 @@ def pdf(
dataset: str,
path: str,
instructions: Optional[str] | Omit = omit,
- mode: Literal["Single", "Batch"] | Omit = omit,
model: Optional[str] | Omit = omit,
node_id: Optional[str] | Omit = omit,
+ pages: Optional[Iterable[int]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -307,9 +306,9 @@ def pdf(
"dataset": dataset,
"path": path,
"instructions": instructions,
- "mode": mode,
"model": model,
"node_id": node_id,
+ "pages": pages,
},
structure_pdf_params.StructurePdfParams,
),
@@ -616,9 +615,9 @@ async def pdf(
dataset: str,
path: str,
instructions: Optional[str] | Omit = omit,
- mode: Literal["Single", "Batch"] | Omit = omit,
model: Optional[str] | Omit = omit,
node_id: Optional[str] | Omit = omit,
+ pages: Optional[Iterable[int]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -647,9 +646,9 @@ async def pdf(
"dataset": dataset,
"path": path,
"instructions": instructions,
- "mode": mode,
"model": model,
"node_id": node_id,
+ "pages": pages,
},
structure_pdf_params.StructurePdfParams,
),
diff --git a/src/structify/resources/teams.py b/src/structify/resources/teams.py
index 6513fc06f..45134d829 100644
--- a/src/structify/resources/teams.py
+++ b/src/structify/resources/teams.py
@@ -4,6 +4,7 @@
from typing import Union, Optional
from datetime import datetime
+from typing_extensions import Literal
import httpx
@@ -20,7 +21,7 @@
team_update_member_role_params,
)
from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -111,9 +112,10 @@ def update(
self,
team_id: str,
*,
+ daytona_credentials: Optional[team_update_params.DaytonaCredentials] | Omit = omit,
description: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
- pipedream_project_id: Optional[str] | Omit = omit,
+ sandbox_provider: Optional[Literal["modal", "daytona"]] | Omit = omit,
slack_bot_token: Optional[str] | Omit = omit,
slack_team_icon: Optional[str] | Omit = omit,
slack_team_id: Optional[str] | Omit = omit,
@@ -121,6 +123,7 @@ def update(
teams_app_id: Optional[str] | Omit = omit,
teams_app_password: Optional[str] | Omit = omit,
teams_tenant_id: Optional[str] | Omit = omit,
+ workflow_bucket: Optional[team_update_params.WorkflowBucket] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -141,12 +144,13 @@ def update(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._put(
- f"/team/{team_id}",
+ path_template("/team/{team_id}", team_id=team_id),
body=maybe_transform(
{
+ "daytona_credentials": daytona_credentials,
"description": description,
"name": name,
- "pipedream_project_id": pipedream_project_id,
+ "sandbox_provider": sandbox_provider,
"slack_bot_token": slack_bot_token,
"slack_team_icon": slack_team_icon,
"slack_team_id": slack_team_id,
@@ -154,6 +158,7 @@ def update(
"teams_app_id": teams_app_id,
"teams_app_password": teams_app_password,
"teams_tenant_id": teams_tenant_id,
+ "workflow_bucket": workflow_bucket,
},
team_update_params.TeamUpdateParams,
),
@@ -237,7 +242,7 @@ def add_member(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._post(
- f"/team/{team_id}/members",
+ path_template("/team/{team_id}/members", team_id=team_id),
body=maybe_transform(
{
"email": email,
@@ -277,7 +282,7 @@ def cancel_invitation(
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/team/{team_id}/invitations",
+ path_template("/team/{team_id}/invitations", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -314,7 +319,7 @@ def create_project(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._post(
- f"/team/{team_id}/projects",
+ path_template("/team/{team_id}/projects", team_id=team_id),
body=maybe_transform(
{
"name": name,
@@ -364,7 +369,7 @@ def credits_usage(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._get(
- f"/team/{team_id}/credits/usage",
+ path_template("/team/{team_id}/credits/usage", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -407,7 +412,7 @@ def get(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._get(
- f"/team/{team_id}",
+ path_template("/team/{team_id}", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -438,7 +443,7 @@ def invitation_details(
if not token:
raise ValueError(f"Expected a non-empty value for `token` but received {token!r}")
return self._get(
- f"/team/invitations/details/{token}",
+ path_template("/team/invitations/details/{token}", token=token),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -469,7 +474,7 @@ def list_members(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._get(
- f"/team/{team_id}/members",
+ path_template("/team/{team_id}/members", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -500,7 +505,7 @@ def list_projects(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._get(
- f"/team/{team_id}/projects",
+ path_template("/team/{team_id}/projects", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -534,7 +539,7 @@ def remove_member(
if not user_id:
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
return self._delete(
- f"/team/{team_id}/members/{user_id}",
+ path_template("/team/{team_id}/members/{user_id}", team_id=team_id, user_id=user_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -565,7 +570,7 @@ def select(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._post(
- f"/team/{team_id}/select",
+ path_template("/team/{team_id}/select", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -600,7 +605,7 @@ def update_member_role(
if not user_id:
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
return self._patch(
- f"/team/{team_id}/members/{user_id}/role",
+ path_template("/team/{team_id}/members/{user_id}/role", team_id=team_id, user_id=user_id),
body=maybe_transform({"role": role}, team_update_member_role_params.TeamUpdateMemberRoleParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -670,9 +675,10 @@ async def update(
self,
team_id: str,
*,
+ daytona_credentials: Optional[team_update_params.DaytonaCredentials] | Omit = omit,
description: Optional[str] | Omit = omit,
name: Optional[str] | Omit = omit,
- pipedream_project_id: Optional[str] | Omit = omit,
+ sandbox_provider: Optional[Literal["modal", "daytona"]] | Omit = omit,
slack_bot_token: Optional[str] | Omit = omit,
slack_team_icon: Optional[str] | Omit = omit,
slack_team_id: Optional[str] | Omit = omit,
@@ -680,6 +686,7 @@ async def update(
teams_app_id: Optional[str] | Omit = omit,
teams_app_password: Optional[str] | Omit = omit,
teams_tenant_id: Optional[str] | Omit = omit,
+ workflow_bucket: Optional[team_update_params.WorkflowBucket] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -700,12 +707,13 @@ async def update(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._put(
- f"/team/{team_id}",
+ path_template("/team/{team_id}", team_id=team_id),
body=await async_maybe_transform(
{
+ "daytona_credentials": daytona_credentials,
"description": description,
"name": name,
- "pipedream_project_id": pipedream_project_id,
+ "sandbox_provider": sandbox_provider,
"slack_bot_token": slack_bot_token,
"slack_team_icon": slack_team_icon,
"slack_team_id": slack_team_id,
@@ -713,6 +721,7 @@ async def update(
"teams_app_id": teams_app_id,
"teams_app_password": teams_app_password,
"teams_tenant_id": teams_tenant_id,
+ "workflow_bucket": workflow_bucket,
},
team_update_params.TeamUpdateParams,
),
@@ -798,7 +807,7 @@ async def add_member(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._post(
- f"/team/{team_id}/members",
+ path_template("/team/{team_id}/members", team_id=team_id),
body=await async_maybe_transform(
{
"email": email,
@@ -838,7 +847,7 @@ async def cancel_invitation(
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/team/{team_id}/invitations",
+ path_template("/team/{team_id}/invitations", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -877,7 +886,7 @@ async def create_project(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._post(
- f"/team/{team_id}/projects",
+ path_template("/team/{team_id}/projects", team_id=team_id),
body=await async_maybe_transform(
{
"name": name,
@@ -927,7 +936,7 @@ async def credits_usage(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._get(
- f"/team/{team_id}/credits/usage",
+ path_template("/team/{team_id}/credits/usage", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -970,7 +979,7 @@ async def get(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._get(
- f"/team/{team_id}",
+ path_template("/team/{team_id}", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1001,7 +1010,7 @@ async def invitation_details(
if not token:
raise ValueError(f"Expected a non-empty value for `token` but received {token!r}")
return await self._get(
- f"/team/invitations/details/{token}",
+ path_template("/team/invitations/details/{token}", token=token),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1032,7 +1041,7 @@ async def list_members(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._get(
- f"/team/{team_id}/members",
+ path_template("/team/{team_id}/members", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1063,7 +1072,7 @@ async def list_projects(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._get(
- f"/team/{team_id}/projects",
+ path_template("/team/{team_id}/projects", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1097,7 +1106,7 @@ async def remove_member(
if not user_id:
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
return await self._delete(
- f"/team/{team_id}/members/{user_id}",
+ path_template("/team/{team_id}/members/{user_id}", team_id=team_id, user_id=user_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1128,7 +1137,7 @@ async def select(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._post(
- f"/team/{team_id}/select",
+ path_template("/team/{team_id}/select", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1163,7 +1172,7 @@ async def update_member_role(
if not user_id:
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
return await self._patch(
- f"/team/{team_id}/members/{user_id}/role",
+ path_template("/team/{team_id}/members/{user_id}/role", team_id=team_id, user_id=user_id),
body=await async_maybe_transform({"role": role}, team_update_member_role_params.TeamUpdateMemberRoleParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
diff --git a/src/structify/resources/user/api_keys.py b/src/structify/resources/user/api_keys.py
index 6cb18071a..1adb80f3f 100644
--- a/src/structify/resources/user/api_keys.py
+++ b/src/structify/resources/user/api_keys.py
@@ -8,7 +8,7 @@
import httpx
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -27,6 +27,8 @@
class APIKeysResource(SyncAPIResource):
+ """All the accessible information about your account through our API"""
+
@cached_property
def with_raw_response(self) -> APIKeysResourceWithRawResponse:
"""
@@ -127,7 +129,7 @@ def get(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/user/api_keys/{id}",
+ path_template("/user/api_keys/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -159,7 +161,7 @@ def revoke(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/user/api_keys/{id}",
+ path_template("/user/api_keys/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -168,6 +170,8 @@ def revoke(
class AsyncAPIKeysResource(AsyncAPIResource):
+ """All the accessible information about your account through our API"""
+
@cached_property
def with_raw_response(self) -> AsyncAPIKeysResourceWithRawResponse:
"""
@@ -268,7 +272,7 @@ async def get(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/user/api_keys/{id}",
+ path_template("/user/api_keys/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -300,7 +304,7 @@ async def revoke(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/user/api_keys/{id}",
+ path_template("/user/api_keys/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/structify/resources/user/user.py b/src/structify/resources/user/user.py
index da9af3724..9d97998a5 100644
--- a/src/structify/resources/user/user.py
+++ b/src/structify/resources/user/user.py
@@ -20,6 +20,7 @@
user_update_params,
user_refresh_params,
user_survey_submit_params,
+ user_save_onboarding_answers_params,
)
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
from ..._utils import maybe_transform, async_maybe_transform
@@ -43,9 +44,12 @@
from ...types.user_info import UserInfo
from ...types.admin.user import User
from ...types.user_usage_response import UserUsageResponse
+from ...types.onboarding_answers_param import OnboardingAnswersParam
from ...types.refresh_session_response import RefreshSessionResponse
from ...types.survey_submission_response import SurveySubmissionResponse
from ...types.user_transactions_response import UserTransactionsResponse
+from ...types.get_onboarding_answers_response import GetOnboardingAnswersResponse
+from ...types.save_onboarding_answers_response import SaveOnboardingAnswersResponse
__all__ = ["UserResource", "AsyncUserResource"]
@@ -57,6 +61,7 @@ def stripe(self) -> StripeResource:
@cached_property
def api_keys(self) -> APIKeysResource:
+ """All the accessible information about your account through our API"""
return APIKeysResource(self._client)
@cached_property
@@ -148,6 +153,24 @@ def enrich(
cast_to=NoneType,
)
+ def get_onboarding_answers(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> GetOnboardingAnswersResponse:
+ return self._get(
+ "/user/onboarding/answers",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=GetOnboardingAnswersResponse,
+ )
+
def info(
self,
*,
@@ -208,6 +231,38 @@ def refresh(
cast_to=RefreshSessionResponse,
)
+ def save_onboarding_answers(
+ self,
+ *,
+ answers: OnboardingAnswersParam,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SaveOnboardingAnswersResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._put(
+ "/user/onboarding/answers",
+ body=maybe_transform(
+ {"answers": answers}, user_save_onboarding_answers_params.UserSaveOnboardingAnswersParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=SaveOnboardingAnswersResponse,
+ )
+
def survey_submit(
self,
*,
@@ -303,6 +358,7 @@ def stripe(self) -> AsyncStripeResource:
@cached_property
def api_keys(self) -> AsyncAPIKeysResource:
+ """All the accessible information about your account through our API"""
return AsyncAPIKeysResource(self._client)
@cached_property
@@ -394,6 +450,24 @@ async def enrich(
cast_to=NoneType,
)
+ async def get_onboarding_answers(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> GetOnboardingAnswersResponse:
+ return await self._get(
+ "/user/onboarding/answers",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=GetOnboardingAnswersResponse,
+ )
+
async def info(
self,
*,
@@ -454,6 +528,38 @@ async def refresh(
cast_to=RefreshSessionResponse,
)
+ async def save_onboarding_answers(
+ self,
+ *,
+ answers: OnboardingAnswersParam,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SaveOnboardingAnswersResponse:
+ """
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._put(
+ "/user/onboarding/answers",
+ body=await async_maybe_transform(
+ {"answers": answers}, user_save_onboarding_answers_params.UserSaveOnboardingAnswersParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=SaveOnboardingAnswersResponse,
+ )
+
async def survey_submit(
self,
*,
@@ -552,12 +658,18 @@ def __init__(self, user: UserResource) -> None:
self.enrich = to_raw_response_wrapper(
user.enrich,
)
+ self.get_onboarding_answers = to_raw_response_wrapper(
+ user.get_onboarding_answers,
+ )
self.info = to_raw_response_wrapper(
user.info,
)
self.refresh = to_raw_response_wrapper(
user.refresh,
)
+ self.save_onboarding_answers = to_raw_response_wrapper(
+ user.save_onboarding_answers,
+ )
self.survey_submit = to_raw_response_wrapper(
user.survey_submit,
)
@@ -574,6 +686,7 @@ def stripe(self) -> StripeResourceWithRawResponse:
@cached_property
def api_keys(self) -> APIKeysResourceWithRawResponse:
+ """All the accessible information about your account through our API"""
return APIKeysResourceWithRawResponse(self._user.api_keys)
@@ -587,12 +700,18 @@ def __init__(self, user: AsyncUserResource) -> None:
self.enrich = async_to_raw_response_wrapper(
user.enrich,
)
+ self.get_onboarding_answers = async_to_raw_response_wrapper(
+ user.get_onboarding_answers,
+ )
self.info = async_to_raw_response_wrapper(
user.info,
)
self.refresh = async_to_raw_response_wrapper(
user.refresh,
)
+ self.save_onboarding_answers = async_to_raw_response_wrapper(
+ user.save_onboarding_answers,
+ )
self.survey_submit = async_to_raw_response_wrapper(
user.survey_submit,
)
@@ -609,6 +728,7 @@ def stripe(self) -> AsyncStripeResourceWithRawResponse:
@cached_property
def api_keys(self) -> AsyncAPIKeysResourceWithRawResponse:
+ """All the accessible information about your account through our API"""
return AsyncAPIKeysResourceWithRawResponse(self._user.api_keys)
@@ -622,12 +742,18 @@ def __init__(self, user: UserResource) -> None:
self.enrich = to_streamed_response_wrapper(
user.enrich,
)
+ self.get_onboarding_answers = to_streamed_response_wrapper(
+ user.get_onboarding_answers,
+ )
self.info = to_streamed_response_wrapper(
user.info,
)
self.refresh = to_streamed_response_wrapper(
user.refresh,
)
+ self.save_onboarding_answers = to_streamed_response_wrapper(
+ user.save_onboarding_answers,
+ )
self.survey_submit = to_streamed_response_wrapper(
user.survey_submit,
)
@@ -644,6 +770,7 @@ def stripe(self) -> StripeResourceWithStreamingResponse:
@cached_property
def api_keys(self) -> APIKeysResourceWithStreamingResponse:
+ """All the accessible information about your account through our API"""
return APIKeysResourceWithStreamingResponse(self._user.api_keys)
@@ -657,12 +784,18 @@ def __init__(self, user: AsyncUserResource) -> None:
self.enrich = async_to_streamed_response_wrapper(
user.enrich,
)
+ self.get_onboarding_answers = async_to_streamed_response_wrapper(
+ user.get_onboarding_answers,
+ )
self.info = async_to_streamed_response_wrapper(
user.info,
)
self.refresh = async_to_streamed_response_wrapper(
user.refresh,
)
+ self.save_onboarding_answers = async_to_streamed_response_wrapper(
+ user.save_onboarding_answers,
+ )
self.survey_submit = async_to_streamed_response_wrapper(
user.survey_submit,
)
@@ -679,4 +812,5 @@ def stripe(self) -> AsyncStripeResourceWithStreamingResponse:
@cached_property
def api_keys(self) -> AsyncAPIKeysResourceWithStreamingResponse:
+ """All the accessible information about your account through our API"""
return AsyncAPIKeysResourceWithStreamingResponse(self._user.api_keys)
diff --git a/src/structify/resources/whitelabel.py b/src/structify/resources/whitelabel.py
index 541facb7e..08cd5aa8e 100644
--- a/src/structify/resources/whitelabel.py
+++ b/src/structify/resources/whitelabel.py
@@ -5,6 +5,7 @@
import httpx
from .._types import Body, Query, Headers, NoneType, NotGiven, not_given
+from .._utils import path_template
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -20,6 +21,8 @@
class WhitelabelResource(SyncAPIResource):
+ """Whitelabeled service proxy endpoints"""
+
@cached_property
def with_raw_response(self) -> WhitelabelResourceWithRawResponse:
"""
@@ -66,7 +69,7 @@ def estimate_cost(
if not path:
raise ValueError(f"Expected a non-empty value for `path` but received {path!r}")
return self._get(
- f"/whitelabel/{service}/estimate-cost/{path}",
+ path_template("/whitelabel/{service}/estimate-cost/{path}", service=service, path=path),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -101,7 +104,7 @@ def proxy_get(
raise ValueError(f"Expected a non-empty value for `path` but received {path!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._get(
- f"/whitelabel/{service}/{path}",
+ path_template("/whitelabel/{service}/{path}", service=service, path=path),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -136,7 +139,7 @@ def proxy_post(
raise ValueError(f"Expected a non-empty value for `path` but received {path!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- f"/whitelabel/{service}/{path}",
+ path_template("/whitelabel/{service}/{path}", service=service, path=path),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -145,6 +148,8 @@ def proxy_post(
class AsyncWhitelabelResource(AsyncAPIResource):
+ """Whitelabeled service proxy endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncWhitelabelResourceWithRawResponse:
"""
@@ -191,7 +196,7 @@ async def estimate_cost(
if not path:
raise ValueError(f"Expected a non-empty value for `path` but received {path!r}")
return await self._get(
- f"/whitelabel/{service}/estimate-cost/{path}",
+ path_template("/whitelabel/{service}/estimate-cost/{path}", service=service, path=path),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -226,7 +231,7 @@ async def proxy_get(
raise ValueError(f"Expected a non-empty value for `path` but received {path!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._get(
- f"/whitelabel/{service}/{path}",
+ path_template("/whitelabel/{service}/{path}", service=service, path=path),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -261,7 +266,7 @@ async def proxy_post(
raise ValueError(f"Expected a non-empty value for `path` but received {path!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- f"/whitelabel/{service}/{path}",
+ path_template("/whitelabel/{service}/{path}", service=service, path=path),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/structify/resources/wiki.py b/src/structify/resources/wiki.py
index 3288974ea..85e6d0b43 100644
--- a/src/structify/resources/wiki.py
+++ b/src/structify/resources/wiki.py
@@ -8,7 +8,7 @@
from ..types import wiki_create_params, wiki_update_params
from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -26,6 +26,8 @@
class WikiResource(SyncAPIResource):
+ """Team wiki page management endpoints"""
+
@cached_property
def with_raw_response(self) -> WikiResourceWithRawResponse:
"""
@@ -72,7 +74,7 @@ def create(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._post(
- f"/team/{team_id}/wiki",
+ path_template("/team/{team_id}/wiki", team_id=team_id),
body=maybe_transform(
{
"markdown": markdown,
@@ -117,7 +119,7 @@ def update(
if not slug:
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
return self._put(
- f"/team/{team_id}/wiki/{slug}",
+ path_template("/team/{team_id}/wiki/{slug}", team_id=team_id, slug=slug),
body=maybe_transform(
{
"markdown": markdown,
@@ -156,7 +158,7 @@ def list(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return self._get(
- f"/team/{team_id}/wiki",
+ path_template("/team/{team_id}/wiki", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -191,7 +193,7 @@ def delete(
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/team/{team_id}/wiki/{slug}",
+ path_template("/team/{team_id}/wiki/{slug}", team_id=team_id, slug=slug),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -225,7 +227,7 @@ def get(
if not slug:
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
return self._get(
- f"/team/{team_id}/wiki/{slug}",
+ path_template("/team/{team_id}/wiki/{slug}", team_id=team_id, slug=slug),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -234,6 +236,8 @@ def get(
class AsyncWikiResource(AsyncAPIResource):
+ """Team wiki page management endpoints"""
+
@cached_property
def with_raw_response(self) -> AsyncWikiResourceWithRawResponse:
"""
@@ -280,7 +284,7 @@ async def create(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._post(
- f"/team/{team_id}/wiki",
+ path_template("/team/{team_id}/wiki", team_id=team_id),
body=await async_maybe_transform(
{
"markdown": markdown,
@@ -325,7 +329,7 @@ async def update(
if not slug:
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
return await self._put(
- f"/team/{team_id}/wiki/{slug}",
+ path_template("/team/{team_id}/wiki/{slug}", team_id=team_id, slug=slug),
body=await async_maybe_transform(
{
"markdown": markdown,
@@ -364,7 +368,7 @@ async def list(
if not team_id:
raise ValueError(f"Expected a non-empty value for `team_id` but received {team_id!r}")
return await self._get(
- f"/team/{team_id}/wiki",
+ path_template("/team/{team_id}/wiki", team_id=team_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -399,7 +403,7 @@ async def delete(
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/team/{team_id}/wiki/{slug}",
+ path_template("/team/{team_id}/wiki/{slug}", team_id=team_id, slug=slug),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -433,7 +437,7 @@ async def get(
if not slug:
raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
return await self._get(
- f"/team/{team_id}/wiki/{slug}",
+ path_template("/team/{team_id}/wiki/{slug}", team_id=team_id, slug=slug),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/structify/resources/workflow_schedule.py b/src/structify/resources/workflow_schedule.py
index 111c2d17e..740128e23 100644
--- a/src/structify/resources/workflow_schedule.py
+++ b/src/structify/resources/workflow_schedule.py
@@ -13,7 +13,7 @@
workflow_schedule_get_sessions_params,
)
from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -77,7 +77,7 @@ def create(
if not chat_session_id:
raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
return self._post(
- f"/workflow-schedule/{chat_session_id}",
+ path_template("/workflow-schedule/{chat_session_id}", chat_session_id=chat_session_id),
body=maybe_transform(
{
"name": name,
@@ -120,7 +120,7 @@ def update(
if not schedule_id:
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
return self._put(
- f"/workflow-schedule/{schedule_id}",
+ path_template("/workflow-schedule/{schedule_id}", schedule_id=schedule_id),
body=maybe_transform(
{
"cron_schedule": cron_schedule,
@@ -161,7 +161,7 @@ def delete(
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/workflow-schedule/{schedule_id}",
+ path_template("/workflow-schedule/{schedule_id}", schedule_id=schedule_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -192,7 +192,7 @@ def get(
if not chat_session_id:
raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
return self._get(
- f"/workflow-schedule/{chat_session_id}",
+ path_template("/workflow-schedule/{chat_session_id}", chat_session_id=chat_session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -243,7 +243,7 @@ def get_sessions(
if not schedule_id:
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
return self._post(
- f"/workflow-schedule/{schedule_id}/sessions",
+ path_template("/workflow-schedule/{schedule_id}/sessions", schedule_id=schedule_id),
body=maybe_transform(
{
"limit": limit,
@@ -282,7 +282,7 @@ def pause(
if not schedule_id:
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
return self._patch(
- f"/workflow-schedule/{schedule_id}/pause",
+ path_template("/workflow-schedule/{schedule_id}/pause", schedule_id=schedule_id),
body=maybe_transform({"paused": paused}, workflow_schedule_pause_params.WorkflowSchedulePauseParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -315,7 +315,7 @@ def run(
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- f"/workflow-schedule/{schedule_id}/run",
+ path_template("/workflow-schedule/{schedule_id}/run", schedule_id=schedule_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -370,7 +370,7 @@ async def create(
if not chat_session_id:
raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
return await self._post(
- f"/workflow-schedule/{chat_session_id}",
+ path_template("/workflow-schedule/{chat_session_id}", chat_session_id=chat_session_id),
body=await async_maybe_transform(
{
"name": name,
@@ -413,7 +413,7 @@ async def update(
if not schedule_id:
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
return await self._put(
- f"/workflow-schedule/{schedule_id}",
+ path_template("/workflow-schedule/{schedule_id}", schedule_id=schedule_id),
body=await async_maybe_transform(
{
"cron_schedule": cron_schedule,
@@ -454,7 +454,7 @@ async def delete(
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/workflow-schedule/{schedule_id}",
+ path_template("/workflow-schedule/{schedule_id}", schedule_id=schedule_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -485,7 +485,7 @@ async def get(
if not chat_session_id:
raise ValueError(f"Expected a non-empty value for `chat_session_id` but received {chat_session_id!r}")
return await self._get(
- f"/workflow-schedule/{chat_session_id}",
+ path_template("/workflow-schedule/{chat_session_id}", chat_session_id=chat_session_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -536,7 +536,7 @@ async def get_sessions(
if not schedule_id:
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
return await self._post(
- f"/workflow-schedule/{schedule_id}/sessions",
+ path_template("/workflow-schedule/{schedule_id}/sessions", schedule_id=schedule_id),
body=await async_maybe_transform(
{
"limit": limit,
@@ -575,7 +575,7 @@ async def pause(
if not schedule_id:
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
return await self._patch(
- f"/workflow-schedule/{schedule_id}/pause",
+ path_template("/workflow-schedule/{schedule_id}/pause", schedule_id=schedule_id),
body=await async_maybe_transform(
{"paused": paused}, workflow_schedule_pause_params.WorkflowSchedulePauseParams
),
@@ -610,7 +610,7 @@ async def run(
raise ValueError(f"Expected a non-empty value for `schedule_id` but received {schedule_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- f"/workflow-schedule/{schedule_id}/run",
+ path_template("/workflow-schedule/{schedule_id}/run", schedule_id=schedule_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/structify/types/__init__.py b/src/structify/types/__init__.py
index 31412756e..636201a5a 100644
--- a/src/structify/types/__init__.py
+++ b/src/structify/types/__init__.py
@@ -15,8 +15,11 @@
from .dashboard import Dashboard as Dashboard
from .team_role import TeamRole as TeamRole
from .user_info import UserInfo as UserInfo
+from .viz_param import VizParam as VizParam
+from .viz_query import VizQuery as VizQuery
from .wiki_page import WikiPage as WikiPage
from .chat_event import ChatEvent as ChatEvent
+from .viz_figure import VizFigure as VizFigure
from .chat_prompt import ChatPrompt as ChatPrompt
from .granularity import Granularity as Granularity
from .table_param import TableParam as TableParam
@@ -29,10 +32,13 @@
from .relationship import Relationship as Relationship
from .workflow_dag import WorkflowDag as WorkflowDag
from .chat_template import ChatTemplate as ChatTemplate
+from .message_param import MessageParam as MessageParam
from .property_type import PropertyType as PropertyType
-from .tool_metadata import ToolMetadata as ToolMetadata
+from .dashboard_item import DashboardItem as DashboardItem
from .dashboard_page import DashboardPage as DashboardPage
+from .dashboard_spec import DashboardSpec as DashboardSpec
from .job_event_body import JobEventBody as JobEventBody
+from .phase_activity import PhaseActivity as PhaseActivity
from .project_member import ProjectMember as ProjectMember
from .strategy_param import StrategyParam as StrategyParam
from .team_with_role import TeamWithRole as TeamWithRole
@@ -49,9 +55,17 @@
from .node_spec_param import NodeSpecParam as NodeSpecParam
from .tool_invocation import ToolInvocation as ToolInvocation
from .usage_group_key import UsageGroupKey as UsageGroupKey
+from .viz_figure_kind import VizFigureKind as VizFigureKind
+from .viz_param_param import VizParamParam as VizParamParam
+from .viz_query_param import VizQueryParam as VizQueryParam
from .chat_copy_params import ChatCopyParams as ChatCopyParams
+from .datahub_progress import DatahubProgress as DatahubProgress
+from .job_get_response import JobGetResponse as JobGetResponse
from .save_requirement import SaveRequirement as SaveRequirement
+from .viz_date_control import VizDateControl as VizDateControl
+from .viz_figure_param import VizFigureParam as VizFigureParam
from .workflow_session import WorkflowSession as WorkflowSession
+from .chat_prompt_param import ChatPromptParam as ChatPromptParam
from .chat_session_role import ChatSessionRole as ChatSessionRole
from .connector_catalog import ConnectorCatalog as ConnectorCatalog
from .connector_summary import ConnectorSummary as ConnectorSummary
@@ -61,14 +75,17 @@
from .get_team_response import GetTeamResponse as GetTeamResponse
from .job_list_response import JobListResponse as JobListResponse
from .job_status_params import JobStatusParams as JobStatusParams
+from .template_question import TemplateQuestion as TemplateQuestion
from .user_usage_params import UserUsageParams as UserUsageParams
from .workflow_node_log import WorkflowNodeLog as WorkflowNodeLog
from .connector_category import ConnectorCategory as ConnectorCategory
+from .datahub_secret_map import DatahubSecretMap as DatahubSecretMap
from .dataset_descriptor import DatasetDescriptor as DatasetDescriptor
from .dataset_get_params import DatasetGetParams as DatasetGetParams
from .entity_view_params import EntityViewParams as EntityViewParams
from .exploration_status import ExplorationStatus as ExplorationStatus
from .merge_config_param import MergeConfigParam as MergeConfigParam
+from .onboarding_answers import OnboardingAnswers as OnboardingAnswers
from .parquet_edit_param import ParquetEditParam as ParquetEditParam
from .project_visibility import ProjectVisibility as ProjectVisibility
from .relationship_param import RelationshipParam as RelationshipParam
@@ -81,6 +98,9 @@
from .team_update_params import TeamUpdateParams as TeamUpdateParams
from .user_enrich_params import UserEnrichParams as UserEnrichParams
from .user_update_params import UserUpdateParams as UserUpdateParams
+from .viz_control_option import VizControlOption as VizControlOption
+from .viz_number_control import VizNumberControl as VizNumberControl
+from .viz_string_control import VizStringControl as VizStringControl
from .wiki_create_params import WikiCreateParams as WikiCreateParams
from .wiki_list_response import WikiListResponse as WikiListResponse
from .wiki_update_params import WikiUpdateParams as WikiUpdateParams
@@ -96,10 +116,12 @@
from .slack_events_params import SlackEventsParams as SlackEventsParams
from .user_refresh_params import UserRefreshParams as UserRefreshParams
from .user_usage_response import UserUsageResponse as UserUsageResponse
+from .viz_boolean_control import VizBooleanControl as VizBooleanControl
from .workflow_run_params import WorkflowRunParams as WorkflowRunParams
from .connector_table_info import ConnectorTableInfo as ConnectorTableInfo
from .create_team_response import CreateTeamResponse as CreateTeamResponse
from .dashboard_page_param import DashboardPageParam as DashboardPageParam
+from .dashboard_spec_param import DashboardSpecParam as DashboardSpecParam
from .dataset_get_response import DatasetGetResponse as DatasetGetResponse
from .dataset_match_params import DatasetMatchParams as DatasetMatchParams
from .document_list_params import DocumentListParams as DocumentListParams
@@ -109,6 +131,7 @@
from .entity_verify_params import EntityVerifyParams as EntityVerifyParams
from .entity_view_response import EntityViewResponse as EntityViewResponse
from .exploration_phase_id import ExplorationPhaseID as ExplorationPhaseID
+from .exploration_progress import ExplorationProgress as ExplorationProgress
from .list_tables_response import ListTablesResponse as ListTablesResponse
from .project_get_response import ProjectGetResponse as ProjectGetResponse
from .scrape_list_response import ScrapeListResponse as ScrapeListResponse
@@ -131,9 +154,12 @@
from .project_update_params import ProjectUpdateParams as ProjectUpdateParams
from .sandbox_list_response import SandboxListResponse as SandboxListResponse
from .update_table_response import UpdateTableResponse as UpdateTableResponse
+from .viz_date_control_type import VizDateControlType as VizDateControlType
+from .viz_figure_definition import VizFigureDefinition as VizFigureDefinition
from .workflow_session_edge import WorkflowSessionEdge as WorkflowSessionEdge
from .workflow_session_node import WorkflowSessionNode as WorkflowSessionNode
from .chat_load_files_params import ChatLoadFilesParams as ChatLoadFilesParams
+from .compress_chat_response import CompressChatResponse as CompressChatResponse
from .connector_get_response import ConnectorGetResponse as ConnectorGetResponse
from .connector_with_secrets import ConnectorWithSecrets as ConnectorWithSecrets
from .credits_usage_response import CreditsUsageResponse as CreditsUsageResponse
@@ -153,6 +179,7 @@
from .scrape_scrape_response import ScrapeScrapeResponse as ScrapeScrapeResponse
from .structure_pdf_response import StructurePdfResponse as StructurePdfResponse
from .team_add_member_params import TeamAddMemberParams as TeamAddMemberParams
+from .viz_date_control_param import VizDateControlParam as VizDateControlParam
from .workflow_schedule_info import WorkflowScheduleInfo as WorkflowScheduleInfo
from .connector_create_params import ConnectorCreateParams as ConnectorCreateParams
from .connector_explorer_chat import ConnectorExplorerChat as ConnectorExplorerChat
@@ -163,20 +190,30 @@
from .entity_add_batch_params import EntityAddBatchParams as EntityAddBatchParams
from .entity_list_jobs_params import EntityListJobsParams as EntityListJobsParams
from .entity_summarize_params import EntitySummarizeParams as EntitySummarizeParams
-from .explore_status_response import ExploreStatusResponse as ExploreStatusResponse
from .get_job_events_response import GetJobEventsResponse as GetJobEventsResponse
-from .chat_delete_files_params import ChatDeleteFilesParams as ChatDeleteFilesParams
+from .template_question_param import TemplateQuestionParam as TemplateQuestionParam
+from .trigger_review_response import TriggerReviewResponse as TriggerReviewResponse
+from .viz_number_control_type import VizNumberControlType as VizNumberControlType
+from .viz_string_control_type import VizStringControlType as VizStringControlType
from .chat_load_files_response import ChatLoadFilesResponse as ChatLoadFilesResponse
from .connector_explore_params import ConnectorExploreParams as ConnectorExploreParams
from .connector_store_response import ConnectorStoreResponse as ConnectorStoreResponse
+from .datahub_secret_map_param import DatahubSecretMapParam as DatahubSecretMapParam
from .dataset_descriptor_param import DatasetDescriptorParam as DatasetDescriptorParam
from .document_download_params import DocumentDownloadParams as DocumentDownloadParams
from .entity_derive_all_params import EntityDeriveAllParams as EntityDeriveAllParams
from .entity_get_merges_params import EntityGetMergesParams as EntityGetMergesParams
+from .list_dashboards_response import ListDashboardsResponse as ListDashboardsResponse
from .match_create_jobs_params import MatchCreateJobsParams as MatchCreateJobsParams
+from .onboarding_answers_param import OnboardingAnswersParam as OnboardingAnswersParam
from .refresh_session_response import RefreshSessionResponse as RefreshSessionResponse
from .session_kill_jobs_params import SessionKillJobsParams as SessionKillJobsParams
+from .simulate_prompt_response import SimulatePromptResponse as SimulatePromptResponse
from .team_subscription_status import TeamSubscriptionStatus as TeamSubscriptionStatus
+from .viz_boolean_control_type import VizBooleanControlType as VizBooleanControlType
+from .viz_control_option_param import VizControlOptionParam as VizControlOptionParam
+from .viz_number_control_param import VizNumberControlParam as VizNumberControlParam
+from .viz_string_control_param import VizStringControlParam as VizStringControlParam
from .wiki_connector_reference import WikiConnectorReference as WikiConnectorReference
from .chat_list_sessions_params import ChatListSessionsParams as ChatListSessionsParams
from .code_generate_code_params import CodeGenerateCodeParams as CodeGenerateCodeParams
@@ -188,21 +225,21 @@
from .exploration_runs_response import ExplorationRunsResponse as ExplorationRunsResponse
from .get_chat_session_response import GetChatSessionResponse as GetChatSessionResponse
from .get_dependencies_response import GetDependenciesResponse as GetDependenciesResponse
-from .job_get_scrapers_response import JobGetScrapersResponse as JobGetScrapersResponse
from .match_list_results_params import MatchListResultsParams as MatchListResultsParams
from .session_get_events_params import SessionGetEventsParams as SessionGetEventsParams
from .slack_event_payload_param import SlackEventPayloadParam as SlackEventPayloadParam
from .team_credits_usage_params import TeamCreditsUsageParams as TeamCreditsUsageParams
from .user_survey_submit_params import UserSurveySubmitParams as UserSurveySubmitParams
+from .viz_boolean_control_param import VizBooleanControlParam as VizBooleanControlParam
from .wiki_page_with_references import WikiPageWithReferences as WikiPageWithReferences
from .accept_invitation_response import AcceptInvitationResponse as AcceptInvitationResponse
from .admin_issue_found_response import AdminIssueFoundResponse as AdminIssueFoundResponse
from .chat_add_git_commit_params import ChatAddGitCommitParams as ChatAddGitCommitParams
from .chat_create_session_params import ChatCreateSessionParams as ChatCreateSessionParams
-from .chat_delete_files_response import ChatDeleteFilesResponse as ChatDeleteFilesResponse
from .chat_session_with_messages import ChatSessionWithMessages as ChatSessionWithMessages
from .chat_update_session_params import ChatUpdateSessionParams as ChatUpdateSessionParams
from .connector_credential_field import ConnectorCredentialField as ConnectorCredentialField
+from .connector_explore_response import ConnectorExploreResponse as ConnectorExploreResponse
from .connector_summaries_params import ConnectorSummariesParams as ConnectorSummariesParams
from .create_match_jobs_response import CreateMatchJobsResponse as CreateMatchJobsResponse
from .document_download_response import DocumentDownloadResponse as DocumentDownloadResponse
@@ -216,6 +253,8 @@
from .update_visibility_response import UpdateVisibilityResponse as UpdateVisibilityResponse
from .user_transactions_response import UserTransactionsResponse as UserTransactionsResponse
from .admin_grant_access_response import AdminGrantAccessResponse as AdminGrantAccessResponse
+from .chat_list_dashboards_params import ChatListDashboardsParams as ChatListDashboardsParams
+from .chat_simulate_prompt_params import ChatSimulatePromptParams as ChatSimulatePromptParams
from .dataset_add_property_params import DatasetAddPropertyParams as DatasetAddPropertyParams
from .dataset_view_table_response import DatasetViewTableResponse as DatasetViewTableResponse
from .entity_trigger_merge_params import EntityTriggerMergeParams as EntityTriggerMergeParams
@@ -231,22 +270,30 @@
from .source_delete_entity_params import SourceDeleteEntityParams as SourceDeleteEntityParams
from .structure_job_status_params import StructureJobStatusParams as StructureJobStatusParams
from .update_member_role_response import UpdateMemberRoleResponse as UpdateMemberRoleResponse
+from .viz_figure_definition_param import VizFigureDefinitionParam as VizFigureDefinitionParam
+from .admin_report_critical_params import AdminReportCriticalParams as AdminReportCriticalParams
from .chat_add_collaborator_params import ChatAddCollaboratorParams as ChatAddCollaboratorParams
from .chat_add_git_commit_response import ChatAddGitCommitResponse as ChatAddGitCommitResponse
from .chat_get_git_commit_response import ChatGetGitCommitResponse as ChatGetGitCommitResponse
from .chat_list_templates_response import ChatListTemplatesResponse as ChatListTemplatesResponse
+from .chat_load_input_files_params import ChatLoadInputFilesParams as ChatLoadInputFilesParams
from .chat_revert_to_commit_params import ChatRevertToCommitParams as ChatRevertToCommitParams
from .connector_summaries_response import ConnectorSummariesResponse as ConnectorSummariesResponse
from .create_chat_session_response import CreateChatSessionResponse as CreateChatSessionResponse
from .dataset_export_to_csv_params import DatasetExportToCsvParams as DatasetExportToCsvParams
from .delete_chat_session_response import DeleteChatSessionResponse as DeleteChatSessionResponse
from .entity_upload_parquet_params import EntityUploadParquetParams as EntityUploadParquetParams
+from .sandbox_get_metrics_response import SandboxGetMetricsResponse as SandboxGetMetricsResponse
from .sandbox_update_status_params import SandboxUpdateStatusParams as SandboxUpdateStatusParams
from .structure_is_complete_params import StructureIsCompleteParams as StructureIsCompleteParams
from .structure_run_async_response import StructureRunAsyncResponse as StructureRunAsyncResponse
from .chat_admin_issue_found_params import ChatAdminIssueFoundParams as ChatAdminIssueFoundParams
+from .chat_delete_input_file_params import ChatDeleteInputFileParams as ChatDeleteInputFileParams
from .chat_update_visibility_params import ChatUpdateVisibilityParams as ChatUpdateVisibilityParams
+from .chat_upload_input_file_params import ChatUploadInputFileParams as ChatUploadInputFileParams
+from .code_apply_manual_edit_params import CodeApplyManualEditParams as CodeApplyManualEditParams
from .connector_catalog_list_params import ConnectorCatalogListParams as ConnectorCatalogListParams
+from .connector_table_path_response import ConnectorTablePathResponse as ConnectorTablePathResponse
from .connector_update_table_params import ConnectorUpdateTableParams as ConnectorUpdateTableParams
from .delete_schema_object_response import DeleteSchemaObjectResponse as DeleteSchemaObjectResponse
from .delete_source_entity_response import DeleteSourceEntityResponse as DeleteSourceEntityResponse
@@ -257,9 +304,12 @@
from .structure_job_status_response import StructureJobStatusResponse as StructureJobStatusResponse
from .team_accept_invitation_params import TeamAcceptInvitationParams as TeamAcceptInvitationParams
from .team_cancel_invitation_params import TeamCancelInvitationParams as TeamCancelInvitationParams
+from .chat_list_input_files_response import ChatListInputFilesResponse as ChatListInputFilesResponse
+from .chat_load_input_files_response import ChatLoadInputFilesResponse as ChatLoadInputFilesResponse
from .chat_revert_to_commit_response import ChatRevertToCommitResponse as ChatRevertToCommitResponse
from .connector_catalog_with_methods import ConnectorCatalogWithMethods as ConnectorCatalogWithMethods
from .connector_create_secret_params import ConnectorCreateSecretParams as ConnectorCreateSecretParams
+from .connector_list_stores_response import ConnectorListStoresResponse as ConnectorListStoresResponse
from .connector_search_tables_params import ConnectorSearchTablesParams as ConnectorSearchTablesParams
from .connector_update_column_params import ConnectorUpdateColumnParams as ConnectorUpdateColumnParams
from .credits_usage_timeseries_point import CreditsUsageTimeseriesPoint as CreditsUsageTimeseriesPoint
@@ -271,9 +321,12 @@
from .team_update_member_role_params import TeamUpdateMemberRoleParams as TeamUpdateMemberRoleParams
from .workflow_node_execution_status import WorkflowNodeExecutionStatus as WorkflowNodeExecutionStatus
from .workflow_schedule_pause_params import WorkflowSchedulePauseParams as WorkflowSchedulePauseParams
+from .chat_delete_input_file_response import ChatDeleteInputFileResponse as ChatDeleteInputFileResponse
from .chat_get_partial_chats_response import ChatGetPartialChatsResponse as ChatGetPartialChatsResponse
+from .chat_upload_input_file_response import ChatUploadInputFileResponse as ChatUploadInputFileResponse
from .connector_catalog_list_response import ConnectorCatalogListResponse as ConnectorCatalogListResponse
from .entity_update_property_response import EntityUpdatePropertyResponse as EntityUpdatePropertyResponse
+from .get_onboarding_answers_response import GetOnboardingAnswersResponse as GetOnboardingAnswersResponse
from .session_edit_node_output_params import SessionEditNodeOutputParams as SessionEditNodeOutputParams
from .workflow_schedule_create_params import WorkflowScheduleCreateParams as WorkflowScheduleCreateParams
from .workflow_schedule_update_params import WorkflowScheduleUpdateParams as WorkflowScheduleUpdateParams
@@ -282,9 +335,9 @@
from .connector_search_tables_response import ConnectorSearchTablesResponse as ConnectorSearchTablesResponse
from .entity_add_relationship_response import EntityAddRelationshipResponse as EntityAddRelationshipResponse
from .entity_get_local_subgraph_params import EntityGetLocalSubgraphParams as EntityGetLocalSubgraphParams
-from .job_get_source_entities_response import JobGetSourceEntitiesResponse as JobGetSourceEntitiesResponse
from .nango_list_integrations_response import NangoListIntegrationsResponse as NangoListIntegrationsResponse
from .project_collaborator_input_param import ProjectCollaboratorInputParam as ProjectCollaboratorInputParam
+from .save_onboarding_answers_response import SaveOnboardingAnswersResponse as SaveOnboardingAnswersResponse
from .connector_auth_method_with_fields import ConnectorAuthMethodWithFields as ConnectorAuthMethodWithFields
from .dataset_reorder_properties_params import DatasetReorderPropertiesParams as DatasetReorderPropertiesParams
from .dataset_set_primary_column_params import DatasetSetPrimaryColumnParams as DatasetSetPrimaryColumnParams
@@ -306,13 +359,13 @@
from .structure_find_relationship_params import StructureFindRelationshipParams as StructureFindRelationshipParams
from .workflow_schedule_get_all_response import WorkflowScheduleGetAllResponse as WorkflowScheduleGetAllResponse
from .chat_update_session_favorite_params import ChatUpdateSessionFavoriteParams as ChatUpdateSessionFavoriteParams
-from .connector_list_with_snippets_params import ConnectorListWithSnippetsParams as ConnectorListWithSnippetsParams
from .dataset_view_relationships_response import DatasetViewRelationshipsResponse as DatasetViewRelationshipsResponse
from .delete_source_relationship_response import DeleteSourceRelationshipResponse as DeleteSourceRelationshipResponse
from .entity_get_source_entities_response import EntityGetSourceEntitiesResponse as EntityGetSourceEntitiesResponse
from .session_request_confirmation_params import SessionRequestConfirmationParams as SessionRequestConfirmationParams
from .session_update_node_progress_params import SessionUpdateNodeProgressParams as SessionUpdateNodeProgressParams
from .structure_enhance_property_response import StructureEnhancePropertyResponse as StructureEnhancePropertyResponse
+from .user_save_onboarding_answers_params import UserSaveOnboardingAnswersParams as UserSaveOnboardingAnswersParams
from .connector_add_schema_object_response import ConnectorAddSchemaObjectResponse as ConnectorAddSchemaObjectResponse
from .dataset_enrichment_progress_response import DatasetEnrichmentProgressResponse as DatasetEnrichmentProgressResponse
from .structure_find_relationship_response import StructureFindRelationshipResponse as StructureFindRelationshipResponse
@@ -325,6 +378,9 @@
from .structure_enhance_relationship_params import (
StructureEnhanceRelationshipParams as StructureEnhanceRelationshipParams,
)
+from .upload_dashboard_layout_request_param import (
+ UploadDashboardLayoutRequestParam as UploadDashboardLayoutRequestParam,
+)
from .workflow_schedule_get_sessions_params import (
WorkflowScheduleGetSessionsParams as WorkflowScheduleGetSessionsParams,
)
@@ -343,12 +399,18 @@
from .structure_enhance_relationship_response import (
StructureEnhanceRelationshipResponse as StructureEnhanceRelationshipResponse,
)
+from .connector_upload_datahub_artifact_params import (
+ ConnectorUploadDatahubArtifactParams as ConnectorUploadDatahubArtifactParams,
+)
from .chat_copy_node_output_by_code_hash_params import (
ChatCopyNodeOutputByCodeHashParams as ChatCopyNodeOutputByCodeHashParams,
)
from .dataset_count_missing_embeddings_response import (
DatasetCountMissingEmbeddingsResponse as DatasetCountMissingEmbeddingsResponse,
)
+from .connector_download_datahub_artifact_params import (
+ ConnectorDownloadDatahubArtifactParams as ConnectorDownloadDatahubArtifactParams,
+)
from .chat_copy_node_output_by_code_hash_response import (
ChatCopyNodeOutputByCodeHashResponse as ChatCopyNodeOutputByCodeHashResponse,
)
diff --git a/src/structify/types/admin/__init__.py b/src/structify/types/admin/__init__.py
index 5fa1433e9..8422f8b82 100644
--- a/src/structify/types/admin/__init__.py
+++ b/src/structify/types/admin/__init__.py
@@ -7,31 +7,38 @@
from .job_list_params import JobListParams as JobListParams
from .team_list_params import TeamListParams as TeamListParams
from .job_delete_params import JobDeleteParams as JobDeleteParams
+from .job_list_response import JobListResponse as JobListResponse
+from .team_list_response import TeamListResponse as TeamListResponse
from .user_create_params import UserCreateParams as UserCreateParams
from .user_list_response import UserListResponse as UserListResponse
from .sandbox_list_params import SandboxListParams as SandboxListParams
from .admin_dataset_return import AdminDatasetReturn as AdminDatasetReturn
from .impersonate_response import ImpersonateResponse as ImpersonateResponse
+from .datahub_ingestion_key import DatahubIngestionKey as DatahubIngestionKey
from .extend_trial_response import ExtendTrialResponse as ExtendTrialResponse
from .user_get_stats_params import UserGetStatsParams as UserGetStatsParams
from .connector_clone_params import ConnectorCloneParams as ConnectorCloneParams
+from .datahub_ingestion_type import DatahubIngestionType as DatahubIngestionType
from .expire_grants_response import ExpireGrantsResponse as ExpireGrantsResponse
from .grant_credits_response import GrantCreditsResponse as GrantCreditsResponse
from .team_add_member_params import TeamAddMemberParams as TeamAddMemberParams
+from .job_kill_by_user_params import JobKillByUserParams as JobKillByUserParams
from .user_get_stats_response import UserGetStatsResponse as UserGetStatsResponse
from .user_impersonate_params import UserImpersonateParams as UserImpersonateParams
-from .admin_list_jobs_response import AdminListJobsResponse as AdminListJobsResponse
+from .connector_clone_response import ConnectorCloneResponse as ConnectorCloneResponse
from .dataset_get_by_id_params import DatasetGetByIDParams as DatasetGetByIDParams
+from .job_concurrency_response import JobConcurrencyResponse as JobConcurrencyResponse
from .team_extend_trial_params import TeamExtendTrialParams as TeamExtendTrialParams
from .admin_add_member_response import AdminAddMemberResponse as AdminAddMemberResponse
from .admin_teams_list_response import AdminTeamsListResponse as AdminTeamsListResponse
from .chat_template_list_params import ChatTemplateListParams as ChatTemplateListParams
-from .clone_connectors_response import CloneConnectorsResponse as CloneConnectorsResponse
+from .job_kill_by_user_response import JobKillByUserResponse as JobKillByUserResponse
from .team_expire_grants_params import TeamExpireGrantsParams as TeamExpireGrantsParams
from .team_grant_credits_params import TeamGrantCreditsParams as TeamGrantCreditsParams
from .team_remove_member_params import TeamRemoveMemberParams as TeamRemoveMemberParams
from .admin_delete_jobs_response import AdminDeleteJobsResponse as AdminDeleteJobsResponse
from .clone_connector_item_param import CloneConnectorItemParam as CloneConnectorItemParam
+from .job_running_stats_response import JobRunningStatsResponse as JobRunningStatsResponse
from .admin_list_members_response import AdminListMembersResponse as AdminListMembersResponse
from .chat_template_create_params import ChatTemplateCreateParams as ChatTemplateCreateParams
from .chat_template_list_response import ChatTemplateListResponse as ChatTemplateListResponse
@@ -41,13 +48,17 @@
from .create_subscription_response import CreateSubscriptionResponse as CreateSubscriptionResponse
from .functional_test_create_params import FunctionalTestCreateParams as FunctionalTestCreateParams
from .functional_test_list_response import FunctionalTestListResponse as FunctionalTestListResponse
+from .job_update_concurrency_params import JobUpdateConcurrencyParams as JobUpdateConcurrencyParams
+from .admin_list_connectors_response import AdminListConnectorsResponse as AdminListConnectorsResponse
from .update_seats_override_response import UpdateSeatsOverrideResponse as UpdateSeatsOverrideResponse
+from .job_update_concurrency_response import JobUpdateConcurrencyResponse as JobUpdateConcurrencyResponse
from .team_cancel_subscription_params import TeamCancelSubscriptionParams as TeamCancelSubscriptionParams
from .team_create_subscription_params import TeamCreateSubscriptionParams as TeamCreateSubscriptionParams
from .functional_test_link_chat_params import FunctionalTestLinkChatParams as FunctionalTestLinkChatParams
from .functional_test_results_response import FunctionalTestResultsResponse as FunctionalTestResultsResponse
from .team_update_seats_override_params import TeamUpdateSeatsOverrideParams as TeamUpdateSeatsOverrideParams
from .functional_test_get_results_params import FunctionalTestGetResultsParams as FunctionalTestGetResultsParams
+from .connector_set_datahub_config_params import ConnectorSetDatahubConfigParams as ConnectorSetDatahubConfigParams
from .functional_test_update_results_params import (
FunctionalTestUpdateResultsParams as FunctionalTestUpdateResultsParams,
)
diff --git a/src/structify/types/admin/admin_list_connectors_response.py b/src/structify/types/admin/admin_list_connectors_response.py
new file mode 100644
index 000000000..6c4e75926
--- /dev/null
+++ b/src/structify/types/admin/admin_list_connectors_response.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ..._models import BaseModel
+from ..connector import Connector
+
+__all__ = ["AdminListConnectorsResponse"]
+
+
+class AdminListConnectorsResponse(BaseModel):
+ connectors: List[Connector]
diff --git a/src/structify/types/admin/admin_teams_list_response.py b/src/structify/types/admin/admin_teams_list_response.py
index 9344a3feb..0f3b7e799 100644
--- a/src/structify/types/admin/admin_teams_list_response.py
+++ b/src/structify/types/admin/admin_teams_list_response.py
@@ -31,6 +31,8 @@ class AdminTeamsListResponseGrant(BaseModel):
starts_at: Optional[datetime] = None
+ stripe_event_id: Optional[str] = None
+
class AdminTeamsListResponseSubscription(BaseModel):
has_active_subscription: bool
diff --git a/src/structify/types/admin/chat_template_create_params.py b/src/structify/types/admin/chat_template_create_params.py
index 9856cd691..5d4472c9c 100644
--- a/src/structify/types/admin/chat_template_create_params.py
+++ b/src/structify/types/admin/chat_template_create_params.py
@@ -2,8 +2,11 @@
from __future__ import annotations
+from typing import Iterable
from typing_extensions import Required, TypedDict
+from ..template_question_param import TemplateQuestionParam
+
__all__ = ["ChatTemplateCreateParams"]
@@ -18,4 +21,6 @@ class ChatTemplateCreateParams(TypedDict, total=False):
is_active: Required[bool]
+ questions: Required[Iterable[TemplateQuestionParam]]
+
title: Required[str]
diff --git a/src/structify/types/admin/chat_template_update_params.py b/src/structify/types/admin/chat_template_update_params.py
index 2b807aa4c..7129486a6 100644
--- a/src/structify/types/admin/chat_template_update_params.py
+++ b/src/structify/types/admin/chat_template_update_params.py
@@ -2,9 +2,11 @@
from __future__ import annotations
-from typing import Optional
+from typing import Iterable, Optional
from typing_extensions import TypedDict
+from ..template_question_param import TemplateQuestionParam
+
__all__ = ["ChatTemplateUpdateParams"]
@@ -17,6 +19,8 @@ class ChatTemplateUpdateParams(TypedDict, total=False):
is_active: Optional[bool]
+ questions: Optional[Iterable[TemplateQuestionParam]]
+
title: Optional[str]
updated_by: Optional[str]
diff --git a/src/structify/types/admin/connector_clone_params.py b/src/structify/types/admin/connector_clone_params.py
index 0b2cd0195..b7511f31b 100644
--- a/src/structify/types/admin/connector_clone_params.py
+++ b/src/structify/types/admin/connector_clone_params.py
@@ -13,4 +13,8 @@
class ConnectorCloneParams(TypedDict, total=False):
connectors: Required[Iterable[CloneConnectorItemParam]]
+ source_membership_id: Required[str]
+
+ source_team_id: Required[str]
+
target_team_id: Required[str]
diff --git a/src/structify/types/admin/clone_connectors_response.py b/src/structify/types/admin/connector_clone_response.py
similarity index 72%
rename from src/structify/types/admin/clone_connectors_response.py
rename to src/structify/types/admin/connector_clone_response.py
index 3f9e92177..3b3f86184 100644
--- a/src/structify/types/admin/clone_connectors_response.py
+++ b/src/structify/types/admin/connector_clone_response.py
@@ -5,8 +5,8 @@
from ..._models import BaseModel
from ..connector import Connector
-__all__ = ["CloneConnectorsResponse"]
+__all__ = ["ConnectorCloneResponse"]
-class CloneConnectorsResponse(BaseModel):
+class ConnectorCloneResponse(BaseModel):
connectors: List[Connector]
diff --git a/src/structify/types/admin/connector_set_datahub_config_params.py b/src/structify/types/admin/connector_set_datahub_config_params.py
new file mode 100644
index 000000000..19b947e9c
--- /dev/null
+++ b/src/structify/types/admin/connector_set_datahub_config_params.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Required, TypedDict
+
+from .datahub_ingestion_type import DatahubIngestionType
+from ..datahub_secret_map_param import DatahubSecretMapParam
+
+__all__ = ["ConnectorSetDatahubConfigParams"]
+
+
+class ConnectorSetDatahubConfigParams(TypedDict, total=False):
+ connector_id: Required[str]
+
+ datahub_ingestion_type: Optional[DatahubIngestionType]
+
+ datahub_secret_map: Optional[DatahubSecretMapParam]
+ """
+ Maps DatahubIngestionKey to the name of the connector secret that holds the
+ value.
+ """
diff --git a/src/structify/types/admin/datahub_ingestion_key.py b/src/structify/types/admin/datahub_ingestion_key.py
new file mode 100644
index 000000000..4fd0234de
--- /dev/null
+++ b/src/structify/types/admin/datahub_ingestion_key.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["DatahubIngestionKey"]
+
+DatahubIngestionKey: TypeAlias = Literal[
+ "host",
+ "port",
+ "database",
+ "username",
+ "password",
+ "account_id",
+ "warehouse",
+ "role",
+ "instance_url",
+ "access_token",
+ "project_id",
+ "credential_json",
+]
diff --git a/src/structify/types/admin/datahub_ingestion_type.py b/src/structify/types/admin/datahub_ingestion_type.py
new file mode 100644
index 000000000..592994fdf
--- /dev/null
+++ b/src/structify/types/admin/datahub_ingestion_type.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["DatahubIngestionType"]
+
+DatahubIngestionType: TypeAlias = Literal["postgres", "snowflake", "salesforce", "hubspot", "bigquery"]
diff --git a/src/structify/types/admin/job_concurrency_response.py b/src/structify/types/admin/job_concurrency_response.py
new file mode 100644
index 000000000..8932c09d4
--- /dev/null
+++ b/src/structify/types/admin/job_concurrency_response.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+
+from ..._models import BaseModel
+
+__all__ = ["JobConcurrencyResponse"]
+
+
+class JobConcurrencyResponse(BaseModel):
+ id: int
+
+ updated_at: datetime
+
+ max_connector_explore_jobs: Optional[int] = None
+
+ max_derive_jobs: Optional[int] = None
+
+ max_match_jobs: Optional[int] = None
+
+ max_pdf_jobs: Optional[int] = None
+
+ max_scrape_jobs: Optional[int] = None
+
+ max_total_jobs: Optional[int] = None
+
+ max_web_jobs: Optional[int] = None
diff --git a/src/structify/types/admin/job_kill_by_user_params.py b/src/structify/types/admin/job_kill_by_user_params.py
new file mode 100644
index 000000000..26dc2f804
--- /dev/null
+++ b/src/structify/types/admin/job_kill_by_user_params.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["JobKillByUserParams"]
+
+
+class JobKillByUserParams(TypedDict, total=False):
+ user_id: Required[str]
diff --git a/src/structify/types/admin/job_kill_by_user_response.py b/src/structify/types/admin/job_kill_by_user_response.py
new file mode 100644
index 000000000..3754fe457
--- /dev/null
+++ b/src/structify/types/admin/job_kill_by_user_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["JobKillByUserResponse"]
+
+
+class JobKillByUserResponse(BaseModel):
+ killed_jobs: int
diff --git a/src/structify/types/admin/job_list_params.py b/src/structify/types/admin/job_list_params.py
index 150217f76..62f040440 100644
--- a/src/structify/types/admin/job_list_params.py
+++ b/src/structify/types/admin/job_list_params.py
@@ -2,36 +2,19 @@
from __future__ import annotations
-from typing import Union, Optional
-from datetime import datetime
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from ..._utils import PropertyInfo
+from typing import Optional
+from typing_extensions import Literal, TypedDict
__all__ = ["JobListParams"]
class JobListParams(TypedDict, total=False):
- filter_test_users: Required[bool]
- """
- Filter out jobs from test users (users with functional_test feature flag or
- debug permission)
- """
-
- limit: Required[int]
- """Number of results to return"""
-
- offset: Required[int]
- """Pagination offset"""
+ job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]]
- dataset_id: Optional[str]
- """Dataset ID to optionally filter jobs by"""
+ limit: int
- seeded_kg_search_term: Optional[str]
- """Seeded kg search term"""
-
- since: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")]
- """List since a specific timestamp"""
+ offset: int
status: Optional[Literal["Queued", "Running", "Completed", "Failed"]]
- """Status to optionally filter jobs by"""
+
+ user_id: Optional[str]
diff --git a/src/structify/types/admin/admin_list_jobs_response.py b/src/structify/types/admin/job_list_response.py
similarity index 82%
rename from src/structify/types/admin/admin_list_jobs_response.py
rename to src/structify/types/admin/job_list_response.py
index eb52fa0f0..523c2310d 100644
--- a/src/structify/types/admin/admin_list_jobs_response.py
+++ b/src/structify/types/admin/job_list_response.py
@@ -1,6 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import List, Union, Optional
+from datetime import datetime
from typing_extensions import Literal, TypeAlias
from pydantic import Field as FieldInfo
@@ -11,7 +12,7 @@
from ..exploration_phase_id import ExplorationPhaseID
__all__ = [
- "AdminListJobsResponse",
+ "JobListResponse",
"Parameters",
"ParametersStructuringInput",
"ParametersStructuringInputAgent",
@@ -25,6 +26,8 @@
"ParametersStructuringInputScrapeFromURLPropertyScrapeFromURLProperty",
"ParametersStructuringInputScrapeURL",
"ParametersStructuringInputScrapeURLScrapeURL",
+ "ParametersStructuringInputDatahubIngestion",
+ "ParametersStructuringInputDatahubIngestionDatahubIngestion",
"ParametersStructuringInputConnectorExploration",
"ParametersStructuringInputConnectorExplorationConnectorExploration",
]
@@ -94,6 +97,18 @@ class ParametersStructuringInputScrapeURL(BaseModel):
scrape_url: ParametersStructuringInputScrapeURLScrapeURL = FieldInfo(alias="ScrapeUrl")
+class ParametersStructuringInputDatahubIngestionDatahubIngestion(BaseModel):
+ connector_id: str
+
+ exploration_run_id: str
+
+ only_do_datahub: bool
+
+
+class ParametersStructuringInputDatahubIngestion(BaseModel):
+ datahub_ingestion: ParametersStructuringInputDatahubIngestionDatahubIngestion = FieldInfo(alias="DatahubIngestion")
+
+
class ParametersStructuringInputConnectorExplorationConnectorExploration(BaseModel):
connector_id: str
@@ -106,8 +121,7 @@ class ParametersStructuringInputConnectorExplorationConnectorExploration(BaseMod
exploration_run_id: str
- stage: Literal["both", "ingestion", "annotation"]
- """Which exploration stage to run"""
+ strategy: Literal["full", "diff"]
class ParametersStructuringInputConnectorExploration(BaseModel):
@@ -121,6 +135,7 @@ class ParametersStructuringInputConnectorExploration(BaseModel):
ParametersStructuringInputTransformationPrompt,
ParametersStructuringInputScrapeFromURLProperty,
ParametersStructuringInputScrapeURL,
+ ParametersStructuringInputDatahubIngestion,
ParametersStructuringInputConnectorExploration,
]
@@ -130,29 +145,39 @@ class Parameters(BaseModel):
extraction_criteria: List[SaveRequirement]
- seeded_kg: KnowledgeGraph
- """
- Knowledge graph info structured to deserialize and display in the same format
- that the LLM outputs. Also the first representation of an LLM output in the
- pipeline from raw tool output to being merged into a DB
- """
-
structuring_input: ParametersStructuringInput
instructions: Optional[str] = None
model: Optional[str] = None
+ seeded_kg: Optional[KnowledgeGraph] = None
+ """
+ Knowledge graph info structured to deserialize and display in the same format
+ that the LLM outputs. Also the first representation of an LLM output in the
+ pipeline from raw tool output to being merged into a DB
+ """
+
-class AdminListJobsResponse(BaseModel):
+class JobListResponse(BaseModel):
id: str
- dataset_id: str
+ created_at: datetime
- job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore"]
+ job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]
status: Literal["Queued", "Running", "Completed", "Failed"]
user_id: str
+ dataset_id: Optional[str] = None
+
+ message: Optional[str] = None
+
parameters: Optional[Parameters] = None
+
+ reason: Optional[str] = None
+
+ run_started_time: Optional[datetime] = None
+
+ run_time_milliseconds: Optional[int] = None
diff --git a/src/structify/types/admin/job_running_stats_response.py b/src/structify/types/admin/job_running_stats_response.py
new file mode 100644
index 000000000..8f0d2f748
--- /dev/null
+++ b/src/structify/types/admin/job_running_stats_response.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ..._models import BaseModel
+
+__all__ = ["JobRunningStatsResponse", "ByType", "ByUser"]
+
+
+class ByType(BaseModel):
+ count: int
+
+ job_type: str
+
+
+class ByUser(BaseModel):
+ email: str
+
+ queued: int
+
+ running: int
+
+ user_id: str
+
+
+class JobRunningStatsResponse(BaseModel):
+ by_type: List[ByType]
+
+ by_user: List[ByUser]
+
+ completed_last_hour: int
+
+ failed_last_hour: int
+
+ total_queued: int
+
+ total_running: int
diff --git a/src/structify/types/admin/job_update_concurrency_params.py b/src/structify/types/admin/job_update_concurrency_params.py
new file mode 100644
index 000000000..5cbbdc869
--- /dev/null
+++ b/src/structify/types/admin/job_update_concurrency_params.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+__all__ = ["JobUpdateConcurrencyParams"]
+
+
+class JobUpdateConcurrencyParams(TypedDict, total=False):
+ max_connector_explore_jobs: Optional[int]
+
+ max_derive_jobs: Optional[int]
+
+ max_match_jobs: Optional[int]
+
+ max_pdf_jobs: Optional[int]
+
+ max_scrape_jobs: Optional[int]
+
+ max_total_jobs: Optional[int]
+
+ max_web_jobs: Optional[int]
diff --git a/src/structify/types/admin/job_update_concurrency_response.py b/src/structify/types/admin/job_update_concurrency_response.py
new file mode 100644
index 000000000..82b1ce3f3
--- /dev/null
+++ b/src/structify/types/admin/job_update_concurrency_response.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+
+from ..._models import BaseModel
+
+__all__ = ["JobUpdateConcurrencyResponse"]
+
+
+class JobUpdateConcurrencyResponse(BaseModel):
+ id: int
+
+ updated_at: datetime
+
+ max_connector_explore_jobs: Optional[int] = None
+
+ max_derive_jobs: Optional[int] = None
+
+ max_match_jobs: Optional[int] = None
+
+ max_pdf_jobs: Optional[int] = None
+
+ max_scrape_jobs: Optional[int] = None
+
+ max_total_jobs: Optional[int] = None
+
+ max_web_jobs: Optional[int] = None
diff --git a/src/structify/types/admin/team_list_params.py b/src/structify/types/admin/team_list_params.py
index e5cec336c..065bf3749 100644
--- a/src/structify/types/admin/team_list_params.py
+++ b/src/structify/types/admin/team_list_params.py
@@ -12,3 +12,5 @@ class TeamListParams(TypedDict, total=False):
limit: Optional[int]
offset: Optional[int]
+
+ search: Optional[str]
diff --git a/src/structify/types/admin/team_list_response.py b/src/structify/types/admin/team_list_response.py
new file mode 100644
index 000000000..0c06da6ba
--- /dev/null
+++ b/src/structify/types/admin/team_list_response.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ..._models import BaseModel
+from .admin_teams_list_response import AdminTeamsListResponse
+
+__all__ = ["TeamListResponse"]
+
+
+class TeamListResponse(BaseModel):
+ items: List[AdminTeamsListResponse]
+
+ total_count: int
diff --git a/src/structify/types/admin/user.py b/src/structify/types/admin/user.py
index e4c6019d9..cc3fb4d99 100644
--- a/src/structify/types/admin/user.py
+++ b/src/structify/types/admin/user.py
@@ -40,7 +40,7 @@ class User(BaseModel):
full_name: str
- is_developer: bool
+ notify_for_interaction: bool
permissions: List[Optional[Literal["labeler", "qa_labeler", "debug", "human_llm", "none"]]]
diff --git a/src/structify/types/admin_report_critical_params.py b/src/structify/types/admin_report_critical_params.py
new file mode 100644
index 000000000..5e036be4f
--- /dev/null
+++ b/src/structify/types/admin_report_critical_params.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["AdminReportCriticalParams"]
+
+
+class AdminReportCriticalParams(TypedDict, total=False):
+ message: Required[str]
diff --git a/src/structify/types/chat_copy_node_output_by_code_hash_response.py b/src/structify/types/chat_copy_node_output_by_code_hash_response.py
index ca05ae006..dde2da91d 100644
--- a/src/structify/types/chat_copy_node_output_by_code_hash_response.py
+++ b/src/structify/types/chat_copy_node_output_by_code_hash_response.py
@@ -1,8 +1,11 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
-from typing_extensions import TypeAlias
+
+from .._models import BaseModel
__all__ = ["ChatCopyNodeOutputByCodeHashResponse"]
-ChatCopyNodeOutputByCodeHashResponse: TypeAlias = Optional[str]
+
+class ChatCopyNodeOutputByCodeHashResponse(BaseModel):
+ cached_node_id: Optional[str] = None
diff --git a/src/structify/types/chat_copy_params.py b/src/structify/types/chat_copy_params.py
index 9e0070cb4..686312b2a 100644
--- a/src/structify/types/chat_copy_params.py
+++ b/src/structify/types/chat_copy_params.py
@@ -18,3 +18,5 @@ class ChatCopyParams(TypedDict, total=False):
copy_inputs: bool
project_id: Optional[str]
+
+ template_id: Optional[str]
diff --git a/src/structify/types/chat_create_session_params.py b/src/structify/types/chat_create_session_params.py
index b7c894703..61b16071f 100644
--- a/src/structify/types/chat_create_session_params.py
+++ b/src/structify/types/chat_create_session_params.py
@@ -16,8 +16,6 @@ class ChatCreateSessionParams(TypedDict, total=False):
ephemeral: Optional[bool]
- initial_message: Optional[str]
-
project_id: Optional[str]
@@ -50,7 +48,9 @@ class Config(TypedDict, total=False):
"gemini.gemini-2.5-flash",
"gemini.gemini-3-pro-preview",
"gemini.gemini-3-flash-preview",
+ "gemini.gemini-3.1-flash-lite-preview",
"vertex_anthropic.claude-sonnet-4-5-vertex",
+ "vertex_anthropic.claude-opus-4-5-vertex",
]
]
"""LLM model keys available in the system. Format: ."""
diff --git a/src/structify/types/chat_delete_files_params.py b/src/structify/types/chat_delete_input_file_params.py
similarity index 60%
rename from src/structify/types/chat_delete_files_params.py
rename to src/structify/types/chat_delete_input_file_params.py
index ed4fcfadc..9b9c5e0e8 100644
--- a/src/structify/types/chat_delete_files_params.py
+++ b/src/structify/types/chat_delete_input_file_params.py
@@ -6,8 +6,8 @@
from .._types import SequenceNotStr
-__all__ = ["ChatDeleteFilesParams"]
+__all__ = ["ChatDeleteInputFileParams"]
-class ChatDeleteFilesParams(TypedDict, total=False):
- paths: Required[SequenceNotStr[str]]
+class ChatDeleteInputFileParams(TypedDict, total=False):
+ filenames: Required[SequenceNotStr[str]]
diff --git a/src/structify/types/chat_delete_files_response.py b/src/structify/types/chat_delete_input_file_response.py
similarity index 62%
rename from src/structify/types/chat_delete_files_response.py
rename to src/structify/types/chat_delete_input_file_response.py
index c075f48c7..b0c00de63 100644
--- a/src/structify/types/chat_delete_files_response.py
+++ b/src/structify/types/chat_delete_input_file_response.py
@@ -2,8 +2,8 @@
from .._models import BaseModel
-__all__ = ["ChatDeleteFilesResponse"]
+__all__ = ["ChatDeleteInputFileResponse"]
-class ChatDeleteFilesResponse(BaseModel):
+class ChatDeleteInputFileResponse(BaseModel):
files_deleted: int
diff --git a/src/structify/types/chat_event.py b/src/structify/types/chat_event.py
index e44f40a4c..c6da66729 100644
--- a/src/structify/types/chat_event.py
+++ b/src/structify/types/chat_event.py
@@ -1,7 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import List, Union, Optional
-from typing_extensions import TypeAlias
+from typing_extensions import Literal, TypeAlias
from pydantic import Field as FieldInfo
@@ -35,6 +35,9 @@
"AttachedFileAttachedFile",
"ConnectorRequest",
"ConnectorRequestConnectorRequest",
+ "UserInterrupted",
+ "IssueFound",
+ "IssueFoundIssueFound",
]
@@ -144,6 +147,12 @@ class Question(BaseModel):
class InternalErrorInternalError(BaseModel):
message: str
+ error_kind: Optional[Literal["unknown", "context_limit", "rate_limited", "timeout", "connection_error"]] = None
+ """
+ Categorizes the kind of internal error that occurred during LLM generation. This
+ allows the frontend to render appropriate error messages without regex matching.
+ """
+
class InternalError(BaseModel):
internal_error: InternalErrorInternalError = FieldInfo(alias="InternalError")
@@ -185,6 +194,22 @@ class ConnectorRequest(BaseModel):
connector_request: ConnectorRequestConnectorRequest = FieldInfo(alias="ConnectorRequest")
+class UserInterrupted(BaseModel):
+ user_interrupted: object = FieldInfo(alias="UserInterrupted")
+
+
+class IssueFoundIssueFound(BaseModel):
+ admin_override: bool
+
+ description: str
+
+ title: str
+
+
+class IssueFound(BaseModel):
+ issue_found: IssueFoundIssueFound = FieldInfo(alias="IssueFound")
+
+
ChatEvent: TypeAlias = Union[
TextMessage,
Thinking,
@@ -197,4 +222,6 @@ class ConnectorRequest(BaseModel):
ReviewRequest,
AttachedFile,
ConnectorRequest,
+ UserInterrupted,
+ IssueFound,
]
diff --git a/src/structify/types/chat_get_partial_chats_response.py b/src/structify/types/chat_get_partial_chats_response.py
index f2fa66051..659af4c13 100644
--- a/src/structify/types/chat_get_partial_chats_response.py
+++ b/src/structify/types/chat_get_partial_chats_response.py
@@ -1,10 +1,21 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
+from datetime import datetime
from typing_extensions import TypeAlias
+from .._models import BaseModel
from .chat_prompt import ChatPrompt
-__all__ = ["ChatGetPartialChatsResponse"]
+__all__ = ["ChatGetPartialChatsResponse", "ChatGetPartialChatsResponseItem"]
-ChatGetPartialChatsResponse: TypeAlias = List[ChatPrompt]
+
+class ChatGetPartialChatsResponseItem(BaseModel):
+ chat_prompt: ChatPrompt
+
+ created_at: datetime
+
+ message_id: Optional[str] = None
+
+
+ChatGetPartialChatsResponse: TypeAlias = List[ChatGetPartialChatsResponseItem]
diff --git a/src/structify/types/chat_get_session_timeline_response.py b/src/structify/types/chat_get_session_timeline_response.py
index e50cb2803..1d936f547 100644
--- a/src/structify/types/chat_get_session_timeline_response.py
+++ b/src/structify/types/chat_get_session_timeline_response.py
@@ -41,7 +41,7 @@ class TimelineMessage(BaseModel):
content_proto: Optional[object] = None
- git_commit_id: Optional[str] = None
+ git_hash: Optional[str] = None
previous_message_id: Optional[str] = None
diff --git a/src/structify/types/chat_list_dashboards_params.py b/src/structify/types/chat_list_dashboards_params.py
new file mode 100644
index 000000000..bb0dadd3e
--- /dev/null
+++ b/src/structify/types/chat_list_dashboards_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+__all__ = ["ChatListDashboardsParams"]
+
+
+class ChatListDashboardsParams(TypedDict, total=False):
+ commit_hash: Optional[str]
+ """Optional commit hash. If omitted, uses the chat session latest commit."""
diff --git a/src/structify/types/chat_list_input_files_response.py b/src/structify/types/chat_list_input_files_response.py
new file mode 100644
index 000000000..f8597a2d8
--- /dev/null
+++ b/src/structify/types/chat_list_input_files_response.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from datetime import datetime
+from typing_extensions import TypeAlias
+
+from .._models import BaseModel
+
+__all__ = ["ChatListInputFilesResponse", "ChatListInputFilesResponseItem"]
+
+
+class ChatListInputFilesResponseItem(BaseModel):
+ chat_session_id: str
+
+ content_type: str
+
+ created_at: datetime
+
+ file_size: int
+
+ filename: str
+
+
+ChatListInputFilesResponse: TypeAlias = List[ChatListInputFilesResponseItem]
diff --git a/src/structify/types/chat_list_sessions_params.py b/src/structify/types/chat_list_sessions_params.py
index ad0ab10d6..70db59561 100644
--- a/src/structify/types/chat_list_sessions_params.py
+++ b/src/structify/types/chat_list_sessions_params.py
@@ -3,7 +3,7 @@
from __future__ import annotations
from typing import Optional
-from typing_extensions import Required, TypedDict
+from typing_extensions import Literal, Required, TypedDict
__all__ = ["ChatListSessionsParams"]
@@ -12,8 +12,20 @@ class ChatListSessionsParams(TypedDict, total=False):
team_id: Required[str]
"""Team ID to filter chat sessions"""
+ connector_id: Optional[str]
+ """Connector ID to filter chat sessions that use this connector"""
+
limit: Optional[int]
"""Maximum number of sessions to return (default: 50)"""
+ offset: Optional[int]
+ """Number of sessions to skip (default: 0)"""
+
project_id: Optional[str]
"""Project ID to filter chat sessions"""
+
+ search: Optional[str]
+ """Search query to filter sessions by name (case-insensitive)"""
+
+ tab: Optional[Literal["my_chats", "favorites", "shared", "team", "recents", "from_messaging"]]
+ """Tab filter for chat sessions"""
diff --git a/src/structify/types/chat_load_input_files_params.py b/src/structify/types/chat_load_input_files_params.py
new file mode 100644
index 000000000..ddc8dbd3a
--- /dev/null
+++ b/src/structify/types/chat_load_input_files_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Annotated, TypedDict
+
+from .._utils import PropertyInfo
+
+__all__ = ["ChatLoadInputFilesParams"]
+
+
+class ChatLoadInputFilesParams(TypedDict, total=False):
+ since: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")]
diff --git a/src/structify/types/chat_load_input_files_response.py b/src/structify/types/chat_load_input_files_response.py
new file mode 100644
index 000000000..19c08da4a
--- /dev/null
+++ b/src/structify/types/chat_load_input_files_response.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, Optional
+from datetime import datetime
+
+from .._models import BaseModel
+
+__all__ = ["ChatLoadInputFilesResponse"]
+
+
+class ChatLoadInputFilesResponse(BaseModel):
+ files: Dict[str, str]
+
+ latest_timestamp: Optional[datetime] = None
diff --git a/src/structify/types/chat_prompt.py b/src/structify/types/chat_prompt.py
index 04c7a1fba..e89b2d303 100644
--- a/src/structify/types/chat_prompt.py
+++ b/src/structify/types/chat_prompt.py
@@ -7,7 +7,6 @@
from .message import Message
from .._models import BaseModel
-from .tool_metadata import ToolMetadata
from .knowledge_graph import KnowledgeGraph
from .save_requirement import SaveRequirement
from .dataset_descriptor import DatasetDescriptor
@@ -238,8 +237,6 @@ class Metadata(BaseModel):
formatter_specific: MetadataFormatterSpecific
- tool_metadata: List[ToolMetadata]
-
qa_potentially_sus_response: Optional[str] = None
diff --git a/src/structify/types/chat_prompt_param.py b/src/structify/types/chat_prompt_param.py
new file mode 100644
index 000000000..10d188a3b
--- /dev/null
+++ b/src/structify/types/chat_prompt_param.py
@@ -0,0 +1,254 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Iterable, Optional
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
+
+from .._types import FileTypes, SequenceNotStr
+from .._utils import PropertyInfo
+from .message_param import MessageParam
+from .knowledge_graph_param import KnowledgeGraphParam
+from .save_requirement_param import SaveRequirementParam
+from .dataset_descriptor_param import DatasetDescriptorParam
+
+__all__ = [
+ "ChatPromptParam",
+ "DecodingParams",
+ "DecodingParamsParameter",
+ "DecodingParamsParameterMaxTokens",
+ "DecodingParamsParameterMaxCompletionTokens",
+ "DecodingParamsParameterTopP",
+ "DecodingParamsParameterRepeatWindow",
+ "DecodingParamsParameterRepeatPenalty",
+ "DecodingParamsParameterTemperature",
+ "DecodingParamsParameterStopTokens",
+ "DecodingParamsParameterLogitBias",
+ "DecodingParamsParameterFunctions",
+ "DecodingParamsParameterJsonValidator",
+ "DecodingParamsParameterRegexValidator",
+ "DecodingParamsParameterContextFreeGrammar",
+ "DecodingParamsParameterNumBeams",
+ "DecodingParamsParameterCrop",
+ "DecodingParamsParameterThinking",
+ "DecodingParamsParameterVerbosity",
+ "DecodingParamsParameterReasoningEffort",
+ "Metadata",
+ "MetadataFormatterSpecific",
+ "MetadataFormatterSpecificImageMeta",
+ "MetadataFormatterSpecificImageMetaImageMeta",
+ "MetadataFormatterSpecificWebMeta",
+ "MetadataFormatterSpecificWebMetaWebMeta",
+ "MetadataFormatterSpecificWebMetaWebMetaFlag",
+ "MetadataFormatterSpecificTextMeta",
+ "MetadataFormatterSpecificTextMetaTextMeta",
+ "MetadataFormatterSpecificScraperMeta",
+ "MetadataFormatterSpecificScraperMetaScraperMeta",
+]
+
+
+class DecodingParamsParameterMaxTokens(TypedDict, total=False):
+ max_tokens: Required[Annotated[int, PropertyInfo(alias="MaxTokens")]]
+
+
+class DecodingParamsParameterMaxCompletionTokens(TypedDict, total=False):
+ max_completion_tokens: Required[Annotated[int, PropertyInfo(alias="MaxCompletionTokens")]]
+
+
+class DecodingParamsParameterTopP(TypedDict, total=False):
+ top_p: Required[Annotated[float, PropertyInfo(alias="TopP")]]
+
+
+class DecodingParamsParameterRepeatWindow(TypedDict, total=False):
+ repeat_window: Required[Annotated[int, PropertyInfo(alias="RepeatWindow")]]
+
+
+class DecodingParamsParameterRepeatPenalty(TypedDict, total=False):
+ repeat_penalty: Required[Annotated[float, PropertyInfo(alias="RepeatPenalty")]]
+
+
+class DecodingParamsParameterTemperature(TypedDict, total=False):
+ temperature: Required[Annotated[float, PropertyInfo(alias="Temperature")]]
+
+
+class DecodingParamsParameterStopTokens(TypedDict, total=False):
+ stop_tokens: Required[Annotated[SequenceNotStr[str], PropertyInfo(alias="StopTokens")]]
+
+
+class DecodingParamsParameterLogitBias(TypedDict, total=False):
+ logit_bias: Required[Annotated[Dict[str, float], PropertyInfo(alias="LogitBias")]]
+
+
+class DecodingParamsParameterFunctions(TypedDict, total=False):
+ functions: Required[Annotated[Iterable[Dict[str, object]], PropertyInfo(alias="Functions")]]
+
+
+class DecodingParamsParameterJsonValidator(TypedDict, total=False):
+ json_validator: Required[Annotated[Dict[str, object], PropertyInfo(alias="JsonValidator")]]
+
+
+class DecodingParamsParameterRegexValidator(TypedDict, total=False):
+ regex_validator: Required[Annotated[str, PropertyInfo(alias="RegexValidator")]]
+
+
+class DecodingParamsParameterContextFreeGrammar(TypedDict, total=False):
+ context_free_grammar: Required[Annotated[str, PropertyInfo(alias="ContextFreeGrammar")]]
+
+
+class DecodingParamsParameterNumBeams(TypedDict, total=False):
+ num_beams: Required[Annotated[int, PropertyInfo(alias="NumBeams")]]
+
+
+class DecodingParamsParameterCrop(TypedDict, total=False):
+ crop: Required[Annotated[bool, PropertyInfo(alias="Crop")]]
+
+
+class DecodingParamsParameterThinking(TypedDict, total=False):
+ thinking: Required[Annotated[int, PropertyInfo(alias="Thinking")]]
+ """Thinking tokens for Claude 3.7. Contains the budget in tokens for thinking."""
+
+
+class DecodingParamsParameterVerbosity(TypedDict, total=False):
+ verbosity: Required[Annotated[Literal["low", "medium", "high"], PropertyInfo(alias="Verbosity")]]
+
+
+class DecodingParamsParameterReasoningEffort(TypedDict, total=False):
+ reasoning_effort: Required[
+ Annotated[Literal["low", "medium", "high", "minimal"], PropertyInfo(alias="ReasoningEffort")]
+ ]
+
+
+DecodingParamsParameter: TypeAlias = Union[
+ DecodingParamsParameterMaxTokens,
+ DecodingParamsParameterMaxCompletionTokens,
+ DecodingParamsParameterTopP,
+ DecodingParamsParameterRepeatWindow,
+ DecodingParamsParameterRepeatPenalty,
+ DecodingParamsParameterTemperature,
+ DecodingParamsParameterStopTokens,
+ DecodingParamsParameterLogitBias,
+ DecodingParamsParameterFunctions,
+ DecodingParamsParameterJsonValidator,
+ DecodingParamsParameterRegexValidator,
+ DecodingParamsParameterContextFreeGrammar,
+ DecodingParamsParameterNumBeams,
+ DecodingParamsParameterCrop,
+ DecodingParamsParameterThinking,
+ DecodingParamsParameterVerbosity,
+ DecodingParamsParameterReasoningEffort,
+]
+
+
+class DecodingParams(TypedDict, total=False):
+ parameters: Required[Iterable[DecodingParamsParameter]]
+
+
+class MetadataFormatterSpecificImageMetaImageMeta(TypedDict, total=False):
+ image: Required[Optional[str]]
+
+ document_name: Optional[str]
+
+ document_page: Optional[int]
+
+ ocr_content: Optional[str]
+
+
+class MetadataFormatterSpecificImageMeta(TypedDict, total=False):
+ image_meta: Required[Annotated[MetadataFormatterSpecificImageMetaImageMeta, PropertyInfo(alias="ImageMeta")]]
+
+
+class MetadataFormatterSpecificWebMetaWebMetaFlag(TypedDict, total=False):
+ aria_label: Required[Annotated[str, PropertyInfo(alias="ariaLabel")]]
+
+ type: Required[str]
+
+ x: Required[float]
+
+ y: Required[float]
+
+ height: float
+
+ href: Optional[str]
+
+ is_interactive: Annotated[Optional[bool], PropertyInfo(alias="isInteractive")]
+
+ number: Optional[int]
+ """The number by which the flag is referred in image, prompt, and tool calls."""
+
+ text: str
+
+ width: float
+ """
+ The serde default here is to give us backwards compatibility it's fine for these
+ to be anything as long as the image isn't given since it won't regenerate.
+ """
+
+
+class MetadataFormatterSpecificWebMetaWebMeta(TypedDict, total=False):
+ flags: Required[Iterable[MetadataFormatterSpecificWebMetaWebMetaFlag]]
+
+ url: Required[str]
+
+ ocr_content: Optional[str]
+
+ screenshot: Optional[FileTypes]
+
+
+class MetadataFormatterSpecificWebMeta(TypedDict, total=False):
+ web_meta: Required[Annotated[MetadataFormatterSpecificWebMetaWebMeta, PropertyInfo(alias="WebMeta")]]
+
+
+class MetadataFormatterSpecificTextMetaTextMeta(TypedDict, total=False):
+ text: Required[str]
+
+
+class MetadataFormatterSpecificTextMeta(TypedDict, total=False):
+ text_meta: Required[Annotated[MetadataFormatterSpecificTextMetaTextMeta, PropertyInfo(alias="TextMeta")]]
+
+
+class MetadataFormatterSpecificScraperMetaScraperMeta(TypedDict, total=False):
+ html_content: Required[str]
+
+ url: Required[str]
+
+
+class MetadataFormatterSpecificScraperMeta(TypedDict, total=False):
+ scraper_meta: Required[
+ Annotated[MetadataFormatterSpecificScraperMetaScraperMeta, PropertyInfo(alias="ScraperMeta")]
+ ]
+
+
+MetadataFormatterSpecific: TypeAlias = Union[
+ MetadataFormatterSpecificImageMeta,
+ MetadataFormatterSpecificWebMeta,
+ MetadataFormatterSpecificTextMeta,
+ MetadataFormatterSpecificScraperMeta,
+]
+
+
+class Metadata(TypedDict, total=False):
+ """All metadata required to generate a prompt for the LLM"""
+
+ dataset_descriptor: Required[DatasetDescriptorParam]
+ """A dataset is where you put multiple referential schemas.
+
+ A dataset is a complete namespace where all references between schemas are held
+ within the dataset.
+ """
+
+ extracted_entities: Required[Iterable[KnowledgeGraphParam]]
+
+ extraction_criteria: Required[Iterable[SaveRequirementParam]]
+
+ formatter_specific: Required[MetadataFormatterSpecific]
+
+ qa_potentially_sus_response: Optional[str]
+
+
+class ChatPromptParam(TypedDict, total=False):
+ decoding_params: Required[DecodingParams]
+
+ messages: Required[Iterable[MessageParam]]
+
+ metadata: Required[Metadata]
+ """All metadata required to generate a prompt for the LLM"""
diff --git a/src/structify/types/chat_session.py b/src/structify/types/chat_session.py
index a3e7305c9..70c8d9dfd 100644
--- a/src/structify/types/chat_session.py
+++ b/src/structify/types/chat_session.py
@@ -36,6 +36,10 @@ class ChatSession(BaseModel):
config_proto: Optional[object] = None
+ instantiated_from_template_id: Optional[str] = None
+
+ message_head: Optional[str] = None
+
name: Optional[str] = None
project_id: Optional[str] = None
diff --git a/src/structify/types/chat_session_with_messages.py b/src/structify/types/chat_session_with_messages.py
index 42a4f3ec3..7820f2e7c 100644
--- a/src/structify/types/chat_session_with_messages.py
+++ b/src/structify/types/chat_session_with_messages.py
@@ -43,7 +43,7 @@ class Message(BaseModel):
content_proto: Optional[object] = None
- git_commit_id: Optional[str] = None
+ git_hash: Optional[str] = None
previous_message_id: Optional[str] = None
@@ -69,6 +69,8 @@ class ChatSessionWithMessages(BaseModel):
created_at: datetime
+ ephemeral: bool
+
git_application_token: str
is_favorite: bool
@@ -87,8 +89,12 @@ class ChatSessionWithMessages(BaseModel):
visibility: ChatVisibility
+ instantiated_from_template_id: Optional[str] = None
+
latest_workflow_session_id: Optional[str] = None
+ message_head: Optional[str] = None
+
name: Optional[str] = None
project_id: Optional[str] = None
diff --git a/src/structify/types/chat_simulate_prompt_params.py b/src/structify/types/chat_simulate_prompt_params.py
new file mode 100644
index 000000000..c9a3df372
--- /dev/null
+++ b/src/structify/types/chat_simulate_prompt_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .chat_prompt_param import ChatPromptParam
+
+__all__ = ["ChatSimulatePromptParams"]
+
+
+class ChatSimulatePromptParams(TypedDict, total=False):
+ chat_prompt: Required[ChatPromptParam]
diff --git a/src/structify/types/chat_template.py b/src/structify/types/chat_template.py
index c7c96474d..1c93c1eab 100644
--- a/src/structify/types/chat_template.py
+++ b/src/structify/types/chat_template.py
@@ -1,8 +1,10 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from typing import List
from datetime import datetime
from .._models import BaseModel
+from .template_question import TemplateQuestion
__all__ = ["ChatTemplate"]
@@ -24,6 +26,8 @@ class ChatTemplate(BaseModel):
is_active: bool
+ questions: List[TemplateQuestion]
+
title: str
updated_at: datetime
diff --git a/src/structify/types/chat_update_session_params.py b/src/structify/types/chat_update_session_params.py
index e3ac063cb..b7f62a070 100644
--- a/src/structify/types/chat_update_session_params.py
+++ b/src/structify/types/chat_update_session_params.py
@@ -9,6 +9,8 @@
class ChatUpdateSessionParams(TypedDict, total=False):
+ message_head: Optional[str]
+
name: Optional[str]
project_id: Optional[str]
diff --git a/src/structify/types/chat_upload_input_file_params.py b/src/structify/types/chat_upload_input_file_params.py
new file mode 100644
index 000000000..a4a6eb732
--- /dev/null
+++ b/src/structify/types/chat_upload_input_file_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .._types import FileTypes
+
+__all__ = ["ChatUploadInputFileParams"]
+
+
+class ChatUploadInputFileParams(TypedDict, total=False):
+ content: Required[FileTypes]
+
+ content_type: Required[str]
+
+ file_name: Required[str]
diff --git a/src/structify/types/chat_upload_input_file_response.py b/src/structify/types/chat_upload_input_file_response.py
new file mode 100644
index 000000000..29e08729c
--- /dev/null
+++ b/src/structify/types/chat_upload_input_file_response.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from datetime import datetime
+
+from .._models import BaseModel
+
+__all__ = ["ChatUploadInputFileResponse", "File"]
+
+
+class File(BaseModel):
+ chat_session_id: str
+
+ content_type: str
+
+ created_at: datetime
+
+ file_size: int
+
+ filename: str
+
+
+class ChatUploadInputFileResponse(BaseModel):
+ file: File
diff --git a/src/structify/types/chat_visibility.py b/src/structify/types/chat_visibility.py
index 562a18934..d53c3721a 100644
--- a/src/structify/types/chat_visibility.py
+++ b/src/structify/types/chat_visibility.py
@@ -4,4 +4,4 @@
__all__ = ["ChatVisibility"]
-ChatVisibility: TypeAlias = Literal["private", "shared_with_team", "public"]
+ChatVisibility: TypeAlias = Literal["private", "shared_with_team", "shared_with_team_view", "public"]
diff --git a/src/structify/types/code_apply_manual_edit_params.py b/src/structify/types/code_apply_manual_edit_params.py
new file mode 100644
index 000000000..ba00c6880
--- /dev/null
+++ b/src/structify/types/code_apply_manual_edit_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["CodeApplyManualEditParams"]
+
+
+class CodeApplyManualEditParams(TypedDict, total=False):
+ code: Required[str]
+
+ filename: Required[str]
diff --git a/src/structify/types/code_generate_code_params.py b/src/structify/types/code_generate_code_params.py
index c93a743bc..0d8de217d 100644
--- a/src/structify/types/code_generate_code_params.py
+++ b/src/structify/types/code_generate_code_params.py
@@ -61,7 +61,9 @@ class Config(TypedDict, total=False):
"gemini.gemini-2.5-flash",
"gemini.gemini-3-pro-preview",
"gemini.gemini-3-flash-preview",
+ "gemini.gemini-3.1-flash-lite-preview",
"vertex_anthropic.claude-sonnet-4-5-vertex",
+ "vertex_anthropic.claude-opus-4-5-vertex",
]
]
"""LLM model keys available in the system. Format: ."""
diff --git a/src/structify/types/compress_chat_response.py b/src/structify/types/compress_chat_response.py
new file mode 100644
index 000000000..17433aa85
--- /dev/null
+++ b/src/structify/types/compress_chat_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["CompressChatResponse"]
+
+
+class CompressChatResponse(BaseModel):
+ status: str
diff --git a/src/structify/types/connector.py b/src/structify/types/connector.py
index d40f64e70..fb8393c35 100644
--- a/src/structify/types/connector.py
+++ b/src/structify/types/connector.py
@@ -1,11 +1,12 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import List, Optional
from datetime import datetime
+from typing_extensions import Literal
from .._models import BaseModel
from .connector_category import ConnectorCategory
-from .exploration_status import ExplorationStatus
+from .datahub_secret_map import DatahubSecretMap
__all__ = ["Connector"]
@@ -15,36 +16,40 @@ class Connector(BaseModel):
created_at: datetime
- exploration_status: ExplorationStatus
-
known_connector_type: str
name: str
+ owner_user_id: str
+
team_id: str
+ team_visibility: Literal["Team", "Private"]
+
updated_at: datetime
connector_category: Optional[ConnectorCategory] = None
+ datahub_ingestion_type: Optional[str] = None
+
+ datahub_secret_map: Optional[DatahubSecretMap] = None
+ """
+ Maps DatahubIngestionKey to the name of the connector secret that holds the
+ value.
+ """
+
datahub_urn: Optional[str] = None
deleted_at: Optional[datetime] = None
description: Optional[str] = None
- exploration_error: Optional[str] = None
-
- exploration_started_at: Optional[datetime] = None
-
nango_connection_id: Optional[str] = None
- nango_integration_id: Optional[str] = None
-
- pipedream_account_id: Optional[str] = None
+ oauth_scopes: Optional[List[Optional[str]]] = None
- pipedream_external_id: Optional[str] = None
+ refresh_cron_schedule: Optional[str] = None
- refresh_script: Optional[str] = None
+ refresh_next_run_at: Optional[datetime] = None
usage_snippet_override: Optional[str] = None
diff --git a/src/structify/types/connector_catalog/admin_create_catalog_params.py b/src/structify/types/connector_catalog/admin_create_catalog_params.py
index 3662fcbec..98662c009 100644
--- a/src/structify/types/connector_catalog/admin_create_catalog_params.py
+++ b/src/structify/types/connector_catalog/admin_create_catalog_params.py
@@ -19,4 +19,8 @@ class AdminCreateCatalogParams(TypedDict, total=False):
description: Optional[str]
+ enterprise_only: bool
+
+ onboarding_priority: Optional[int]
+
priority: Optional[int]
diff --git a/src/structify/types/connector_catalog/admin_update_catalog_params.py b/src/structify/types/connector_catalog/admin_update_catalog_params.py
index 90f8b2286..23d639c71 100644
--- a/src/structify/types/connector_catalog/admin_update_catalog_params.py
+++ b/src/structify/types/connector_catalog/admin_update_catalog_params.py
@@ -15,6 +15,10 @@ class AdminUpdateCatalogParams(TypedDict, total=False):
description: Optional[str]
+ enterprise_only: Optional[bool]
+
name: Optional[str]
+ onboarding_priority: Optional[int]
+
priority: Optional[int]
diff --git a/src/structify/types/connector_catalog/connector_catalog.py b/src/structify/types/connector_catalog/connector_catalog.py
index c68249b73..8f0b9eb5e 100644
--- a/src/structify/types/connector_catalog/connector_catalog.py
+++ b/src/structify/types/connector_catalog/connector_catalog.py
@@ -15,6 +15,8 @@ class ConnectorCatalog(BaseModel):
created_at: datetime
+ enterprise_only: bool
+
name: str
slug: str
@@ -23,4 +25,6 @@ class ConnectorCatalog(BaseModel):
description: Optional[str] = None
+ onboarding_priority: Optional[int] = None
+
priority: Optional[int] = None
diff --git a/src/structify/types/connector_catalog_list_params.py b/src/structify/types/connector_catalog_list_params.py
index 7189a9672..3ccf7f44e 100644
--- a/src/structify/types/connector_catalog_list_params.py
+++ b/src/structify/types/connector_catalog_list_params.py
@@ -5,10 +5,18 @@
from typing import Optional
from typing_extensions import TypedDict
+from .._types import SequenceNotStr
+
__all__ = ["ConnectorCatalogListParams"]
class ConnectorCatalogListParams(TypedDict, total=False):
+ categories: SequenceNotStr[str]
+ """
+ Optional category filter (exact match against any element in the categories
+ array)
+ """
+
include_inactive: bool
"""Include inactive auth methods (admin only)"""
diff --git a/src/structify/types/connector_create_params.py b/src/structify/types/connector_create_params.py
index 1f5534267..1195618b6 100644
--- a/src/structify/types/connector_create_params.py
+++ b/src/structify/types/connector_create_params.py
@@ -13,24 +13,10 @@ class ConnectorCreateParams(TypedDict, total=False):
name: Required[str]
- team_id: Required[str]
-
description: Optional[str]
nango_connection_id: Optional[str]
"""Nango connection ID for OAuth token management"""
- nango_integration_id: Optional[str]
- """Nango integration ID (e.g., "linear", "slack")"""
-
- pipedream_account_id: Optional[str]
-
- pipedream_external_id: Optional[str]
- """Unique external ID for Pipedream routing (required for Pipedream connectors)"""
-
- pipedream_project_id: Optional[str]
-
- refresh_script: Optional[str]
-
secrets: Dict[str, str]
"""Optional secrets/environment variables for the connector"""
diff --git a/src/structify/types/connector_download_datahub_artifact_params.py b/src/structify/types/connector_download_datahub_artifact_params.py
new file mode 100644
index 000000000..d62b879dd
--- /dev/null
+++ b/src/structify/types/connector_download_datahub_artifact_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ConnectorDownloadDatahubArtifactParams"]
+
+
+class ConnectorDownloadDatahubArtifactParams(TypedDict, total=False):
+ connector_id: Required[str]
+
+ exploration_run_id: Optional[str]
diff --git a/src/structify/types/connector_explore_params.py b/src/structify/types/connector_explore_params.py
index d4b23d4b9..4d94d5501 100644
--- a/src/structify/types/connector_explore_params.py
+++ b/src/structify/types/connector_explore_params.py
@@ -3,7 +3,7 @@
from __future__ import annotations
from typing import Optional
-from typing_extensions import Literal, TypedDict
+from typing_extensions import TypedDict
__all__ = ["ConnectorExploreParams"]
@@ -11,9 +11,9 @@
class ConnectorExploreParams(TypedDict, total=False):
database_id: Optional[str]
- schema_id: Optional[str]
+ only_do_datahub: Optional[bool]
+ """If true, run only DataHub ingestion without queuing Diego annotation jobs."""
- stage: Optional[Literal["both", "ingestion", "annotation"]]
- """Which exploration stage to run"""
+ schema_id: Optional[str]
table_id: Optional[str]
diff --git a/src/structify/types/connector_explore_response.py b/src/structify/types/connector_explore_response.py
new file mode 100644
index 000000000..f6dbedfce
--- /dev/null
+++ b/src/structify/types/connector_explore_response.py
@@ -0,0 +1,57 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["ConnectorExploreResponse"]
+
+
+class ConnectorExploreResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]
+
+ max_steps_without_save: int
+
+ membership_id: str
+
+ status: Literal["Queued", "Running", "Completed", "Failed"]
+
+ updated_at: datetime
+
+ use_proxy: bool
+
+ user_id: str
+
+ dataset_id: Optional[str] = None
+
+ exploration_run_id: Optional[str] = None
+
+ max_errors: Optional[int] = None
+
+ max_execution_time_secs: Optional[int] = None
+
+ max_total_steps: Optional[int] = None
+
+ message: Optional[str] = None
+ """A message about the status of the job at completion"""
+
+ node_id: Optional[str] = None
+
+ parameters: Optional[object] = None
+ """Proto for JobInput"""
+
+ reason: Optional[str] = None
+ """A reason for the job's existence"""
+
+ run_started_time: Optional[datetime] = None
+ """What time did the job start running?"""
+
+ run_time_milliseconds: Optional[int] = None
+
+ seeded_kg_search_term: Optional[str] = None
diff --git a/src/structify/types/connector_get_explorer_chat_params.py b/src/structify/types/connector_get_explorer_chat_params.py
index f84ede929..32d136fc4 100644
--- a/src/structify/types/connector_get_explorer_chat_params.py
+++ b/src/structify/types/connector_get_explorer_chat_params.py
@@ -2,11 +2,17 @@
from __future__ import annotations
-from typing_extensions import Required, TypedDict
+from typing import Optional
+from typing_extensions import TypedDict
__all__ = ["ConnectorGetExplorerChatParams"]
class ConnectorGetExplorerChatParams(TypedDict, total=False):
- run_id: Required[str]
- """Exploration run ID (required)"""
+ database_id: Optional[str]
+
+ run_id: Optional[str]
+
+ schema_id: Optional[str]
+
+ table_id: Optional[str]
diff --git a/src/structify/types/connector_get_response.py b/src/structify/types/connector_get_response.py
index f1ec3ee59..c566b553e 100644
--- a/src/structify/types/connector_get_response.py
+++ b/src/structify/types/connector_get_response.py
@@ -23,3 +23,5 @@ class ConnectorGetResponseSecret(BaseModel):
class ConnectorGetResponse(Connector):
secrets: List[ConnectorGetResponseSecret]
+
+ shared_user_ids: List[str]
diff --git a/src/structify/types/connector_list_params.py b/src/structify/types/connector_list_params.py
index 6f9c91258..7be465a02 100644
--- a/src/structify/types/connector_list_params.py
+++ b/src/structify/types/connector_list_params.py
@@ -2,15 +2,12 @@
from __future__ import annotations
-from typing_extensions import Required, TypedDict
+from typing_extensions import TypedDict
__all__ = ["ConnectorListParams"]
class ConnectorListParams(TypedDict, total=False):
- team_id: Required[str]
- """Team ID to list connectors for"""
-
limit: int
offset: int
diff --git a/src/structify/types/connector_list_stores_response.py b/src/structify/types/connector_list_stores_response.py
new file mode 100644
index 000000000..f2675f159
--- /dev/null
+++ b/src/structify/types/connector_list_stores_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict
+from typing_extensions import TypeAlias
+
+from .llm_information_store import LlmInformationStore
+
+__all__ = ["ConnectorListStoresResponse"]
+
+ConnectorListStoresResponse: TypeAlias = Dict[str, LlmInformationStore]
diff --git a/src/structify/types/connector_list_with_snippets_params.py b/src/structify/types/connector_list_with_snippets_params.py
deleted file mode 100644
index 998cd2f6b..000000000
--- a/src/structify/types/connector_list_with_snippets_params.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-__all__ = ["ConnectorListWithSnippetsParams"]
-
-
-class ConnectorListWithSnippetsParams(TypedDict, total=False):
- team_id: Required[str]
- """Team ID to list connectors for"""
diff --git a/src/structify/types/connector_search_tables_params.py b/src/structify/types/connector_search_tables_params.py
index 2f2847016..83b002eec 100644
--- a/src/structify/types/connector_search_tables_params.py
+++ b/src/structify/types/connector_search_tables_params.py
@@ -12,4 +12,4 @@ class ConnectorSearchTablesParams(TypedDict, total=False):
"""Search query string"""
team_id: Required[str]
- """Team ID to search tables for"""
+ """Team ID to scope table search"""
diff --git a/src/structify/types/connector_search_tables_response.py b/src/structify/types/connector_search_tables_response.py
index bbf3314a5..ef591a4ac 100644
--- a/src/structify/types/connector_search_tables_response.py
+++ b/src/structify/types/connector_search_tables_response.py
@@ -21,6 +21,8 @@
class RankedResultColumn(BaseModel):
"""Represents a column in a table or API resource"""
+ id: str
+
name: str
"""Name of the column"""
@@ -34,6 +36,8 @@ class RankedResultColumn(BaseModel):
class RankedResultTableColumn(BaseModel):
"""Represents a column in a table or API resource"""
+ id: str
+
name: str
"""Name of the column"""
@@ -84,6 +88,8 @@ class RankedResult(BaseModel):
class RawResultColumn(BaseModel):
"""Represents a column in a table or API resource"""
+ id: str
+
name: str
"""Name of the column"""
@@ -97,6 +103,8 @@ class RawResultColumn(BaseModel):
class RawResultTableColumn(BaseModel):
"""Represents a column in a table or API resource"""
+ id: str
+
name: str
"""Name of the column"""
diff --git a/src/structify/types/connector_summaries_params.py b/src/structify/types/connector_summaries_params.py
index 886dfcca3..46632c7f3 100644
--- a/src/structify/types/connector_summaries_params.py
+++ b/src/structify/types/connector_summaries_params.py
@@ -11,5 +11,3 @@
class ConnectorSummariesParams(TypedDict, total=False):
connector_ids: Required[SequenceNotStr[str]]
-
- team_id: Required[str]
diff --git a/src/structify/types/connector_table_path_response.py b/src/structify/types/connector_table_path_response.py
new file mode 100644
index 000000000..973e2493a
--- /dev/null
+++ b/src/structify/types/connector_table_path_response.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["ConnectorTablePathResponse"]
+
+
+class ConnectorTablePathResponse(BaseModel):
+ connector_id: str
+
+ database_name: str
+
+ schema_name: str
+
+ table_name: str
diff --git a/src/structify/types/connector_update_params.py b/src/structify/types/connector_update_params.py
index 51ffbed78..9b1a14456 100644
--- a/src/structify/types/connector_update_params.py
+++ b/src/structify/types/connector_update_params.py
@@ -3,18 +3,44 @@
from __future__ import annotations
from typing import Optional
-from typing_extensions import TypedDict
+from typing_extensions import Literal, TypedDict
+
+from .._types import SequenceNotStr
+from .connector_category import ConnectorCategory
+from .datahub_secret_map_param import DatahubSecretMapParam
__all__ = ["ConnectorUpdateParams"]
class ConnectorUpdateParams(TypedDict, total=False):
+ connector_category: Optional[ConnectorCategory]
+
+ datahub_ingestion_type: Optional[str]
+
+ datahub_secret_map: Optional[DatahubSecretMapParam]
+ """
+ Maps DatahubIngestionKey to the name of the connector secret that holds the
+ value.
+ """
+
+ datahub_urn: Optional[str]
+
description: Optional[str]
known_connector_type: Optional[str]
name: Optional[str]
- refresh_script: Optional[str]
+ nango_connection_id: Optional[str]
+
+ oauth_scopes: Optional[SequenceNotStr[Optional[str]]]
+
+ owner_user_id: Optional[str]
+
+ refresh_cron_schedule: Optional[str]
+
+ team_visibility: Optional[Literal["Team", "Private"]]
usage_snippet_override: Optional[str]
+
+ user_ids: Optional[SequenceNotStr[str]]
diff --git a/src/structify/types/connector_upload_datahub_artifact_params.py b/src/structify/types/connector_upload_datahub_artifact_params.py
new file mode 100644
index 000000000..d7e22d8f5
--- /dev/null
+++ b/src/structify/types/connector_upload_datahub_artifact_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .._types import FileTypes
+
+__all__ = ["ConnectorUploadDatahubArtifactParams"]
+
+
+class ConnectorUploadDatahubArtifactParams(TypedDict, total=False):
+ connector_id: Required[str]
+
+ exploration_run_id: Required[str]
+
+ file: Required[FileTypes]
diff --git a/src/structify/types/connector_with_secrets.py b/src/structify/types/connector_with_secrets.py
index 6f471b74d..0e8a26b76 100644
--- a/src/structify/types/connector_with_secrets.py
+++ b/src/structify/types/connector_with_secrets.py
@@ -12,8 +12,6 @@
class ConnectorWithSecretsSecret(BaseModel):
"""Response model for listing secrets (without sensitive data)"""
- id: str
-
created_at: datetime
secret_name: str
diff --git a/src/structify/types/dashboard_item.py b/src/structify/types/dashboard_item.py
new file mode 100644
index 000000000..586b4755c
--- /dev/null
+++ b/src/structify/types/dashboard_item.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+from .dashboard_spec import DashboardSpec
+
+__all__ = ["DashboardItem"]
+
+
+class DashboardItem(BaseModel):
+ file_name: str
+ """File path relative to repository root."""
+
+ spec: DashboardSpec
diff --git a/src/structify/types/dashboard_spec.py b/src/structify/types/dashboard_spec.py
new file mode 100644
index 000000000..5bc8dbc38
--- /dev/null
+++ b/src/structify/types/dashboard_spec.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List
+
+from .._models import BaseModel
+from .viz_param import VizParam
+from .viz_query import VizQuery
+from .viz_figure import VizFigure
+
+__all__ = ["DashboardSpec"]
+
+
+class DashboardSpec(BaseModel):
+ dataset: str
+
+ description: str
+
+ figures: List[VizFigure]
+
+ params: Dict[str, VizParam]
+
+ queries: List[VizQuery]
+
+ title: str
+
+ version: str
diff --git a/src/structify/types/dashboard_spec_param.py b/src/structify/types/dashboard_spec_param.py
new file mode 100644
index 000000000..baa9907f6
--- /dev/null
+++ b/src/structify/types/dashboard_spec_param.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Iterable
+from typing_extensions import Required, TypedDict
+
+from .viz_param_param import VizParamParam
+from .viz_query_param import VizQueryParam
+from .viz_figure_param import VizFigureParam
+
+__all__ = ["DashboardSpecParam"]
+
+
+class DashboardSpecParam(TypedDict, total=False):
+ dataset: Required[str]
+
+ description: Required[str]
+
+ figures: Required[Iterable[VizFigureParam]]
+
+ params: Required[Dict[str, VizParamParam]]
+
+ queries: Required[Iterable[VizQueryParam]]
+
+ title: Required[str]
+
+ version: Required[str]
diff --git a/src/structify/types/datahub_progress.py b/src/structify/types/datahub_progress.py
new file mode 100644
index 000000000..5fd316fa6
--- /dev/null
+++ b/src/structify/types/datahub_progress.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DatahubProgress"]
+
+
+class DatahubProgress(BaseModel):
+ databases_created: int
+
+ job_id: str
+
+ job_status: Literal["Queued", "Running", "Completed", "Failed"]
+
+ pages_fetched: int
+
+ records_written: int
+
+ schemas_created: int
+
+ tables_processed: int
+
+ total_datasets: int
diff --git a/src/structify/types/datahub_secret_map.py b/src/structify/types/datahub_secret_map.py
new file mode 100644
index 000000000..bf80a823b
--- /dev/null
+++ b/src/structify/types/datahub_secret_map.py
@@ -0,0 +1,8 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict
+from typing_extensions import TypeAlias
+
+__all__ = ["DatahubSecretMap"]
+
+DatahubSecretMap: TypeAlias = Dict[str, str]
diff --git a/src/structify/types/datahub_secret_map_param.py b/src/structify/types/datahub_secret_map_param.py
new file mode 100644
index 000000000..6cd1d2874
--- /dev/null
+++ b/src/structify/types/datahub_secret_map_param.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict
+from typing_extensions import TypeAlias
+
+__all__ = ["DatahubSecretMapParam"]
+
+DatahubSecretMapParam: TypeAlias = Dict[str, str]
diff --git a/src/structify/types/dataset_view_table_response.py b/src/structify/types/dataset_view_table_response.py
index 2080355a2..18e546830 100644
--- a/src/structify/types/dataset_view_table_response.py
+++ b/src/structify/types/dataset_view_table_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List, Union, Optional
+from typing import Dict, Union, Optional
from datetime import datetime
from typing_extensions import Literal, TypeAlias
@@ -103,10 +103,10 @@ class DatasetViewTableResponse(BaseModel):
dataset_id: str
- job_ids: List[str]
-
label: str
properties: Dict[str, Properties]
updated_at: datetime
+
+ job_id: Optional[str] = None
diff --git a/src/structify/types/dataset_view_tables_with_relationships_response.py b/src/structify/types/dataset_view_tables_with_relationships_response.py
index 2dbf55099..72ecfb24f 100644
--- a/src/structify/types/dataset_view_tables_with_relationships_response.py
+++ b/src/structify/types/dataset_view_tables_with_relationships_response.py
@@ -118,14 +118,14 @@ class ConnectedEntity(BaseModel):
dataset_id: str
- job_ids: List[str]
-
label: str
properties: Dict[str, ConnectedEntityProperties]
updated_at: datetime
+ job_id: Optional[str] = None
+
class EntityPropertiesPartialDateObject(BaseModel):
original_string: str
@@ -212,14 +212,14 @@ class Entity(BaseModel):
dataset_id: str
- job_ids: List[str]
-
label: str
properties: Dict[str, EntityProperties]
updated_at: datetime
+ job_id: Optional[str] = None
+
class RelationshipPropertiesPartialDateObject(BaseModel):
original_string: str
diff --git a/src/structify/types/entity_get_local_subgraph_response.py b/src/structify/types/entity_get_local_subgraph_response.py
index e3ed1bcb7..eeb9e4348 100644
--- a/src/structify/types/entity_get_local_subgraph_response.py
+++ b/src/structify/types/entity_get_local_subgraph_response.py
@@ -117,6 +117,8 @@ class Neighbor(BaseModel):
updated_at: datetime
+ job_id: Optional[str] = None
+
class RelationshipPropertiesPartialDateObject(BaseModel):
original_string: str
diff --git a/src/structify/types/entity_get_response.py b/src/structify/types/entity_get_response.py
index fb913d686..43e98a9a2 100644
--- a/src/structify/types/entity_get_response.py
+++ b/src/structify/types/entity_get_response.py
@@ -108,3 +108,5 @@ class EntityGetResponse(BaseModel):
properties: Dict[str, Properties]
updated_at: datetime
+
+ job_id: Optional[str] = None
diff --git a/src/structify/types/entity_list_jobs_response.py b/src/structify/types/entity_list_jobs_response.py
index 1bcedcda2..85ddcb6dc 100644
--- a/src/structify/types/entity_list_jobs_response.py
+++ b/src/structify/types/entity_list_jobs_response.py
@@ -14,9 +14,7 @@ class EntityListJobsResponseItem(BaseModel):
created_at: datetime
- dataset_id: str
-
- job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore"]
+ job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]
max_steps_without_save: int
@@ -30,6 +28,10 @@ class EntityListJobsResponseItem(BaseModel):
user_id: str
+ dataset_id: Optional[str] = None
+
+ exploration_run_id: Optional[str] = None
+
max_errors: Optional[int] = None
max_execution_time_secs: Optional[int] = None
diff --git a/src/structify/types/entity_search_response.py b/src/structify/types/entity_search_response.py
index 5edf5eca8..ef9e15d45 100644
--- a/src/structify/types/entity_search_response.py
+++ b/src/structify/types/entity_search_response.py
@@ -110,5 +110,7 @@ class EntitySearchResponseItem(BaseModel):
updated_at: datetime
+ job_id: Optional[str] = None
+
EntitySearchResponse: TypeAlias = List[EntitySearchResponseItem]
diff --git a/src/structify/types/entity_summarize_response.py b/src/structify/types/entity_summarize_response.py
index c1eecbfde..7ce3c6dde 100644
--- a/src/structify/types/entity_summarize_response.py
+++ b/src/structify/types/entity_summarize_response.py
@@ -110,5 +110,7 @@ class EntitySummarizeResponseItem(BaseModel):
updated_at: datetime
+ job_id: Optional[str] = None
+
EntitySummarizeResponse: TypeAlias = List[EntitySummarizeResponseItem]
diff --git a/src/structify/types/entity_update_property_response.py b/src/structify/types/entity_update_property_response.py
index 9d0e10065..015a19568 100644
--- a/src/structify/types/entity_update_property_response.py
+++ b/src/structify/types/entity_update_property_response.py
@@ -108,3 +108,5 @@ class EntityUpdatePropertyResponse(BaseModel):
properties: Dict[str, Properties]
updated_at: datetime
+
+ job_id: Optional[str] = None
diff --git a/src/structify/types/entity_view_response.py b/src/structify/types/entity_view_response.py
index d66212f6f..7bba540f1 100644
--- a/src/structify/types/entity_view_response.py
+++ b/src/structify/types/entity_view_response.py
@@ -142,6 +142,8 @@ class ConnectedEntity(BaseModel):
updated_at: datetime
+ job_id: Optional[str] = None
+
class EntityPropertiesPartialDateObject(BaseModel):
original_string: str
@@ -234,6 +236,8 @@ class Entity(BaseModel):
updated_at: datetime
+ job_id: Optional[str] = None
+
class RelationshipPropertiesPartialDateObject(BaseModel):
original_string: str
@@ -422,6 +426,8 @@ class SimilarEntity(BaseModel):
updated_at: datetime
+ job_id: Optional[str] = None
+
class SourceLocationTextText(BaseModel):
byte_offset: int
diff --git a/src/structify/types/exploration_progress.py b/src/structify/types/exploration_progress.py
new file mode 100644
index 000000000..2b3d4f515
--- /dev/null
+++ b/src/structify/types/exploration_progress.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from .._models import BaseModel
+from .phase_activity import PhaseActivity
+from .datahub_progress import DatahubProgress
+
+__all__ = ["ExplorationProgress"]
+
+
+class ExplorationProgress(BaseModel):
+ phases: List[PhaseActivity]
+
+ datahub: Optional[DatahubProgress] = None
diff --git a/src/structify/types/exploration_run.py b/src/structify/types/exploration_run.py
index ff4368f5a..e4bb3798a 100644
--- a/src/structify/types/exploration_run.py
+++ b/src/structify/types/exploration_run.py
@@ -1,13 +1,25 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from typing import Optional
from datetime import datetime
from .._models import BaseModel
+from .exploration_status import ExplorationStatus
__all__ = ["ExplorationRun"]
class ExplorationRun(BaseModel):
+ id: str
+
+ connector_id: str
+
created_at: datetime
- run_id: str
+ status: ExplorationStatus
+
+ checkpoint_blob_name: Optional[str] = None
+
+ latest_snapshot_blob_name: Optional[str] = None
+
+ triggered_by: Optional[str] = None
diff --git a/src/structify/types/explore_status_response.py b/src/structify/types/explore_status_response.py
deleted file mode 100644
index 475324a99..000000000
--- a/src/structify/types/explore_status_response.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-
-from .._models import BaseModel
-from .exploration_status import ExplorationStatus
-
-__all__ = ["ExploreStatusResponse"]
-
-
-class ExploreStatusResponse(BaseModel):
- status: ExplorationStatus
-
- error: Optional[str] = None
-
- started_at: Optional[datetime] = None
diff --git a/src/structify/types/get_chat_session_response.py b/src/structify/types/get_chat_session_response.py
index 5ad205a0d..3a31d94ed 100644
--- a/src/structify/types/get_chat_session_response.py
+++ b/src/structify/types/get_chat_session_response.py
@@ -7,6 +7,7 @@
from .._models import BaseModel
from .chat_event import ChatEvent
from .chat_visibility import ChatVisibility
+from .workflow_session import WorkflowSession
from .chat_session_role import ChatSessionRole
__all__ = ["GetChatSessionResponse", "Session", "SessionCommit", "SessionMessage"]
@@ -37,6 +38,10 @@ class SessionMessage(BaseModel):
timestamp: datetime
+ git_hash: Optional[str] = None
+
+ previous_message_id: Optional[str] = None
+
class Session(BaseModel):
id: str
@@ -45,6 +50,8 @@ class Session(BaseModel):
created_at: datetime
+ ephemeral: bool
+
git_application_token: str
is_favorite: bool
@@ -63,8 +70,14 @@ class Session(BaseModel):
visibility: ChatVisibility
+ workflow_sessions: List[WorkflowSession]
+
+ instantiated_from_template_id: Optional[str] = None
+
latest_workflow_session_id: Optional[str] = None
+ message_head: Optional[str] = None
+
name: Optional[str] = None
project_id: Optional[str] = None
diff --git a/src/structify/types/get_onboarding_answers_response.py b/src/structify/types/get_onboarding_answers_response.py
new file mode 100644
index 000000000..cada36acc
--- /dev/null
+++ b/src/structify/types/get_onboarding_answers_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+from .onboarding_answers import OnboardingAnswers
+
+__all__ = ["GetOnboardingAnswersResponse"]
+
+
+class GetOnboardingAnswersResponse(BaseModel):
+ answers: OnboardingAnswers
diff --git a/src/structify/types/job_cancel_response.py b/src/structify/types/job_cancel_response.py
index 640fcf079..01f4a4293 100644
--- a/src/structify/types/job_cancel_response.py
+++ b/src/structify/types/job_cancel_response.py
@@ -14,9 +14,7 @@ class JobCancelResponse(BaseModel):
created_at: datetime
- dataset_id: str
-
- job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore"]
+ job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]
max_steps_without_save: int
@@ -30,6 +28,10 @@ class JobCancelResponse(BaseModel):
user_id: str
+ dataset_id: Optional[str] = None
+
+ exploration_run_id: Optional[str] = None
+
max_errors: Optional[int] = None
max_execution_time_secs: Optional[int] = None
diff --git a/src/structify/types/job_event_body.py b/src/structify/types/job_event_body.py
index 85f1e3f9f..d35bb49af 100644
--- a/src/structify/types/job_event_body.py
+++ b/src/structify/types/job_event_body.py
@@ -24,6 +24,8 @@
"DatahubDatabasesCreated",
"DatahubSchemasCreated",
"DatahubTablesProcessed",
+ "DatahubAnnotationsQueued",
+ "DatahubIngestionProgress",
"DatahubEmbeddingBatch",
"ViewedPdfPage",
]
@@ -167,9 +169,25 @@ class DatahubTablesProcessed(BaseModel):
tables_failed: int
+ tables_removed: int
+
tables_updated: int
+class DatahubAnnotationsQueued(BaseModel):
+ diff_annotations_queued: int
+
+ event_type: Literal["datahub_annotations_queued"]
+
+ full_annotations_queued: int
+
+
+class DatahubIngestionProgress(BaseModel):
+ event_type: Literal["datahub_ingestion_progress"]
+
+ records_written: int
+
+
class DatahubEmbeddingBatch(BaseModel):
batch_num: int
@@ -203,6 +221,8 @@ class ViewedPdfPage(BaseModel):
DatahubDatabasesCreated,
DatahubSchemasCreated,
DatahubTablesProcessed,
+ DatahubAnnotationsQueued,
+ DatahubIngestionProgress,
DatahubEmbeddingBatch,
ViewedPdfPage,
],
diff --git a/src/structify/types/job_get_response.py b/src/structify/types/job_get_response.py
new file mode 100644
index 000000000..82961dcbf
--- /dev/null
+++ b/src/structify/types/job_get_response.py
@@ -0,0 +1,368 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from .image import Image
+from .source import Source
+from .._models import BaseModel
+from .chat_event import ChatEvent
+from .chat_prompt import ChatPrompt
+from .knowledge_graph import KnowledgeGraph
+from .save_requirement import SaveRequirement
+from .exploration_phase_id import ExplorationPhaseID
+
+__all__ = [
+ "JobGetResponse",
+ "Agent",
+ "Info",
+ "InfoParameters",
+ "InfoParametersStructuringInput",
+ "InfoParametersStructuringInputAgent",
+ "InfoParametersStructuringInputAgentAgent",
+ "InfoParametersStructuringInputAgentAgentPdf",
+ "InfoParametersStructuringInputAgentAgentPdfPdf",
+ "InfoParametersStructuringInputAgentAgentWeb",
+ "InfoParametersStructuringInputAgentAgentWebWeb",
+ "InfoParametersStructuringInputTransformationPrompt",
+ "InfoParametersStructuringInputScrapeFromURLProperty",
+ "InfoParametersStructuringInputScrapeFromURLPropertyScrapeFromURLProperty",
+ "InfoParametersStructuringInputScrapeURL",
+ "InfoParametersStructuringInputScrapeURLScrapeURL",
+ "InfoParametersStructuringInputDatahubIngestion",
+ "InfoParametersStructuringInputDatahubIngestionDatahubIngestion",
+ "InfoParametersStructuringInputConnectorExploration",
+ "InfoParametersStructuringInputConnectorExplorationConnectorExploration",
+ "Saved",
+ "SavedProperties",
+ "SavedPropertiesPartialDateObject",
+ "SavedPropertiesURLObject",
+ "SavedPropertiesMoneyObject",
+ "SavedPropertiesPersonName",
+ "SavedPropertiesAddressObject",
+ "SavedLocation",
+ "SavedLocationText",
+ "SavedLocationTextText",
+ "SavedLocationVisual",
+ "SavedLocationVisualVisual",
+ "SavedLocationPage",
+ "SavedLocationPagePage",
+]
+
+
+class Agent(BaseModel):
+ base_url: str
+
+ is_newly_created: bool
+
+ scraper_created_at: datetime
+
+ scraper_id: str
+
+ scraper_updated_at: datetime
+
+ chat: Optional[ChatPrompt] = None
+
+ code: Optional[str] = None
+
+ events: Optional[List[ChatEvent]] = None
+
+ next_page_code: Optional[str] = None
+
+
+class InfoParametersStructuringInputAgentAgentPdfPdf(BaseModel):
+ """Ingest all pages of a PDF and process them independently."""
+
+ path: str
+
+ page: Optional[int] = None
+
+
+class InfoParametersStructuringInputAgentAgentPdf(BaseModel):
+ pdf: InfoParametersStructuringInputAgentAgentPdfPdf = FieldInfo(alias="PDF")
+ """Ingest all pages of a PDF and process them independently."""
+
+
+class InfoParametersStructuringInputAgentAgentWebWeb(BaseModel):
+ banned_domains: Optional[List[str]] = None
+
+ starting_searches: Optional[List[str]] = None
+
+ starting_urls: Optional[List[str]] = None
+
+
+class InfoParametersStructuringInputAgentAgentWeb(BaseModel):
+ web: InfoParametersStructuringInputAgentAgentWebWeb = FieldInfo(alias="Web")
+
+
+InfoParametersStructuringInputAgentAgent: TypeAlias = Union[
+ InfoParametersStructuringInputAgentAgentPdf, InfoParametersStructuringInputAgentAgentWeb
+]
+
+
+class InfoParametersStructuringInputAgent(BaseModel):
+ agent: InfoParametersStructuringInputAgentAgent = FieldInfo(alias="Agent")
+
+
+class InfoParametersStructuringInputTransformationPrompt(BaseModel):
+ transformation_prompt: str = FieldInfo(alias="TransformationPrompt")
+
+
+class InfoParametersStructuringInputScrapeFromURLPropertyScrapeFromURLProperty(BaseModel):
+ batch_scrape: bool
+
+ url_property_name: str
+
+ use_markdown: bool
+
+
+class InfoParametersStructuringInputScrapeFromURLProperty(BaseModel):
+ scrape_from_url_property: InfoParametersStructuringInputScrapeFromURLPropertyScrapeFromURLProperty = FieldInfo(
+ alias="ScrapeFromUrlProperty"
+ )
+
+
+class InfoParametersStructuringInputScrapeURLScrapeURL(BaseModel):
+ batch_scrape: bool
+
+ url: str
+
+ use_markdown: bool
+
+
+class InfoParametersStructuringInputScrapeURL(BaseModel):
+ scrape_url: InfoParametersStructuringInputScrapeURLScrapeURL = FieldInfo(alias="ScrapeUrl")
+
+
+class InfoParametersStructuringInputDatahubIngestionDatahubIngestion(BaseModel):
+ connector_id: str
+
+ exploration_run_id: str
+
+ only_do_datahub: bool
+
+
+class InfoParametersStructuringInputDatahubIngestion(BaseModel):
+ datahub_ingestion: InfoParametersStructuringInputDatahubIngestionDatahubIngestion = FieldInfo(
+ alias="DatahubIngestion"
+ )
+
+
+class InfoParametersStructuringInputConnectorExplorationConnectorExploration(BaseModel):
+ connector_id: str
+
+ exploration_phase_id: ExplorationPhaseID
+ """Identifies the phase of connector exploration
+
+ This enum is used to track which phase of exploration a chat session belongs to.
+ It's stored as JSONB in the database to allow for flexible phase identification.
+ """
+
+ exploration_run_id: str
+
+ strategy: Literal["full", "diff"]
+
+
+class InfoParametersStructuringInputConnectorExploration(BaseModel):
+ connector_exploration: InfoParametersStructuringInputConnectorExplorationConnectorExploration = FieldInfo(
+ alias="ConnectorExploration"
+ )
+
+
+InfoParametersStructuringInput: TypeAlias = Union[
+ InfoParametersStructuringInputAgent,
+ InfoParametersStructuringInputTransformationPrompt,
+ InfoParametersStructuringInputScrapeFromURLProperty,
+ InfoParametersStructuringInputScrapeURL,
+ InfoParametersStructuringInputDatahubIngestion,
+ InfoParametersStructuringInputConnectorExploration,
+]
+
+
+class InfoParameters(BaseModel):
+ allow_extra_entities: bool
+
+ extraction_criteria: List[SaveRequirement]
+
+ structuring_input: InfoParametersStructuringInput
+
+ instructions: Optional[str] = None
+
+ model: Optional[str] = None
+
+ seeded_kg: Optional[KnowledgeGraph] = None
+ """
+ Knowledge graph info structured to deserialize and display in the same format
+ that the LLM outputs. Also the first representation of an LLM output in the
+ pipeline from raw tool output to being merged into a DB
+ """
+
+
+class Info(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]
+
+ status: Literal["Queued", "Running", "Completed", "Failed"]
+
+ user_id: str
+
+ dataset_id: Optional[str] = None
+
+ message: Optional[str] = None
+
+ parameters: Optional[InfoParameters] = None
+
+ reason: Optional[str] = None
+
+ run_started_time: Optional[datetime] = None
+
+ run_time_milliseconds: Optional[int] = None
+
+
+class SavedPropertiesPartialDateObject(BaseModel):
+ original_string: str
+
+ year: int
+
+ day: Optional[int] = None
+
+ month: Optional[int] = None
+
+
+class SavedPropertiesURLObject(BaseModel):
+ original_string: str
+
+ url: str
+
+
+class SavedPropertiesMoneyObject(BaseModel):
+ amount: float
+
+ currency_code: Literal[
+ "USD",
+ "EUR",
+ "GBP",
+ "JPY",
+ "CNY",
+ "INR",
+ "RUB",
+ "CAD",
+ "AUD",
+ "CHF",
+ "ILS",
+ "NZD",
+ "SGD",
+ "HKD",
+ "NOK",
+ "SEK",
+ "PLN",
+ "TRY",
+ "DKK",
+ "MXN",
+ "ZAR",
+ "PHP",
+ "VND",
+ "THB",
+ "BRL",
+ "KRW",
+ ]
+
+ original_string: str
+
+
+class SavedPropertiesPersonName(BaseModel):
+ name: str
+
+
+class SavedPropertiesAddressObject(BaseModel):
+ components: Dict[str, str]
+
+ original_address: str
+
+
+SavedProperties: TypeAlias = Union[
+ str,
+ bool,
+ float,
+ SavedPropertiesPartialDateObject,
+ str,
+ str,
+ SavedPropertiesURLObject,
+ str,
+ SavedPropertiesMoneyObject,
+ Image,
+ SavedPropertiesPersonName,
+ SavedPropertiesAddressObject,
+ str,
+]
+
+
+class SavedLocationTextText(BaseModel):
+ byte_offset: int
+
+
+class SavedLocationText(BaseModel):
+ text: SavedLocationTextText = FieldInfo(alias="Text")
+
+
+class SavedLocationVisualVisual(BaseModel):
+ x: int
+
+ y: int
+
+
+class SavedLocationVisual(BaseModel):
+ visual: SavedLocationVisualVisual = FieldInfo(alias="Visual")
+
+
+class SavedLocationPagePage(BaseModel):
+ page_number: int
+
+
+class SavedLocationPage(BaseModel):
+ page: SavedLocationPagePage = FieldInfo(alias="Page")
+
+
+SavedLocation: TypeAlias = Union[SavedLocationText, SavedLocationVisual, SavedLocationPage, None]
+
+
+class Saved(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ is_summary: bool
+
+ label: str
+
+ llm_id: int
+
+ properties: Dict[str, SavedProperties]
+
+ source_id: str
+
+ user_specified: bool
+
+ job_id: Optional[str] = None
+
+ kg_entity_id: Optional[str] = None
+
+ link: Optional[Source] = None
+
+ location: Optional[SavedLocation] = None
+
+ scraper_id: Optional[str] = None
+
+
+class JobGetResponse(BaseModel):
+ agents: List[Agent]
+
+ info: Info
+
+ saved: List[List[Saved]]
diff --git a/src/structify/types/job_get_scrapers_response.py b/src/structify/types/job_get_scrapers_response.py
deleted file mode 100644
index d22f6a616..000000000
--- a/src/structify/types/job_get_scrapers_response.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import TypeAlias
-
-from .._models import BaseModel
-from .chat_event import ChatEvent
-from .chat_prompt import ChatPrompt
-
-__all__ = ["JobGetScrapersResponse", "JobGetScrapersResponseItem"]
-
-
-class JobGetScrapersResponseItem(BaseModel):
- base_url: str
-
- is_newly_created: bool
-
- scraper_created_at: datetime
-
- scraper_id: str
-
- scraper_updated_at: datetime
-
- chat: Optional[ChatPrompt] = None
-
- code: Optional[str] = None
-
- events: Optional[List[ChatEvent]] = None
-
- next_page_code: Optional[str] = None
-
-
-JobGetScrapersResponse: TypeAlias = List[JobGetScrapersResponseItem]
diff --git a/src/structify/types/job_get_source_entities_response.py b/src/structify/types/job_get_source_entities_response.py
deleted file mode 100644
index a43f7932b..000000000
--- a/src/structify/types/job_get_source_entities_response.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Dict, List, Union, Optional
-from datetime import datetime
-from typing_extensions import Literal, TypeAlias
-
-from pydantic import Field as FieldInfo
-
-from .image import Image
-from .source import Source
-from .._models import BaseModel
-
-__all__ = [
- "JobGetSourceEntitiesResponse",
- "SourceEntity",
- "SourceEntityProperties",
- "SourceEntityPropertiesPartialDateObject",
- "SourceEntityPropertiesURLObject",
- "SourceEntityPropertiesMoneyObject",
- "SourceEntityPropertiesPersonName",
- "SourceEntityPropertiesAddressObject",
- "SourceEntityLocation",
- "SourceEntityLocationText",
- "SourceEntityLocationTextText",
- "SourceEntityLocationVisual",
- "SourceEntityLocationVisualVisual",
- "SourceEntityLocationPage",
- "SourceEntityLocationPagePage",
-]
-
-
-class SourceEntityPropertiesPartialDateObject(BaseModel):
- original_string: str
-
- year: int
-
- day: Optional[int] = None
-
- month: Optional[int] = None
-
-
-class SourceEntityPropertiesURLObject(BaseModel):
- original_string: str
-
- url: str
-
-
-class SourceEntityPropertiesMoneyObject(BaseModel):
- amount: float
-
- currency_code: Literal[
- "USD",
- "EUR",
- "GBP",
- "JPY",
- "CNY",
- "INR",
- "RUB",
- "CAD",
- "AUD",
- "CHF",
- "ILS",
- "NZD",
- "SGD",
- "HKD",
- "NOK",
- "SEK",
- "PLN",
- "TRY",
- "DKK",
- "MXN",
- "ZAR",
- "PHP",
- "VND",
- "THB",
- "BRL",
- "KRW",
- ]
-
- original_string: str
-
-
-class SourceEntityPropertiesPersonName(BaseModel):
- name: str
-
-
-class SourceEntityPropertiesAddressObject(BaseModel):
- components: Dict[str, str]
-
- original_address: str
-
-
-SourceEntityProperties: TypeAlias = Union[
- str,
- bool,
- float,
- SourceEntityPropertiesPartialDateObject,
- str,
- str,
- SourceEntityPropertiesURLObject,
- str,
- SourceEntityPropertiesMoneyObject,
- Image,
- SourceEntityPropertiesPersonName,
- SourceEntityPropertiesAddressObject,
- str,
-]
-
-
-class SourceEntityLocationTextText(BaseModel):
- byte_offset: int
-
-
-class SourceEntityLocationText(BaseModel):
- text: SourceEntityLocationTextText = FieldInfo(alias="Text")
-
-
-class SourceEntityLocationVisualVisual(BaseModel):
- x: int
-
- y: int
-
-
-class SourceEntityLocationVisual(BaseModel):
- visual: SourceEntityLocationVisualVisual = FieldInfo(alias="Visual")
-
-
-class SourceEntityLocationPagePage(BaseModel):
- page_number: int
-
-
-class SourceEntityLocationPage(BaseModel):
- page: SourceEntityLocationPagePage = FieldInfo(alias="Page")
-
-
-SourceEntityLocation: TypeAlias = Union[
- SourceEntityLocationText, SourceEntityLocationVisual, SourceEntityLocationPage, None
-]
-
-
-class SourceEntity(BaseModel):
- id: str
-
- created_at: datetime
-
- is_summary: bool
-
- label: str
-
- llm_id: int
-
- properties: Dict[str, SourceEntityProperties]
-
- source_id: str
-
- user_specified: bool
-
- job_id: Optional[str] = None
-
- kg_entity_id: Optional[str] = None
-
- link: Optional[Source] = None
-
- location: Optional[SourceEntityLocation] = None
-
- scraper_id: Optional[str] = None
-
-
-class JobGetSourceEntitiesResponse(BaseModel):
- source_entities: List[List[SourceEntity]]
diff --git a/src/structify/types/job_list_params.py b/src/structify/types/job_list_params.py
index e13064899..d93b17726 100644
--- a/src/structify/types/job_list_params.py
+++ b/src/structify/types/job_list_params.py
@@ -15,7 +15,7 @@ class JobListParams(TypedDict, total=False):
dataset: Optional[str]
"""Dataset name to optionally filter jobs by"""
- job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore"]]
+ job_type: Optional[Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]]
"""Type of job to optionally filter jobs by"""
limit: int
diff --git a/src/structify/types/job_list_response.py b/src/structify/types/job_list_response.py
index 4ed6da86a..122fbeb06 100644
--- a/src/structify/types/job_list_response.py
+++ b/src/structify/types/job_list_response.py
@@ -26,6 +26,8 @@
"ParametersStructuringInputScrapeFromURLPropertyScrapeFromURLProperty",
"ParametersStructuringInputScrapeURL",
"ParametersStructuringInputScrapeURLScrapeURL",
+ "ParametersStructuringInputDatahubIngestion",
+ "ParametersStructuringInputDatahubIngestionDatahubIngestion",
"ParametersStructuringInputConnectorExploration",
"ParametersStructuringInputConnectorExplorationConnectorExploration",
]
@@ -95,6 +97,18 @@ class ParametersStructuringInputScrapeURL(BaseModel):
scrape_url: ParametersStructuringInputScrapeURLScrapeURL = FieldInfo(alias="ScrapeUrl")
+class ParametersStructuringInputDatahubIngestionDatahubIngestion(BaseModel):
+ connector_id: str
+
+ exploration_run_id: str
+
+ only_do_datahub: bool
+
+
+class ParametersStructuringInputDatahubIngestion(BaseModel):
+ datahub_ingestion: ParametersStructuringInputDatahubIngestionDatahubIngestion = FieldInfo(alias="DatahubIngestion")
+
+
class ParametersStructuringInputConnectorExplorationConnectorExploration(BaseModel):
connector_id: str
@@ -107,8 +121,7 @@ class ParametersStructuringInputConnectorExplorationConnectorExploration(BaseMod
exploration_run_id: str
- stage: Literal["both", "ingestion", "annotation"]
- """Which exploration stage to run"""
+ strategy: Literal["full", "diff"]
class ParametersStructuringInputConnectorExploration(BaseModel):
@@ -122,6 +135,7 @@ class ParametersStructuringInputConnectorExploration(BaseModel):
ParametersStructuringInputTransformationPrompt,
ParametersStructuringInputScrapeFromURLProperty,
ParametersStructuringInputScrapeURL,
+ ParametersStructuringInputDatahubIngestion,
ParametersStructuringInputConnectorExploration,
]
@@ -131,33 +145,33 @@ class Parameters(BaseModel):
extraction_criteria: List[SaveRequirement]
- seeded_kg: KnowledgeGraph
- """
- Knowledge graph info structured to deserialize and display in the same format
- that the LLM outputs. Also the first representation of an LLM output in the
- pipeline from raw tool output to being merged into a DB
- """
-
structuring_input: ParametersStructuringInput
instructions: Optional[str] = None
model: Optional[str] = None
+ seeded_kg: Optional[KnowledgeGraph] = None
+ """
+ Knowledge graph info structured to deserialize and display in the same format
+ that the LLM outputs. Also the first representation of an LLM output in the
+ pipeline from raw tool output to being merged into a DB
+ """
+
class JobListResponse(BaseModel):
id: str
created_at: datetime
- dataset_id: str
-
- job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore"]
+ job_type: Literal["Web", "Pdf", "Derive", "Scrape", "Match", "ConnectorExplore", "DatahubIngestion"]
status: Literal["Queued", "Running", "Completed", "Failed"]
user_id: str
+ dataset_id: Optional[str] = None
+
message: Optional[str] = None
parameters: Optional[Parameters] = None
@@ -167,5 +181,3 @@ class JobListResponse(BaseModel):
run_started_time: Optional[datetime] = None
run_time_milliseconds: Optional[int] = None
-
- special_job_type: Optional[Literal["HumanLLM"]] = None
diff --git a/src/structify/types/list_chat_sessions_response.py b/src/structify/types/list_chat_sessions_response.py
index cdfc2307e..320833ee3 100644
--- a/src/structify/types/list_chat_sessions_response.py
+++ b/src/structify/types/list_chat_sessions_response.py
@@ -7,7 +7,7 @@
from .chat_visibility import ChatVisibility
from .chat_session_role import ChatSessionRole
-__all__ = ["ListChatSessionsResponse", "Session"]
+__all__ = ["ListChatSessionsResponse", "Session", "TabCounts"]
class Session(BaseModel):
@@ -15,6 +15,8 @@ class Session(BaseModel):
created_at: datetime
+ has_workflow_schedule: bool
+
is_favorite: bool
team_id: str
@@ -33,8 +35,36 @@ class Session(BaseModel):
project_id: Optional[str] = None
+ slack_channel_id: Optional[str] = None
+
+ teams_channel_id: Optional[str] = None
+
+ teams_conversation_id: Optional[str] = None
+
+
+class TabCounts(BaseModel):
+ """Per-tab counts for chat session listing"""
+
+ favorites: int
+
+ from_messaging: int
+
+ my_chats: int
+
+ recents: int
+
+ shared: int
+
+ team: int
+
class ListChatSessionsResponse(BaseModel):
"""Response for listing chat sessions"""
sessions: List[Session]
+
+ tab_counts: TabCounts
+ """Per-tab counts for chat session listing"""
+
+ total_count: int
+ """Total number of chat sessions matching the query (for pagination)"""
diff --git a/src/structify/types/list_dashboards_response.py b/src/structify/types/list_dashboards_response.py
new file mode 100644
index 000000000..b25e00c74
--- /dev/null
+++ b/src/structify/types/list_dashboards_response.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from .._models import BaseModel
+from .dashboard_item import DashboardItem
+
+__all__ = ["ListDashboardsResponse"]
+
+
+class ListDashboardsResponse(BaseModel):
+ commit_hash: str
+ """Commit hash used to load dashboard specs."""
+
+ dashboards: List[DashboardItem]
+ """All dashboard specs in src/visualizations/\\**.viz.json."""
diff --git a/src/structify/types/llm_information_store.py b/src/structify/types/llm_information_store.py
index b1a81a3d5..a8dde6fee 100644
--- a/src/structify/types/llm_information_store.py
+++ b/src/structify/types/llm_information_store.py
@@ -10,6 +10,8 @@
class DatabaseSchemaTableColumn(BaseModel):
"""Represents a column in a table or API resource"""
+ id: str
+
name: str
"""Name of the column"""
diff --git a/src/structify/types/message_param.py b/src/structify/types/message_param.py
new file mode 100644
index 000000000..8b5d1bcf9
--- /dev/null
+++ b/src/structify/types/message_param.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Iterable
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
+
+from .._types import FileTypes
+from .._utils import PropertyInfo
+
+__all__ = ["MessageParam", "Content", "ContentText", "ContentImage"]
+
+
+class ContentText(TypedDict, total=False):
+ text: Required[Annotated[str, PropertyInfo(alias="Text")]]
+
+
+class ContentImage(TypedDict, total=False):
+ image: Required[Annotated[FileTypes, PropertyInfo(alias="Image")]]
+
+
+Content: TypeAlias = Union[ContentText, ContentImage]
+
+
+class MessageParam(TypedDict, total=False):
+ """Our generic definition of a message to a chat agent."""
+
+ content: Required[Iterable[Content]]
+ """
+ We want this to be a vec of contents so we can accurately capture an
+ interleaving of images and text.
+
+ This is meant to be a completely raw, unprocessed representation of the text.
+ Don't take stuff out.
+ """
+
+ role: Required[Literal["user", "system", "assistant"]]
diff --git a/src/structify/types/onboarding_answers.py b/src/structify/types/onboarding_answers.py
new file mode 100644
index 000000000..d3d0be2a2
--- /dev/null
+++ b/src/structify/types/onboarding_answers.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from .._models import BaseModel
+
+__all__ = ["OnboardingAnswers"]
+
+
+class OnboardingAnswers(BaseModel):
+ company_name: Optional[str] = None
+
+ connected_connector_ids: Optional[List[str]] = None
+
+ full_name: Optional[str] = None
+
+ primary_goal: Optional[str] = None
+
+ recommended_template_id: Optional[str] = None
+
+ role: Optional[str] = None
+
+ systems_to_connect: Optional[List[str]] = None
diff --git a/src/structify/types/onboarding_answers_param.py b/src/structify/types/onboarding_answers_param.py
new file mode 100644
index 000000000..b3e43f9f8
--- /dev/null
+++ b/src/structify/types/onboarding_answers_param.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+from .._types import SequenceNotStr
+
+__all__ = ["OnboardingAnswersParam"]
+
+
+class OnboardingAnswersParam(TypedDict, total=False):
+ company_name: Optional[str]
+
+ connected_connector_ids: Optional[SequenceNotStr[str]]
+
+ full_name: Optional[str]
+
+ primary_goal: Optional[str]
+
+ recommended_template_id: Optional[str]
+
+ role: Optional[str]
+
+ systems_to_connect: Optional[SequenceNotStr[str]]
diff --git a/src/structify/types/phase_activity.py b/src/structify/types/phase_activity.py
new file mode 100644
index 000000000..63e43ac12
--- /dev/null
+++ b/src/structify/types/phase_activity.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from .._models import BaseModel
+from .exploration_phase_id import ExplorationPhaseID
+
+__all__ = ["PhaseActivity"]
+
+
+class PhaseActivity(BaseModel):
+ job_id: str
+
+ phase_id: ExplorationPhaseID
+ """Identifies the phase of connector exploration
+
+ This enum is used to track which phase of exploration a chat session belongs to.
+ It's stored as JSONB in the database to allow for flexible phase identification.
+ """
+
+ status: Literal["Queued", "Running", "Completed", "Failed"]
+
+ chat_id: Optional[str] = None
diff --git a/src/structify/types/sandbox.py b/src/structify/types/sandbox.py
index 37e213da1..ce0ca3756 100644
--- a/src/structify/types/sandbox.py
+++ b/src/structify/types/sandbox.py
@@ -18,7 +18,9 @@ class Sandbox(BaseModel):
provider_id: str
- status: Literal["alive", "terminated"]
+ status: Literal["alive", "paused", "terminated"]
+
+ team_id: str
updated_at: datetime
@@ -30,6 +32,8 @@ class Sandbox(BaseModel):
latest_node: Optional[str] = None
+ resumed_at: Optional[datetime] = None
+
session_id: Optional[str] = None
tunnel_url: Optional[str] = None
diff --git a/src/structify/types/sandbox_get_metrics_response.py b/src/structify/types/sandbox_get_metrics_response.py
new file mode 100644
index 000000000..bb9d4ee97
--- /dev/null
+++ b/src/structify/types/sandbox_get_metrics_response.py
@@ -0,0 +1,41 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["SandboxGetMetricsResponse", "Memory", "Process", "Sandbox"]
+
+
+class Memory(BaseModel):
+ available_mb: float
+
+ percent: float
+
+ total_mb: float
+
+ used_mb: float
+
+
+class Process(BaseModel):
+ cpu_percent: float
+
+ memory_mb: float
+
+
+class Sandbox(BaseModel):
+ remaining_seconds: int
+
+ start_time: float
+
+ total_timeout_seconds: int
+
+ uptime_seconds: int
+
+
+class SandboxGetMetricsResponse(BaseModel):
+ cpu_percent: float
+
+ memory: Memory
+
+ process: Process
+
+ sandbox: Sandbox
diff --git a/src/structify/types/save_onboarding_answers_response.py b/src/structify/types/save_onboarding_answers_response.py
new file mode 100644
index 000000000..03ee078f3
--- /dev/null
+++ b/src/structify/types/save_onboarding_answers_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+from .onboarding_answers import OnboardingAnswers
+
+__all__ = ["SaveOnboardingAnswersResponse"]
+
+
+class SaveOnboardingAnswersResponse(BaseModel):
+ answers: OnboardingAnswers
diff --git a/src/structify/types/session_create_session_params.py b/src/structify/types/session_create_session_params.py
index df1aae369..2f08f0c31 100644
--- a/src/structify/types/session_create_session_params.py
+++ b/src/structify/types/session_create_session_params.py
@@ -11,6 +11,6 @@
class SessionCreateSessionParams(TypedDict, total=False):
chat_session_id: Required[str]
- git_commit: Required[str]
+ parent_chat_message_id: Optional[str]
workflow_schedule_id: Optional[str]
diff --git a/src/structify/types/session_upload_dashboard_layout_params.py b/src/structify/types/session_upload_dashboard_layout_params.py
index 039ff7441..9404afd61 100644
--- a/src/structify/types/session_upload_dashboard_layout_params.py
+++ b/src/structify/types/session_upload_dashboard_layout_params.py
@@ -2,16 +2,31 @@
from __future__ import annotations
-from typing_extensions import Required, TypedDict
+from typing import Union, Iterable
+from typing_extensions import Required, TypeAlias, TypedDict
from .dashboard_param import DashboardParam
+from .dashboard_spec_param import DashboardSpecParam
-__all__ = ["SessionUploadDashboardLayoutParams"]
+__all__ = ["SessionUploadDashboardLayoutParams", "Variant0", "Variant1", "Variant1DashboardSpec"]
-class SessionUploadDashboardLayoutParams(TypedDict, total=False):
+class Variant0(TypedDict, total=False):
layout: Required[DashboardParam]
"""
A page is the top-level container with title/description Can contain multiple
dashboards with different datasets
"""
+
+
+class Variant1(TypedDict, total=False):
+ dashboard_specs: Required[Iterable[Variant1DashboardSpec]]
+
+
+class Variant1DashboardSpec(TypedDict, total=False):
+ file_name: Required[str]
+
+ spec: Required[DashboardSpecParam]
+
+
+SessionUploadDashboardLayoutParams: TypeAlias = Union[Variant0, Variant1]
diff --git a/src/structify/types/session_upload_node_output_data_params.py b/src/structify/types/session_upload_node_output_data_params.py
index 35ee81397..dcc0b284c 100644
--- a/src/structify/types/session_upload_node_output_data_params.py
+++ b/src/structify/types/session_upload_node_output_data_params.py
@@ -13,4 +13,16 @@
class SessionUploadNodeOutputDataParams(TypedDict, total=False):
content: Required[FileTypes]
+ cache_final_rows: Optional[int]
+
+ cache_final_size_bytes: Optional[int]
+
+ cache_max_bytes: Optional[int]
+
+ cache_original_rows: Optional[int]
+
+ cache_original_size_bytes: Optional[int]
+
+ cache_truncated: Optional[bool]
+
output_schema: Optional[str]
diff --git a/src/structify/types/simulate_prompt_response.py b/src/structify/types/simulate_prompt_response.py
new file mode 100644
index 000000000..a6e39100a
--- /dev/null
+++ b/src/structify/types/simulate_prompt_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["SimulatePromptResponse"]
+
+
+class SimulatePromptResponse(BaseModel):
+ response: str
diff --git a/src/structify/types/structure_pdf_params.py b/src/structify/types/structure_pdf_params.py
index e4c577e8b..48b2db292 100644
--- a/src/structify/types/structure_pdf_params.py
+++ b/src/structify/types/structure_pdf_params.py
@@ -2,8 +2,8 @@
from __future__ import annotations
-from typing import Optional
-from typing_extensions import Literal, Required, TypedDict
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
__all__ = ["StructurePdfParams"]
@@ -15,8 +15,8 @@ class StructurePdfParams(TypedDict, total=False):
instructions: Optional[str]
- mode: Literal["Single", "Batch"]
-
model: Optional[str]
node_id: Optional[str]
+
+ pages: Optional[Iterable[int]]
diff --git a/src/structify/types/team.py b/src/structify/types/team.py
index cc1a46ccc..3d4a67f59 100644
--- a/src/structify/types/team.py
+++ b/src/structify/types/team.py
@@ -5,7 +5,19 @@
from .._models import BaseModel
-__all__ = ["Team"]
+__all__ = ["Team", "DaytonaCredentials", "WorkflowBucket"]
+
+
+class DaytonaCredentials(BaseModel):
+ api_key: Optional[str] = None
+
+ api_url: Optional[str] = None
+
+
+class WorkflowBucket(BaseModel):
+ bucket_url: str
+
+ gcp_credentials_json: Optional[str] = None
class Team(BaseModel):
@@ -17,9 +29,9 @@ class Team(BaseModel):
updated_at: datetime
- description: Optional[str] = None
+ daytona_credentials: Optional[DaytonaCredentials] = None
- pipedream_project_id: Optional[str] = None
+ description: Optional[str] = None
sandbox_provider: Optional[str] = None
@@ -36,3 +48,5 @@ class Team(BaseModel):
teams_service_url: Optional[str] = None
teams_tenant_id: Optional[str] = None
+
+ workflow_bucket: Optional[WorkflowBucket] = None
diff --git a/src/structify/types/team_update_params.py b/src/structify/types/team_update_params.py
index e671cbb8b..6beaeed9f 100644
--- a/src/structify/types/team_update_params.py
+++ b/src/structify/types/team_update_params.py
@@ -3,17 +3,19 @@
from __future__ import annotations
from typing import Optional
-from typing_extensions import TypedDict
+from typing_extensions import Literal, Required, TypedDict
-__all__ = ["TeamUpdateParams"]
+__all__ = ["TeamUpdateParams", "DaytonaCredentials", "WorkflowBucket"]
class TeamUpdateParams(TypedDict, total=False):
+ daytona_credentials: Optional[DaytonaCredentials]
+
description: Optional[str]
name: Optional[str]
- pipedream_project_id: Optional[str]
+ sandbox_provider: Optional[Literal["modal", "daytona"]]
slack_bot_token: Optional[str]
@@ -28,3 +30,17 @@ class TeamUpdateParams(TypedDict, total=False):
teams_app_password: Optional[str]
teams_tenant_id: Optional[str]
+
+ workflow_bucket: Optional[WorkflowBucket]
+
+
+class DaytonaCredentials(TypedDict, total=False):
+ api_key: Optional[str]
+
+ api_url: Optional[str]
+
+
+class WorkflowBucket(TypedDict, total=False):
+ bucket_url: Required[str]
+
+ gcp_credentials_json: Optional[str]
diff --git a/src/structify/types/template_question.py b/src/structify/types/template_question.py
new file mode 100644
index 000000000..356e55278
--- /dev/null
+++ b/src/structify/types/template_question.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from .._models import BaseModel
+
+__all__ = ["TemplateQuestion"]
+
+
+class TemplateQuestion(BaseModel):
+ prompt: str
+
+ options: Optional[List[str]] = None
diff --git a/src/structify/types/template_question_param.py b/src/structify/types/template_question_param.py
new file mode 100644
index 000000000..65cc0a2e2
--- /dev/null
+++ b/src/structify/types/template_question_param.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Required, TypedDict
+
+from .._types import SequenceNotStr
+
+__all__ = ["TemplateQuestionParam"]
+
+
+class TemplateQuestionParam(TypedDict, total=False):
+ prompt: Required[str]
+
+ options: Optional[SequenceNotStr[str]]
diff --git a/src/structify/types/tool_invocation.py b/src/structify/types/tool_invocation.py
index 97fa0e021..6956a3018 100644
--- a/src/structify/types/tool_invocation.py
+++ b/src/structify/types/tool_invocation.py
@@ -36,6 +36,9 @@
"DeleteFileInput",
"MoveFile",
"MoveFileInput",
+ "ApplyPatch",
+ "ApplyPatchInput",
+ "ApplyPatchInputEdit",
"RunBash",
"RunBashInput",
"RunPython",
@@ -66,6 +69,10 @@
"CreateConnectorInput",
"SearchConnectorTypes",
"SearchConnectorTypesInput",
+ "PinPreviousTool",
+ "PinPreviousToolInput",
+ "RunPipeline",
+ "RunPipelineInput",
]
@@ -191,12 +198,8 @@ class InspectStep(BaseModel):
class ReadNodeLogsInput(BaseModel):
- end_line: int
-
node_function_name: str
- start_line: int
-
log_type: Optional[str] = None
@@ -228,6 +231,26 @@ class MoveFile(BaseModel):
name: Literal["MoveFile"]
+class ApplyPatchInputEdit(BaseModel):
+ new_string: str
+
+ old_string: str
+
+
+class ApplyPatchInput(BaseModel):
+ apply_all: bool
+
+ edits: List[ApplyPatchInputEdit]
+
+ file: str
+
+
+class ApplyPatch(BaseModel):
+ input: ApplyPatchInput
+
+ name: Literal["ApplyPatch"]
+
+
class RunBashInput(BaseModel):
command: str
@@ -307,8 +330,6 @@ class SaveTableInput(BaseModel):
notes: Optional[str] = None
- tag: Optional[str] = None
-
class SaveTable(BaseModel):
input: SaveTableInput
@@ -432,6 +453,26 @@ class SearchConnectorTypes(BaseModel):
name: Literal["SearchConnectorTypes"]
+class PinPreviousToolInput(BaseModel):
+ path: str
+
+
+class PinPreviousTool(BaseModel):
+ input: PinPreviousToolInput
+
+ name: Literal["PinPreviousTool"]
+
+
+class RunPipelineInput(BaseModel):
+ rerun_all_steps: Optional[bool] = None
+
+
+class RunPipeline(BaseModel):
+ input: RunPipelineInput
+
+ name: Literal["RunPipeline"]
+
+
ToolInvocation: TypeAlias = Annotated[
Union[
WebSearch,
@@ -448,6 +489,7 @@ class SearchConnectorTypes(BaseModel):
ReadNodeLogs,
DeleteFile,
MoveFile,
+ ApplyPatch,
RunBash,
RunPython,
IssueFound,
@@ -463,6 +505,8 @@ class SearchConnectorTypes(BaseModel):
SelectData,
CreateConnector,
SearchConnectorTypes,
+ PinPreviousTool,
+ RunPipeline,
],
PropertyInfo(discriminator="name"),
]
diff --git a/src/structify/types/tool_metadata.py b/src/structify/types/tool_metadata.py
deleted file mode 100644
index a9e3f084c..000000000
--- a/src/structify/types/tool_metadata.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["ToolMetadata"]
-
-
-class ToolMetadata(BaseModel):
- description: str
-
- name: Literal["Exit", "Save", "Wait", "Type", "Scroll", "ScrollToBottom", "Click", "Hover", "Error", "Google"]
-
- regex_validator: str
diff --git a/src/structify/types/tool_result.py b/src/structify/types/tool_result.py
index e81cdfc57..54ab93253 100644
--- a/src/structify/types/tool_result.py
+++ b/src/structify/types/tool_result.py
@@ -22,6 +22,7 @@
"NodeLogs",
"Image",
"ImageImage",
+ "Pinned",
]
@@ -101,6 +102,10 @@ class Image(BaseModel):
image: ImageImage = FieldInfo(alias="Image")
+class Pinned(BaseModel):
+ pinned: str = FieldInfo(alias="Pinned")
+
+
ToolResult: TypeAlias = Union[
Literal["Pending", "NoResult", "Completed"],
Error,
@@ -111,4 +116,5 @@ class Image(BaseModel):
ConnectorSearch,
NodeLogs,
Image,
+ Pinned,
]
diff --git a/src/structify/types/trigger_review_response.py b/src/structify/types/trigger_review_response.py
new file mode 100644
index 000000000..af114c75f
--- /dev/null
+++ b/src/structify/types/trigger_review_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["TriggerReviewResponse"]
+
+
+class TriggerReviewResponse(BaseModel):
+ triggered: bool
diff --git a/src/structify/types/update_table_response.py b/src/structify/types/update_table_response.py
index a913c8a38..4ae117ce9 100644
--- a/src/structify/types/update_table_response.py
+++ b/src/structify/types/update_table_response.py
@@ -10,6 +10,8 @@
class TableColumn(BaseModel):
"""Represents a column in a table or API resource"""
+ id: str
+
name: str
"""Name of the column"""
diff --git a/src/structify/types/upload_dashboard_layout_request_param.py b/src/structify/types/upload_dashboard_layout_request_param.py
new file mode 100644
index 000000000..972cd55ed
--- /dev/null
+++ b/src/structify/types/upload_dashboard_layout_request_param.py
@@ -0,0 +1,32 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Iterable
+from typing_extensions import Required, TypeAlias, TypedDict
+
+from .dashboard_param import DashboardParam
+from .dashboard_spec_param import DashboardSpecParam
+
+__all__ = ["UploadDashboardLayoutRequestParam", "Layout", "DashboardSpecs", "DashboardSpecsDashboardSpec"]
+
+
+class Layout(TypedDict, total=False):
+ layout: Required[DashboardParam]
+ """
+ A page is the top-level container with title/description Can contain multiple
+ dashboards with different datasets
+ """
+
+
+class DashboardSpecsDashboardSpec(TypedDict, total=False):
+ file_name: Required[str]
+
+ spec: Required[DashboardSpecParam]
+
+
+class DashboardSpecs(TypedDict, total=False):
+ dashboard_specs: Required[Iterable[DashboardSpecsDashboardSpec]]
+
+
+UploadDashboardLayoutRequestParam: TypeAlias = Union[Layout, DashboardSpecs]
diff --git a/src/structify/types/user_info.py b/src/structify/types/user_info.py
index 32a8d4e7e..7532590e7 100644
--- a/src/structify/types/user_info.py
+++ b/src/structify/types/user_info.py
@@ -34,7 +34,7 @@ class UserInfo(BaseModel):
full_name: str
- is_developer: bool
+ notify_for_interaction: bool
permissions: List[Literal["labeler", "qa_labeler", "debug", "human_llm", "none"]]
diff --git a/src/structify/types/user_save_onboarding_answers_params.py b/src/structify/types/user_save_onboarding_answers_params.py
new file mode 100644
index 000000000..4689e70ae
--- /dev/null
+++ b/src/structify/types/user_save_onboarding_answers_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .onboarding_answers_param import OnboardingAnswersParam
+
+__all__ = ["UserSaveOnboardingAnswersParams"]
+
+
+class UserSaveOnboardingAnswersParams(TypedDict, total=False):
+ answers: Required[OnboardingAnswersParam]
diff --git a/src/structify/types/user_update_params.py b/src/structify/types/user_update_params.py
index 9db7c6e9a..9c1616109 100644
--- a/src/structify/types/user_update_params.py
+++ b/src/structify/types/user_update_params.py
@@ -54,14 +54,14 @@ class Updates(TypedDict, total=False):
full_name: Optional[str]
- is_developer: Optional[bool]
-
job_title: Optional[str]
last_selected_team_id: Optional[str]
linkedin_url: Optional[str]
+ notify_for_interaction: Optional[bool]
+
onboarding_session_id: Optional[str]
permissions: Optional[List[Optional[Literal["labeler", "qa_labeler", "debug", "human_llm", "none"]]]]
diff --git a/src/structify/types/viz_boolean_control.py b/src/structify/types/viz_boolean_control.py
new file mode 100644
index 000000000..7b217fd44
--- /dev/null
+++ b/src/structify/types/viz_boolean_control.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+from .viz_boolean_control_type import VizBooleanControlType
+
+__all__ = ["VizBooleanControl"]
+
+
+class VizBooleanControl(BaseModel):
+ label: str
+
+ type: VizBooleanControlType
diff --git a/src/structify/types/viz_boolean_control_param.py b/src/structify/types/viz_boolean_control_param.py
new file mode 100644
index 000000000..866601613
--- /dev/null
+++ b/src/structify/types/viz_boolean_control_param.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .viz_boolean_control_type import VizBooleanControlType
+
+__all__ = ["VizBooleanControlParam"]
+
+
+class VizBooleanControlParam(TypedDict, total=False):
+ label: Required[str]
+
+ type: Required[VizBooleanControlType]
diff --git a/src/structify/types/viz_boolean_control_type.py b/src/structify/types/viz_boolean_control_type.py
new file mode 100644
index 000000000..be767552e
--- /dev/null
+++ b/src/structify/types/viz_boolean_control_type.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["VizBooleanControlType"]
+
+VizBooleanControlType: TypeAlias = Literal["checkbox"]
diff --git a/src/structify/types/viz_control_option.py b/src/structify/types/viz_control_option.py
new file mode 100644
index 000000000..dfe26755e
--- /dev/null
+++ b/src/structify/types/viz_control_option.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["VizControlOption"]
+
+
+class VizControlOption(BaseModel):
+ label: str
+
+ value: str
diff --git a/src/structify/types/viz_control_option_param.py b/src/structify/types/viz_control_option_param.py
new file mode 100644
index 000000000..b6edd6bc1
--- /dev/null
+++ b/src/structify/types/viz_control_option_param.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["VizControlOptionParam"]
+
+
+class VizControlOptionParam(TypedDict, total=False):
+ label: Required[str]
+
+ value: Required[str]
diff --git a/src/structify/types/viz_date_control.py b/src/structify/types/viz_date_control.py
new file mode 100644
index 000000000..397dbe4a5
--- /dev/null
+++ b/src/structify/types/viz_date_control.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+from .viz_date_control_type import VizDateControlType
+
+__all__ = ["VizDateControl"]
+
+
+class VizDateControl(BaseModel):
+ label: str
+
+ type: VizDateControlType
diff --git a/src/structify/types/viz_date_control_param.py b/src/structify/types/viz_date_control_param.py
new file mode 100644
index 000000000..32ed102e4
--- /dev/null
+++ b/src/structify/types/viz_date_control_param.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .viz_date_control_type import VizDateControlType
+
+__all__ = ["VizDateControlParam"]
+
+
+class VizDateControlParam(TypedDict, total=False):
+ label: Required[str]
+
+ type: Required[VizDateControlType]
diff --git a/src/structify/types/viz_date_control_type.py b/src/structify/types/viz_date_control_type.py
new file mode 100644
index 000000000..a24b3f95c
--- /dev/null
+++ b/src/structify/types/viz_date_control_type.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["VizDateControlType"]
+
+VizDateControlType: TypeAlias = Literal["date"]
diff --git a/src/structify/types/viz_figure.py b/src/structify/types/viz_figure.py
new file mode 100644
index 000000000..dab6b01c6
--- /dev/null
+++ b/src/structify/types/viz_figure.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from .._models import BaseModel
+from .viz_figure_definition import VizFigureDefinition
+
+__all__ = ["VizFigure"]
+
+
+class VizFigure(BaseModel):
+ id: str
+
+ figure: VizFigureDefinition
+
+ description: Optional[str] = None
+
+ span: Optional[int] = None
+
+ title: Optional[str] = None
diff --git a/src/structify/types/viz_figure_definition.py b/src/structify/types/viz_figure_definition.py
new file mode 100644
index 000000000..9928e4e8a
--- /dev/null
+++ b/src/structify/types/viz_figure_definition.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+from .viz_figure_kind import VizFigureKind
+
+__all__ = ["VizFigureDefinition"]
+
+
+class VizFigureDefinition(BaseModel):
+ expression: str
+
+ kind: VizFigureKind
diff --git a/src/structify/types/viz_figure_definition_param.py b/src/structify/types/viz_figure_definition_param.py
new file mode 100644
index 000000000..1f26b349a
--- /dev/null
+++ b/src/structify/types/viz_figure_definition_param.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .viz_figure_kind import VizFigureKind
+
+__all__ = ["VizFigureDefinitionParam"]
+
+
+class VizFigureDefinitionParam(TypedDict, total=False):
+ expression: Required[str]
+
+ kind: Required[VizFigureKind]
diff --git a/src/structify/types/viz_figure_kind.py b/src/structify/types/viz_figure_kind.py
new file mode 100644
index 000000000..e70d16356
--- /dev/null
+++ b/src/structify/types/viz_figure_kind.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["VizFigureKind"]
+
+VizFigureKind: TypeAlias = Literal["js", "vega-lite", "data-table"]
diff --git a/src/structify/types/viz_figure_param.py b/src/structify/types/viz_figure_param.py
new file mode 100644
index 000000000..e76dd3968
--- /dev/null
+++ b/src/structify/types/viz_figure_param.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .viz_figure_definition_param import VizFigureDefinitionParam
+
+__all__ = ["VizFigureParam"]
+
+
+class VizFigureParam(TypedDict, total=False):
+ id: Required[str]
+
+ figure: Required[VizFigureDefinitionParam]
+
+ description: str
+
+ span: int
+
+ title: str
diff --git a/src/structify/types/viz_number_control.py b/src/structify/types/viz_number_control.py
new file mode 100644
index 000000000..efdc9d22e
--- /dev/null
+++ b/src/structify/types/viz_number_control.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from .._models import BaseModel
+from .viz_number_control_type import VizNumberControlType
+
+__all__ = ["VizNumberControl"]
+
+
+class VizNumberControl(BaseModel):
+ label: str
+
+ max: float
+
+ min: float
+
+ type: VizNumberControlType
+
+ step: Optional[float] = None
diff --git a/src/structify/types/viz_number_control_param.py b/src/structify/types/viz_number_control_param.py
new file mode 100644
index 000000000..2d511b586
--- /dev/null
+++ b/src/structify/types/viz_number_control_param.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .viz_number_control_type import VizNumberControlType
+
+__all__ = ["VizNumberControlParam"]
+
+
+class VizNumberControlParam(TypedDict, total=False):
+ label: Required[str]
+
+ max: Required[float]
+
+ min: Required[float]
+
+ type: Required[VizNumberControlType]
+
+ step: float
diff --git a/src/structify/types/viz_number_control_type.py b/src/structify/types/viz_number_control_type.py
new file mode 100644
index 000000000..30ffa1301
--- /dev/null
+++ b/src/structify/types/viz_number_control_type.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["VizNumberControlType"]
+
+VizNumberControlType: TypeAlias = Literal["range"]
diff --git a/src/structify/types/viz_param.py b/src/structify/types/viz_param.py
new file mode 100644
index 000000000..83e779bb8
--- /dev/null
+++ b/src/structify/types/viz_param.py
@@ -0,0 +1,48 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Union, Optional
+from typing_extensions import Literal, Annotated, TypeAlias
+
+from .._utils import PropertyInfo
+from .._models import BaseModel
+from .viz_date_control import VizDateControl
+from .viz_number_control import VizNumberControl
+from .viz_string_control import VizStringControl
+from .viz_boolean_control import VizBooleanControl
+
+__all__ = ["VizParam", "String", "Number", "Boolean", "Date"]
+
+
+class String(BaseModel):
+ type: Literal["string"]
+
+ value: str
+
+ control: Optional[VizStringControl] = None
+
+
+class Number(BaseModel):
+ type: Literal["number"]
+
+ value: float
+
+ control: Optional[VizNumberControl] = None
+
+
+class Boolean(BaseModel):
+ type: Literal["boolean"]
+
+ value: bool
+
+ control: Optional[VizBooleanControl] = None
+
+
+class Date(BaseModel):
+ type: Literal["date"]
+
+ value: str
+
+ control: Optional[VizDateControl] = None
+
+
+VizParam: TypeAlias = Annotated[Union[String, Number, Boolean, Date], PropertyInfo(discriminator="type")]
diff --git a/src/structify/types/viz_param_param.py b/src/structify/types/viz_param_param.py
new file mode 100644
index 000000000..ca0d8f6a1
--- /dev/null
+++ b/src/structify/types/viz_param_param.py
@@ -0,0 +1,48 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+from .viz_date_control_param import VizDateControlParam
+from .viz_number_control_param import VizNumberControlParam
+from .viz_string_control_param import VizStringControlParam
+from .viz_boolean_control_param import VizBooleanControlParam
+
+__all__ = ["VizParamParam", "String", "Number", "Boolean", "Date"]
+
+
+class String(TypedDict, total=False):
+ type: Required[Literal["string"]]
+
+ value: Required[str]
+
+ control: VizStringControlParam
+
+
+class Number(TypedDict, total=False):
+ type: Required[Literal["number"]]
+
+ value: Required[float]
+
+ control: VizNumberControlParam
+
+
+class Boolean(TypedDict, total=False):
+ type: Required[Literal["boolean"]]
+
+ value: Required[bool]
+
+ control: VizBooleanControlParam
+
+
+class Date(TypedDict, total=False):
+ type: Required[Literal["date"]]
+
+ value: Required[str]
+
+ control: VizDateControlParam
+
+
+VizParamParam: TypeAlias = Union[String, Number, Boolean, Date]
diff --git a/src/structify/types/viz_query.py b/src/structify/types/viz_query.py
new file mode 100644
index 000000000..e6c751625
--- /dev/null
+++ b/src/structify/types/viz_query.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["VizQuery"]
+
+
+class VizQuery(BaseModel):
+ id: str
+
+ sql: str
diff --git a/src/structify/types/viz_query_param.py b/src/structify/types/viz_query_param.py
new file mode 100644
index 000000000..71aad068a
--- /dev/null
+++ b/src/structify/types/viz_query_param.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["VizQueryParam"]
+
+
+class VizQueryParam(TypedDict, total=False):
+ id: Required[str]
+
+ sql: Required[str]
diff --git a/src/structify/types/viz_string_control.py b/src/structify/types/viz_string_control.py
new file mode 100644
index 000000000..fbb70d640
--- /dev/null
+++ b/src/structify/types/viz_string_control.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from .._models import BaseModel
+from .viz_control_option import VizControlOption
+from .viz_string_control_type import VizStringControlType
+
+__all__ = ["VizStringControl"]
+
+
+class VizStringControl(BaseModel):
+ label: str
+
+ options: List[VizControlOption]
+
+ type: VizStringControlType
diff --git a/src/structify/types/viz_string_control_param.py b/src/structify/types/viz_string_control_param.py
new file mode 100644
index 000000000..f01adeb0d
--- /dev/null
+++ b/src/structify/types/viz_string_control_param.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Required, TypedDict
+
+from .viz_string_control_type import VizStringControlType
+from .viz_control_option_param import VizControlOptionParam
+
+__all__ = ["VizStringControlParam"]
+
+
+class VizStringControlParam(TypedDict, total=False):
+ label: Required[str]
+
+ options: Required[Iterable[VizControlOptionParam]]
+
+ type: Required[VizStringControlType]
diff --git a/src/structify/types/viz_string_control_type.py b/src/structify/types/viz_string_control_type.py
new file mode 100644
index 000000000..fa2b28c76
--- /dev/null
+++ b/src/structify/types/viz_string_control_type.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["VizStringControlType"]
+
+VizStringControlType: TypeAlias = Literal["dropdown"]
diff --git a/src/structify/types/workflow_dag.py b/src/structify/types/workflow_dag.py
index 2a0f0470f..d896e6210 100644
--- a/src/structify/types/workflow_dag.py
+++ b/src/structify/types/workflow_dag.py
@@ -5,6 +5,7 @@
from .._models import BaseModel
from .dashboard import Dashboard
+from .dashboard_item import DashboardItem
from .workflow_session_edge import WorkflowSessionEdge
from .workflow_session_node import WorkflowSessionNode
@@ -14,6 +15,8 @@
class WorkflowDag(BaseModel):
aborted: bool
+ dashboard_specs: List[DashboardItem]
+
edges: List[WorkflowSessionEdge]
is_ready: bool
diff --git a/src/structify/types/workflow_schedule_info.py b/src/structify/types/workflow_schedule_info.py
index a0e9bf44d..eae143b7e 100644
--- a/src/structify/types/workflow_schedule_info.py
+++ b/src/structify/types/workflow_schedule_info.py
@@ -3,6 +3,7 @@
from typing import Optional
from .._models import BaseModel
+from .chat_visibility import ChatVisibility
__all__ = ["WorkflowScheduleInfo"]
@@ -21,3 +22,9 @@ class WorkflowScheduleInfo(BaseModel):
git_commit_hash: Optional[str] = None
next_run_time: Optional[str] = None
+
+ owner_email: Optional[str] = None
+
+ updated_at: Optional[str] = None
+
+ visibility: Optional[ChatVisibility] = None
diff --git a/src/structify/types/workflow_session.py b/src/structify/types/workflow_session.py
index dfbcdbd57..49284cb58 100644
--- a/src/structify/types/workflow_session.py
+++ b/src/structify/types/workflow_session.py
@@ -29,6 +29,6 @@ class WorkflowSession(BaseModel):
error_traceback: Optional[str] = None
- git_commit: Optional[str] = None
+ parent_chat_message_id: Optional[str] = None
workflow_schedule_id: Optional[str] = None
diff --git a/src/structify/types/workflow_session_node.py b/src/structify/types/workflow_session_node.py
index a790119d5..0f93d2b48 100644
--- a/src/structify/types/workflow_session_node.py
+++ b/src/structify/types/workflow_session_node.py
@@ -30,6 +30,18 @@ class WorkflowSessionNode(BaseModel):
updated_at: datetime
+ cache_final_rows: Optional[int] = None
+
+ cache_final_size_bytes: Optional[int] = None
+
+ cache_max_bytes: Optional[int] = None
+
+ cache_original_rows: Optional[int] = None
+
+ cache_original_size_bytes: Optional[int] = None
+
+ cache_truncated: Optional[bool] = None
+
code: Optional[str] = None
confirmation_status: Optional[str] = None
diff --git a/tests/api_resources/admin/test_chat_templates.py b/tests/api_resources/admin/test_chat_templates.py
index e33d109bf..8d8115368 100644
--- a/tests/api_resources/admin/test_chat_templates.py
+++ b/tests/api_resources/admin/test_chat_templates.py
@@ -28,6 +28,7 @@ def test_method_create(self, client: Structify) -> None:
display_order=0,
image_url="image_url",
is_active=True,
+ questions=[{"prompt": "prompt"}],
title="title",
)
assert_matches_type(ChatTemplate, chat_template, path=["response"])
@@ -40,6 +41,7 @@ def test_raw_response_create(self, client: Structify) -> None:
display_order=0,
image_url="image_url",
is_active=True,
+ questions=[{"prompt": "prompt"}],
title="title",
)
@@ -56,6 +58,7 @@ def test_streaming_response_create(self, client: Structify) -> None:
display_order=0,
image_url="image_url",
is_active=True,
+ questions=[{"prompt": "prompt"}],
title="title",
) as response:
assert not response.is_closed
@@ -81,6 +84,12 @@ def test_method_update_with_all_params(self, client: Structify) -> None:
display_order=0,
image_url="image_url",
is_active=True,
+ questions=[
+ {
+ "prompt": "prompt",
+ "options": ["string"],
+ }
+ ],
title="title",
updated_by="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -163,6 +172,7 @@ async def test_method_create(self, async_client: AsyncStructify) -> None:
display_order=0,
image_url="image_url",
is_active=True,
+ questions=[{"prompt": "prompt"}],
title="title",
)
assert_matches_type(ChatTemplate, chat_template, path=["response"])
@@ -175,6 +185,7 @@ async def test_raw_response_create(self, async_client: AsyncStructify) -> None:
display_order=0,
image_url="image_url",
is_active=True,
+ questions=[{"prompt": "prompt"}],
title="title",
)
@@ -191,6 +202,7 @@ async def test_streaming_response_create(self, async_client: AsyncStructify) ->
display_order=0,
image_url="image_url",
is_active=True,
+ questions=[{"prompt": "prompt"}],
title="title",
) as response:
assert not response.is_closed
@@ -216,6 +228,12 @@ async def test_method_update_with_all_params(self, async_client: AsyncStructify)
display_order=0,
image_url="image_url",
is_active=True,
+ questions=[
+ {
+ "prompt": "prompt",
+ "options": ["string"],
+ }
+ ],
title="title",
updated_by="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
diff --git a/tests/api_resources/admin/test_connector.py b/tests/api_resources/admin/test_connector.py
index 3535580ac..7d2a3c984 100644
--- a/tests/api_resources/admin/test_connector.py
+++ b/tests/api_resources/admin/test_connector.py
@@ -9,7 +9,11 @@
from structify import Structify, AsyncStructify
from tests.utils import assert_matches_type
-from structify.types.admin import CloneConnectorsResponse
+from structify.types import Connector
+from structify.types.admin import (
+ ConnectorCloneResponse,
+ AdminListConnectorsResponse,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -27,9 +31,11 @@ def test_method_clone(self, client: Structify) -> None:
"source_connector_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
}
],
+ source_membership_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ source_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
target_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(CloneConnectorsResponse, connector, path=["response"])
+ assert_matches_type(ConnectorCloneResponse, connector, path=["response"])
@parametrize
def test_raw_response_clone(self, client: Structify) -> None:
@@ -41,13 +47,15 @@ def test_raw_response_clone(self, client: Structify) -> None:
"source_connector_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
}
],
+ source_membership_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ source_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
target_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = response.parse()
- assert_matches_type(CloneConnectorsResponse, connector, path=["response"])
+ assert_matches_type(ConnectorCloneResponse, connector, path=["response"])
@parametrize
def test_streaming_response_clone(self, client: Structify) -> None:
@@ -59,13 +67,93 @@ def test_streaming_response_clone(self, client: Structify) -> None:
"source_connector_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
}
],
+ source_membership_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ source_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
target_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = response.parse()
- assert_matches_type(CloneConnectorsResponse, connector, path=["response"])
+ assert_matches_type(ConnectorCloneResponse, connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_list_team_connectors(self, client: Structify) -> None:
+ connector = client.admin.connector.list_team_connectors(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(AdminListConnectorsResponse, connector, path=["response"])
+
+ @parametrize
+ def test_raw_response_list_team_connectors(self, client: Structify) -> None:
+ response = client.admin.connector.with_raw_response.list_team_connectors(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = response.parse()
+ assert_matches_type(AdminListConnectorsResponse, connector, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list_team_connectors(self, client: Structify) -> None:
+ with client.admin.connector.with_streaming_response.list_team_connectors(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = response.parse()
+ assert_matches_type(AdminListConnectorsResponse, connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list_team_connectors(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `team_id` but received ''"):
+ client.admin.connector.with_raw_response.list_team_connectors(
+ "",
+ )
+
+ @parametrize
+ def test_method_set_datahub_config(self, client: Structify) -> None:
+ connector = client.admin.connector.set_datahub_config(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(Connector, connector, path=["response"])
+
+ @parametrize
+ def test_method_set_datahub_config_with_all_params(self, client: Structify) -> None:
+ connector = client.admin.connector.set_datahub_config(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ datahub_ingestion_type="postgres",
+ datahub_secret_map={"foo": "string"},
+ )
+ assert_matches_type(Connector, connector, path=["response"])
+
+ @parametrize
+ def test_raw_response_set_datahub_config(self, client: Structify) -> None:
+ response = client.admin.connector.with_raw_response.set_datahub_config(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = response.parse()
+ assert_matches_type(Connector, connector, path=["response"])
+
+ @parametrize
+ def test_streaming_response_set_datahub_config(self, client: Structify) -> None:
+ with client.admin.connector.with_streaming_response.set_datahub_config(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = response.parse()
+ assert_matches_type(Connector, connector, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -85,9 +173,11 @@ async def test_method_clone(self, async_client: AsyncStructify) -> None:
"source_connector_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
}
],
+ source_membership_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ source_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
target_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(CloneConnectorsResponse, connector, path=["response"])
+ assert_matches_type(ConnectorCloneResponse, connector, path=["response"])
@parametrize
async def test_raw_response_clone(self, async_client: AsyncStructify) -> None:
@@ -99,13 +189,15 @@ async def test_raw_response_clone(self, async_client: AsyncStructify) -> None:
"source_connector_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
}
],
+ source_membership_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ source_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
target_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = await response.parse()
- assert_matches_type(CloneConnectorsResponse, connector, path=["response"])
+ assert_matches_type(ConnectorCloneResponse, connector, path=["response"])
@parametrize
async def test_streaming_response_clone(self, async_client: AsyncStructify) -> None:
@@ -117,12 +209,92 @@ async def test_streaming_response_clone(self, async_client: AsyncStructify) -> N
"source_connector_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
}
],
+ source_membership_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ source_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
target_team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = await response.parse()
- assert_matches_type(CloneConnectorsResponse, connector, path=["response"])
+ assert_matches_type(ConnectorCloneResponse, connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_list_team_connectors(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.admin.connector.list_team_connectors(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(AdminListConnectorsResponse, connector, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list_team_connectors(self, async_client: AsyncStructify) -> None:
+ response = await async_client.admin.connector.with_raw_response.list_team_connectors(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = await response.parse()
+ assert_matches_type(AdminListConnectorsResponse, connector, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list_team_connectors(self, async_client: AsyncStructify) -> None:
+ async with async_client.admin.connector.with_streaming_response.list_team_connectors(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = await response.parse()
+ assert_matches_type(AdminListConnectorsResponse, connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list_team_connectors(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `team_id` but received ''"):
+ await async_client.admin.connector.with_raw_response.list_team_connectors(
+ "",
+ )
+
+ @parametrize
+ async def test_method_set_datahub_config(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.admin.connector.set_datahub_config(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(Connector, connector, path=["response"])
+
+ @parametrize
+ async def test_method_set_datahub_config_with_all_params(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.admin.connector.set_datahub_config(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ datahub_ingestion_type="postgres",
+ datahub_secret_map={"foo": "string"},
+ )
+ assert_matches_type(Connector, connector, path=["response"])
+
+ @parametrize
+ async def test_raw_response_set_datahub_config(self, async_client: AsyncStructify) -> None:
+ response = await async_client.admin.connector.with_raw_response.set_datahub_config(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = await response.parse()
+ assert_matches_type(Connector, connector, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_set_datahub_config(self, async_client: AsyncStructify) -> None:
+ async with async_client.admin.connector.with_streaming_response.set_datahub_config(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = await response.parse()
+ assert_matches_type(Connector, connector, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/admin/test_jobs.py b/tests/api_resources/admin/test_jobs.py
index bfc2d0cea..2ae99cb3f 100644
--- a/tests/api_resources/admin/test_jobs.py
+++ b/tests/api_resources/admin/test_jobs.py
@@ -9,9 +9,15 @@
from structify import Structify, AsyncStructify
from tests.utils import assert_matches_type
-from structify._utils import parse_datetime
from structify.pagination import SyncJobsList, AsyncJobsList
-from structify.types.admin import AdminListJobsResponse, AdminDeleteJobsResponse
+from structify.types.admin import (
+ JobListResponse,
+ JobKillByUserResponse,
+ JobConcurrencyResponse,
+ AdminDeleteJobsResponse,
+ JobRunningStatsResponse,
+ JobUpdateConcurrencyResponse,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -21,51 +27,37 @@ class TestJobs:
@parametrize
def test_method_list(self, client: Structify) -> None:
- job = client.admin.jobs.list(
- filter_test_users=True,
- limit=0,
- offset=0,
- )
- assert_matches_type(SyncJobsList[AdminListJobsResponse], job, path=["response"])
+ job = client.admin.jobs.list()
+ assert_matches_type(SyncJobsList[JobListResponse], job, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Structify) -> None:
job = client.admin.jobs.list(
- filter_test_users=True,
+ job_type="Web",
limit=0,
offset=0,
- dataset_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- seeded_kg_search_term="seeded_kg_search_term",
- since=parse_datetime("2019-12-27T18:11:19.117Z"),
status="Queued",
+ user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(SyncJobsList[AdminListJobsResponse], job, path=["response"])
+ assert_matches_type(SyncJobsList[JobListResponse], job, path=["response"])
@parametrize
def test_raw_response_list(self, client: Structify) -> None:
- response = client.admin.jobs.with_raw_response.list(
- filter_test_users=True,
- limit=0,
- offset=0,
- )
+ response = client.admin.jobs.with_raw_response.list()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = response.parse()
- assert_matches_type(SyncJobsList[AdminListJobsResponse], job, path=["response"])
+ assert_matches_type(SyncJobsList[JobListResponse], job, path=["response"])
@parametrize
def test_streaming_response_list(self, client: Structify) -> None:
- with client.admin.jobs.with_streaming_response.list(
- filter_test_users=True,
- limit=0,
- offset=0,
- ) as response:
+ with client.admin.jobs.with_streaming_response.list() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = response.parse()
- assert_matches_type(SyncJobsList[AdminListJobsResponse], job, path=["response"])
+ assert_matches_type(SyncJobsList[JobListResponse], job, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -100,6 +92,125 @@ def test_streaming_response_delete(self, client: Structify) -> None:
assert cast(Any, response.is_closed) is True
+ @parametrize
+ def test_method_concurrency(self, client: Structify) -> None:
+ job = client.admin.jobs.concurrency()
+ assert_matches_type(JobConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ def test_raw_response_concurrency(self, client: Structify) -> None:
+ response = client.admin.jobs.with_raw_response.concurrency()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ job = response.parse()
+ assert_matches_type(JobConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ def test_streaming_response_concurrency(self, client: Structify) -> None:
+ with client.admin.jobs.with_streaming_response.concurrency() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ job = response.parse()
+ assert_matches_type(JobConcurrencyResponse, job, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_kill_by_user(self, client: Structify) -> None:
+ job = client.admin.jobs.kill_by_user(
+ user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(JobKillByUserResponse, job, path=["response"])
+
+ @parametrize
+ def test_raw_response_kill_by_user(self, client: Structify) -> None:
+ response = client.admin.jobs.with_raw_response.kill_by_user(
+ user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ job = response.parse()
+ assert_matches_type(JobKillByUserResponse, job, path=["response"])
+
+ @parametrize
+ def test_streaming_response_kill_by_user(self, client: Structify) -> None:
+ with client.admin.jobs.with_streaming_response.kill_by_user(
+ user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ job = response.parse()
+ assert_matches_type(JobKillByUserResponse, job, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_running_stats(self, client: Structify) -> None:
+ job = client.admin.jobs.running_stats()
+ assert_matches_type(JobRunningStatsResponse, job, path=["response"])
+
+ @parametrize
+ def test_raw_response_running_stats(self, client: Structify) -> None:
+ response = client.admin.jobs.with_raw_response.running_stats()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ job = response.parse()
+ assert_matches_type(JobRunningStatsResponse, job, path=["response"])
+
+ @parametrize
+ def test_streaming_response_running_stats(self, client: Structify) -> None:
+ with client.admin.jobs.with_streaming_response.running_stats() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ job = response.parse()
+ assert_matches_type(JobRunningStatsResponse, job, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_update_concurrency(self, client: Structify) -> None:
+ job = client.admin.jobs.update_concurrency()
+ assert_matches_type(JobUpdateConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ def test_method_update_concurrency_with_all_params(self, client: Structify) -> None:
+ job = client.admin.jobs.update_concurrency(
+ max_connector_explore_jobs=0,
+ max_derive_jobs=0,
+ max_match_jobs=0,
+ max_pdf_jobs=0,
+ max_scrape_jobs=0,
+ max_total_jobs=0,
+ max_web_jobs=0,
+ )
+ assert_matches_type(JobUpdateConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ def test_raw_response_update_concurrency(self, client: Structify) -> None:
+ response = client.admin.jobs.with_raw_response.update_concurrency()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ job = response.parse()
+ assert_matches_type(JobUpdateConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update_concurrency(self, client: Structify) -> None:
+ with client.admin.jobs.with_streaming_response.update_concurrency() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ job = response.parse()
+ assert_matches_type(JobUpdateConcurrencyResponse, job, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
class TestAsyncJobs:
parametrize = pytest.mark.parametrize(
@@ -108,51 +219,37 @@ class TestAsyncJobs:
@parametrize
async def test_method_list(self, async_client: AsyncStructify) -> None:
- job = await async_client.admin.jobs.list(
- filter_test_users=True,
- limit=0,
- offset=0,
- )
- assert_matches_type(AsyncJobsList[AdminListJobsResponse], job, path=["response"])
+ job = await async_client.admin.jobs.list()
+ assert_matches_type(AsyncJobsList[JobListResponse], job, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncStructify) -> None:
job = await async_client.admin.jobs.list(
- filter_test_users=True,
+ job_type="Web",
limit=0,
offset=0,
- dataset_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- seeded_kg_search_term="seeded_kg_search_term",
- since=parse_datetime("2019-12-27T18:11:19.117Z"),
status="Queued",
+ user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(AsyncJobsList[AdminListJobsResponse], job, path=["response"])
+ assert_matches_type(AsyncJobsList[JobListResponse], job, path=["response"])
@parametrize
async def test_raw_response_list(self, async_client: AsyncStructify) -> None:
- response = await async_client.admin.jobs.with_raw_response.list(
- filter_test_users=True,
- limit=0,
- offset=0,
- )
+ response = await async_client.admin.jobs.with_raw_response.list()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = await response.parse()
- assert_matches_type(AsyncJobsList[AdminListJobsResponse], job, path=["response"])
+ assert_matches_type(AsyncJobsList[JobListResponse], job, path=["response"])
@parametrize
async def test_streaming_response_list(self, async_client: AsyncStructify) -> None:
- async with async_client.admin.jobs.with_streaming_response.list(
- filter_test_users=True,
- limit=0,
- offset=0,
- ) as response:
+ async with async_client.admin.jobs.with_streaming_response.list() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = await response.parse()
- assert_matches_type(AsyncJobsList[AdminListJobsResponse], job, path=["response"])
+ assert_matches_type(AsyncJobsList[JobListResponse], job, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -186,3 +283,122 @@ async def test_streaming_response_delete(self, async_client: AsyncStructify) ->
assert_matches_type(AdminDeleteJobsResponse, job, path=["response"])
assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_concurrency(self, async_client: AsyncStructify) -> None:
+ job = await async_client.admin.jobs.concurrency()
+ assert_matches_type(JobConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ async def test_raw_response_concurrency(self, async_client: AsyncStructify) -> None:
+ response = await async_client.admin.jobs.with_raw_response.concurrency()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ job = await response.parse()
+ assert_matches_type(JobConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_concurrency(self, async_client: AsyncStructify) -> None:
+ async with async_client.admin.jobs.with_streaming_response.concurrency() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ job = await response.parse()
+ assert_matches_type(JobConcurrencyResponse, job, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_kill_by_user(self, async_client: AsyncStructify) -> None:
+ job = await async_client.admin.jobs.kill_by_user(
+ user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(JobKillByUserResponse, job, path=["response"])
+
+ @parametrize
+ async def test_raw_response_kill_by_user(self, async_client: AsyncStructify) -> None:
+ response = await async_client.admin.jobs.with_raw_response.kill_by_user(
+ user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ job = await response.parse()
+ assert_matches_type(JobKillByUserResponse, job, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_kill_by_user(self, async_client: AsyncStructify) -> None:
+ async with async_client.admin.jobs.with_streaming_response.kill_by_user(
+ user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ job = await response.parse()
+ assert_matches_type(JobKillByUserResponse, job, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_running_stats(self, async_client: AsyncStructify) -> None:
+ job = await async_client.admin.jobs.running_stats()
+ assert_matches_type(JobRunningStatsResponse, job, path=["response"])
+
+ @parametrize
+ async def test_raw_response_running_stats(self, async_client: AsyncStructify) -> None:
+ response = await async_client.admin.jobs.with_raw_response.running_stats()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ job = await response.parse()
+ assert_matches_type(JobRunningStatsResponse, job, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_running_stats(self, async_client: AsyncStructify) -> None:
+ async with async_client.admin.jobs.with_streaming_response.running_stats() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ job = await response.parse()
+ assert_matches_type(JobRunningStatsResponse, job, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_update_concurrency(self, async_client: AsyncStructify) -> None:
+ job = await async_client.admin.jobs.update_concurrency()
+ assert_matches_type(JobUpdateConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ async def test_method_update_concurrency_with_all_params(self, async_client: AsyncStructify) -> None:
+ job = await async_client.admin.jobs.update_concurrency(
+ max_connector_explore_jobs=0,
+ max_derive_jobs=0,
+ max_match_jobs=0,
+ max_pdf_jobs=0,
+ max_scrape_jobs=0,
+ max_total_jobs=0,
+ max_web_jobs=0,
+ )
+ assert_matches_type(JobUpdateConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update_concurrency(self, async_client: AsyncStructify) -> None:
+ response = await async_client.admin.jobs.with_raw_response.update_concurrency()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ job = await response.parse()
+ assert_matches_type(JobUpdateConcurrencyResponse, job, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update_concurrency(self, async_client: AsyncStructify) -> None:
+ async with async_client.admin.jobs.with_streaming_response.update_concurrency() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ job = await response.parse()
+ assert_matches_type(JobUpdateConcurrencyResponse, job, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/admin/test_teams.py b/tests/api_resources/admin/test_teams.py
index 57ba074c1..f1ba06f3b 100644
--- a/tests/api_resources/admin/test_teams.py
+++ b/tests/api_resources/admin/test_teams.py
@@ -10,13 +10,12 @@
from structify import Structify, AsyncStructify
from tests.utils import assert_matches_type
from structify._utils import parse_datetime
-from structify.pagination import SyncJobsList, AsyncJobsList
from structify.types.admin import (
+ TeamListResponse,
ExtendTrialResponse,
ExpireGrantsResponse,
GrantCreditsResponse,
AdminAddMemberResponse,
- AdminTeamsListResponse,
AdminListMembersResponse,
AdminRemoveMemberResponse,
CancelSubscriptionResponse,
@@ -33,15 +32,16 @@ class TestTeams:
@parametrize
def test_method_list(self, client: Structify) -> None:
team = client.admin.teams.list()
- assert_matches_type(SyncJobsList[AdminTeamsListResponse], team, path=["response"])
+ assert_matches_type(TeamListResponse, team, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Structify) -> None:
team = client.admin.teams.list(
limit=0,
offset=0,
+ search="search",
)
- assert_matches_type(SyncJobsList[AdminTeamsListResponse], team, path=["response"])
+ assert_matches_type(TeamListResponse, team, path=["response"])
@parametrize
def test_raw_response_list(self, client: Structify) -> None:
@@ -50,7 +50,7 @@ def test_raw_response_list(self, client: Structify) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
team = response.parse()
- assert_matches_type(SyncJobsList[AdminTeamsListResponse], team, path=["response"])
+ assert_matches_type(TeamListResponse, team, path=["response"])
@parametrize
def test_streaming_response_list(self, client: Structify) -> None:
@@ -59,7 +59,7 @@ def test_streaming_response_list(self, client: Structify) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
team = response.parse()
- assert_matches_type(SyncJobsList[AdminTeamsListResponse], team, path=["response"])
+ assert_matches_type(TeamListResponse, team, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -421,15 +421,16 @@ class TestAsyncTeams:
@parametrize
async def test_method_list(self, async_client: AsyncStructify) -> None:
team = await async_client.admin.teams.list()
- assert_matches_type(AsyncJobsList[AdminTeamsListResponse], team, path=["response"])
+ assert_matches_type(TeamListResponse, team, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncStructify) -> None:
team = await async_client.admin.teams.list(
limit=0,
offset=0,
+ search="search",
)
- assert_matches_type(AsyncJobsList[AdminTeamsListResponse], team, path=["response"])
+ assert_matches_type(TeamListResponse, team, path=["response"])
@parametrize
async def test_raw_response_list(self, async_client: AsyncStructify) -> None:
@@ -438,7 +439,7 @@ async def test_raw_response_list(self, async_client: AsyncStructify) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
team = await response.parse()
- assert_matches_type(AsyncJobsList[AdminTeamsListResponse], team, path=["response"])
+ assert_matches_type(TeamListResponse, team, path=["response"])
@parametrize
async def test_streaming_response_list(self, async_client: AsyncStructify) -> None:
@@ -447,7 +448,7 @@ async def test_streaming_response_list(self, async_client: AsyncStructify) -> No
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
team = await response.parse()
- assert_matches_type(AsyncJobsList[AdminTeamsListResponse], team, path=["response"])
+ assert_matches_type(TeamListResponse, team, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/connector_catalog/test_admin.py b/tests/api_resources/connector_catalog/test_admin.py
index a4a9898df..10cb267d0 100644
--- a/tests/api_resources/connector_catalog/test_admin.py
+++ b/tests/api_resources/connector_catalog/test_admin.py
@@ -194,6 +194,8 @@ def test_method_create_catalog_with_all_params(self, client: Structify) -> None:
slug="slug",
categories=["string"],
description="description",
+ enterprise_only=True,
+ onboarding_priority=0,
priority=0,
)
assert_matches_type(ConnectorCatalog, admin, path=["response"])
@@ -558,7 +560,9 @@ def test_method_update_catalog_with_all_params(self, client: Structify) -> None:
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
categories=["string"],
description="description",
+ enterprise_only=True,
name="name",
+ onboarding_priority=0,
priority=0,
)
assert_matches_type(ConnectorCatalog, admin, path=["response"])
@@ -700,7 +704,7 @@ def test_path_params_update_scope(self, client: Structify) -> None:
def test_method_upload_logo(self, client: Structify) -> None:
admin = client.connector_catalog.admin.upload_logo(
slug="slug",
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(UploadLogoResponse, admin, path=["response"])
@@ -708,7 +712,7 @@ def test_method_upload_logo(self, client: Structify) -> None:
def test_raw_response_upload_logo(self, client: Structify) -> None:
response = client.connector_catalog.admin.with_raw_response.upload_logo(
slug="slug",
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -720,7 +724,7 @@ def test_raw_response_upload_logo(self, client: Structify) -> None:
def test_streaming_response_upload_logo(self, client: Structify) -> None:
with client.connector_catalog.admin.with_streaming_response.upload_logo(
slug="slug",
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -735,7 +739,7 @@ def test_path_params_upload_logo(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `slug` but received ''"):
client.connector_catalog.admin.with_raw_response.upload_logo(
slug="",
- file=b"raw file contents",
+ file=b"Example data",
)
@@ -912,6 +916,8 @@ async def test_method_create_catalog_with_all_params(self, async_client: AsyncSt
slug="slug",
categories=["string"],
description="description",
+ enterprise_only=True,
+ onboarding_priority=0,
priority=0,
)
assert_matches_type(ConnectorCatalog, admin, path=["response"])
@@ -1276,7 +1282,9 @@ async def test_method_update_catalog_with_all_params(self, async_client: AsyncSt
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
categories=["string"],
description="description",
+ enterprise_only=True,
name="name",
+ onboarding_priority=0,
priority=0,
)
assert_matches_type(ConnectorCatalog, admin, path=["response"])
@@ -1418,7 +1426,7 @@ async def test_path_params_update_scope(self, async_client: AsyncStructify) -> N
async def test_method_upload_logo(self, async_client: AsyncStructify) -> None:
admin = await async_client.connector_catalog.admin.upload_logo(
slug="slug",
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(UploadLogoResponse, admin, path=["response"])
@@ -1426,7 +1434,7 @@ async def test_method_upload_logo(self, async_client: AsyncStructify) -> None:
async def test_raw_response_upload_logo(self, async_client: AsyncStructify) -> None:
response = await async_client.connector_catalog.admin.with_raw_response.upload_logo(
slug="slug",
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -1438,7 +1446,7 @@ async def test_raw_response_upload_logo(self, async_client: AsyncStructify) -> N
async def test_streaming_response_upload_logo(self, async_client: AsyncStructify) -> None:
async with async_client.connector_catalog.admin.with_streaming_response.upload_logo(
slug="slug",
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1453,5 +1461,5 @@ async def test_path_params_upload_logo(self, async_client: AsyncStructify) -> No
with pytest.raises(ValueError, match=r"Expected a non-empty value for `slug` but received ''"):
await async_client.connector_catalog.admin.with_raw_response.upload_logo(
slug="",
- file=b"raw file contents",
+ file=b"Example data",
)
diff --git a/tests/api_resources/test_admin.py b/tests/api_resources/test_admin.py
new file mode 100644
index 000000000..2e6c742b9
--- /dev/null
+++ b/tests/api_resources/test_admin.py
@@ -0,0 +1,84 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from structify import Structify, AsyncStructify
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAdmin:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_report_critical(self, client: Structify) -> None:
+ admin = client.admin.report_critical(
+ message="message",
+ )
+ assert admin is None
+
+ @parametrize
+ def test_raw_response_report_critical(self, client: Structify) -> None:
+ response = client.admin.with_raw_response.report_critical(
+ message="message",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ admin = response.parse()
+ assert admin is None
+
+ @parametrize
+ def test_streaming_response_report_critical(self, client: Structify) -> None:
+ with client.admin.with_streaming_response.report_critical(
+ message="message",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ admin = response.parse()
+ assert admin is None
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncAdmin:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_report_critical(self, async_client: AsyncStructify) -> None:
+ admin = await async_client.admin.report_critical(
+ message="message",
+ )
+ assert admin is None
+
+ @parametrize
+ async def test_raw_response_report_critical(self, async_client: AsyncStructify) -> None:
+ response = await async_client.admin.with_raw_response.report_critical(
+ message="message",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ admin = await response.parse()
+ assert admin is None
+
+ @parametrize
+ async def test_streaming_response_report_critical(self, async_client: AsyncStructify) -> None:
+ async with async_client.admin.with_streaming_response.report_critical(
+ message="message",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ admin = await response.parse()
+ assert admin is None
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_chat.py b/tests/api_resources/test_chat.py
index 2d1b33db1..c2800d934 100644
--- a/tests/api_resources/test_chat.py
+++ b/tests/api_resources/test_chat.py
@@ -5,17 +5,21 @@
import os
from typing import Any, cast
+import httpx
import pytest
+from respx import MockRouter
from structify import Structify, AsyncStructify
from tests.utils import assert_matches_type
from structify.types import (
- ChatPrompt,
ChatSession,
+ ChatTemplate,
+ CompressChatResponse,
ChatLoadFilesResponse,
GetChatSessionResponse,
+ ListDashboardsResponse,
+ SimulatePromptResponse,
AdminIssueFoundResponse,
- ChatDeleteFilesResponse,
ChatSessionWithMessages,
GetDependenciesResponse,
AdminGrantAccessResponse,
@@ -27,9 +31,21 @@
CreateChatSessionResponse,
DeleteChatSessionResponse,
ListCollaboratorsResponse,
+ ChatListInputFilesResponse,
+ ChatLoadInputFilesResponse,
ChatRevertToCommitResponse,
+ ChatDeleteInputFileResponse,
ChatGetPartialChatsResponse,
+ ChatUploadInputFileResponse,
ChatGetSessionTimelineResponse,
+ ChatCopyNodeOutputByCodeHashResponse,
+)
+from structify._utils import parse_datetime
+from structify._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -126,44 +142,6 @@ def test_path_params_add_git_commit(self, client: Structify) -> None:
commit_hash="commit_hash",
)
- @parametrize
- def test_method_admin_get_chat_prompt(self, client: Structify) -> None:
- chat = client.chat.admin_get_chat_prompt(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(ChatPrompt, chat, path=["response"])
-
- @parametrize
- def test_raw_response_admin_get_chat_prompt(self, client: Structify) -> None:
- response = client.chat.with_raw_response.admin_get_chat_prompt(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- chat = response.parse()
- assert_matches_type(ChatPrompt, chat, path=["response"])
-
- @parametrize
- def test_streaming_response_admin_get_chat_prompt(self, client: Structify) -> None:
- with client.chat.with_streaming_response.admin_get_chat_prompt(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- chat = response.parse()
- assert_matches_type(ChatPrompt, chat, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_admin_get_chat_prompt(self, client: Structify) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
- client.chat.with_raw_response.admin_get_chat_prompt(
- "",
- )
-
@parametrize
def test_method_admin_issue_found(self, client: Structify) -> None:
chat = client.chat.admin_issue_found(
@@ -210,6 +188,44 @@ def test_path_params_admin_issue_found(self, client: Structify) -> None:
title="title",
)
+ @parametrize
+ def test_method_compress(self, client: Structify) -> None:
+ chat = client.chat.compress(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(CompressChatResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_compress(self, client: Structify) -> None:
+ response = client.chat.with_raw_response.compress(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(CompressChatResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_compress(self, client: Structify) -> None:
+ with client.chat.with_streaming_response.compress(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(CompressChatResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_compress(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
+ client.chat.with_raw_response.compress(
+ "",
+ )
+
@parametrize
def test_method_copy(self, client: Structify) -> None:
chat = client.chat.copy(
@@ -227,6 +243,7 @@ def test_method_copy_with_all_params(self, client: Structify) -> None:
team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
copy_inputs=True,
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ template_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(ChatSessionWithMessages, chat, path=["response"])
@@ -265,7 +282,7 @@ def test_method_copy_node_output_by_code_hash(self, client: Structify) -> None:
code_md5_hash="code_md5_hash",
new_node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(str, chat, path=["response"])
+ assert_matches_type(ChatCopyNodeOutputByCodeHashResponse, chat, path=["response"])
@parametrize
def test_raw_response_copy_node_output_by_code_hash(self, client: Structify) -> None:
@@ -278,7 +295,7 @@ def test_raw_response_copy_node_output_by_code_hash(self, client: Structify) ->
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
chat = response.parse()
- assert_matches_type(str, chat, path=["response"])
+ assert_matches_type(ChatCopyNodeOutputByCodeHashResponse, chat, path=["response"])
@parametrize
def test_streaming_response_copy_node_output_by_code_hash(self, client: Structify) -> None:
@@ -291,7 +308,7 @@ def test_streaming_response_copy_node_output_by_code_hash(self, client: Structif
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
chat = response.parse()
- assert_matches_type(str, chat, path=["response"])
+ assert_matches_type(ChatCopyNodeOutputByCodeHashResponse, chat, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -323,7 +340,6 @@ def test_method_create_session_with_all_params(self, client: Structify) -> None:
"system_prompt": "system_prompt",
},
ephemeral=True,
- initial_message="initial_message",
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(CreateChatSessionResponse, chat, path=["response"])
@@ -353,45 +369,45 @@ def test_streaming_response_create_session(self, client: Structify) -> None:
assert cast(Any, response.is_closed) is True
@parametrize
- def test_method_delete_files(self, client: Structify) -> None:
- chat = client.chat.delete_files(
+ def test_method_delete_input_file(self, client: Structify) -> None:
+ chat = client.chat.delete_input_file(
chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- paths=["string"],
+ filenames=["string"],
)
- assert_matches_type(ChatDeleteFilesResponse, chat, path=["response"])
+ assert_matches_type(ChatDeleteInputFileResponse, chat, path=["response"])
@parametrize
- def test_raw_response_delete_files(self, client: Structify) -> None:
- response = client.chat.with_raw_response.delete_files(
+ def test_raw_response_delete_input_file(self, client: Structify) -> None:
+ response = client.chat.with_raw_response.delete_input_file(
chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- paths=["string"],
+ filenames=["string"],
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
chat = response.parse()
- assert_matches_type(ChatDeleteFilesResponse, chat, path=["response"])
+ assert_matches_type(ChatDeleteInputFileResponse, chat, path=["response"])
@parametrize
- def test_streaming_response_delete_files(self, client: Structify) -> None:
- with client.chat.with_streaming_response.delete_files(
+ def test_streaming_response_delete_input_file(self, client: Structify) -> None:
+ with client.chat.with_streaming_response.delete_input_file(
chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- paths=["string"],
+ filenames=["string"],
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
chat = response.parse()
- assert_matches_type(ChatDeleteFilesResponse, chat, path=["response"])
+ assert_matches_type(ChatDeleteInputFileResponse, chat, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_delete_files(self, client: Structify) -> None:
+ def test_path_params_delete_input_file(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
- client.chat.with_raw_response.delete_files(
+ client.chat.with_raw_response.delete_input_file(
chat_id="",
- paths=["string"],
+ filenames=["string"],
)
@parametrize
@@ -632,6 +648,44 @@ def test_path_params_get_session_timeline(self, client: Structify) -> None:
"",
)
+ @parametrize
+ def test_method_get_template(self, client: Structify) -> None:
+ chat = client.chat.get_template(
+ "template_id",
+ )
+ assert_matches_type(ChatTemplate, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_get_template(self, client: Structify) -> None:
+ response = client.chat.with_raw_response.get_template(
+ "template_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ChatTemplate, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get_template(self, client: Structify) -> None:
+ with client.chat.with_streaming_response.get_template(
+ "template_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ChatTemplate, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get_template(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `template_id` but received ''"):
+ client.chat.with_raw_response.get_template(
+ "",
+ )
+
@parametrize
def test_method_grant_admin_override(self, client: Structify) -> None:
chat = client.chat.grant_admin_override(
@@ -716,6 +770,90 @@ def test_path_params_list_collaborators(self, client: Structify) -> None:
"",
)
+ @parametrize
+ def test_method_list_dashboards(self, client: Structify) -> None:
+ chat = client.chat.list_dashboards(
+ chat_id="chat_id",
+ )
+ assert_matches_type(ListDashboardsResponse, chat, path=["response"])
+
+ @parametrize
+ def test_method_list_dashboards_with_all_params(self, client: Structify) -> None:
+ chat = client.chat.list_dashboards(
+ chat_id="chat_id",
+ commit_hash="commit_hash",
+ )
+ assert_matches_type(ListDashboardsResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_list_dashboards(self, client: Structify) -> None:
+ response = client.chat.with_raw_response.list_dashboards(
+ chat_id="chat_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ListDashboardsResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list_dashboards(self, client: Structify) -> None:
+ with client.chat.with_streaming_response.list_dashboards(
+ chat_id="chat_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ListDashboardsResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list_dashboards(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ client.chat.with_raw_response.list_dashboards(
+ chat_id="",
+ )
+
+ @parametrize
+ def test_method_list_input_files(self, client: Structify) -> None:
+ chat = client.chat.list_input_files(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(ChatListInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_list_input_files(self, client: Structify) -> None:
+ response = client.chat.with_raw_response.list_input_files(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ChatListInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list_input_files(self, client: Structify) -> None:
+ with client.chat.with_streaming_response.list_input_files(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ChatListInputFilesResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list_input_files(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ client.chat.with_raw_response.list_input_files(
+ "",
+ )
+
@parametrize
def test_method_list_sessions(self, client: Structify) -> None:
chat = client.chat.list_sessions(
@@ -727,8 +865,12 @@ def test_method_list_sessions(self, client: Structify) -> None:
def test_method_list_sessions_with_all_params(self, client: Structify) -> None:
chat = client.chat.list_sessions(
team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
limit=0,
+ offset=0,
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ search="search",
+ tab="my_chats",
)
assert_matches_type(ListChatSessionsResponse, chat, path=["response"])
@@ -820,6 +962,118 @@ def test_streaming_response_load_files(self, client: Structify) -> None:
assert cast(Any, response.is_closed) is True
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_load_input_file(self, client: Structify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/chat/input-files/download/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/filename").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ chat = client.chat.load_input_file(
+ filename="filename",
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert chat.is_closed
+ assert chat.json() == {"foo": "bar"}
+ assert cast(Any, chat.is_closed) is True
+ assert isinstance(chat, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_raw_response_load_input_file(self, client: Structify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/chat/input-files/download/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/filename").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+
+ chat = client.chat.with_raw_response.load_input_file(
+ filename="filename",
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert chat.is_closed is True
+ assert chat.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert chat.json() == {"foo": "bar"}
+ assert isinstance(chat, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_streaming_response_load_input_file(self, client: Structify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/chat/input-files/download/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/filename").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ with client.chat.with_streaming_response.load_input_file(
+ filename="filename",
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as chat:
+ assert not chat.is_closed
+ assert chat.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert chat.json() == {"foo": "bar"}
+ assert cast(Any, chat.is_closed) is True
+ assert isinstance(chat, StreamedBinaryAPIResponse)
+
+ assert cast(Any, chat.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_path_params_load_input_file(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ client.chat.with_raw_response.load_input_file(
+ filename="filename",
+ chat_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `filename` but received ''"):
+ client.chat.with_raw_response.load_input_file(
+ filename="",
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ @parametrize
+ def test_method_load_input_files(self, client: Structify) -> None:
+ chat = client.chat.load_input_files(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(ChatLoadInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ def test_method_load_input_files_with_all_params(self, client: Structify) -> None:
+ chat = client.chat.load_input_files(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ since=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(ChatLoadInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_load_input_files(self, client: Structify) -> None:
+ response = client.chat.with_raw_response.load_input_files(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ChatLoadInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_load_input_files(self, client: Structify) -> None:
+ with client.chat.with_streaming_response.load_input_files(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ChatLoadInputFilesResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_load_input_files(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ client.chat.with_raw_response.load_input_files(
+ chat_id="",
+ )
+
@parametrize
def test_method_make_permanent(self, client: Structify) -> None:
chat = client.chat.make_permanent(
@@ -948,6 +1202,236 @@ def test_path_params_revert_to_commit(self, client: Structify) -> None:
commit_hash="commit_hash",
)
+ @parametrize
+ def test_method_simulate_prompt(self, client: Structify) -> None:
+ chat = client.chat.simulate_prompt(
+ chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ chat_prompt={
+ "decoding_params": {"parameters": [{"max_tokens": 0}]},
+ "messages": [
+ {
+ "content": [{"text": "Text"}],
+ "role": "user",
+ }
+ ],
+ "metadata": {
+ "dataset_descriptor": {
+ "description": "description",
+ "name": "name",
+ "relationships": [
+ {
+ "description": "description",
+ "name": "name",
+ "source_table": "source_table",
+ "target_table": "target_table",
+ }
+ ],
+ "tables": [
+ {
+ "description": "description",
+ "name": "name",
+ "properties": [
+ {
+ "description": "description",
+ "name": "name",
+ }
+ ],
+ }
+ ],
+ },
+ "extracted_entities": [
+ {
+ "entities": [
+ {
+ "id": 0,
+ "properties": {"foo": "string"},
+ "type": "type",
+ }
+ ]
+ }
+ ],
+ "extraction_criteria": [{"relationship_name": "relationship_name"}],
+ "formatter_specific": {"image_meta": {"image": "image"}},
+ },
+ },
+ )
+ assert_matches_type(SimulatePromptResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_simulate_prompt(self, client: Structify) -> None:
+ response = client.chat.with_raw_response.simulate_prompt(
+ chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ chat_prompt={
+ "decoding_params": {"parameters": [{"max_tokens": 0}]},
+ "messages": [
+ {
+ "content": [{"text": "Text"}],
+ "role": "user",
+ }
+ ],
+ "metadata": {
+ "dataset_descriptor": {
+ "description": "description",
+ "name": "name",
+ "relationships": [
+ {
+ "description": "description",
+ "name": "name",
+ "source_table": "source_table",
+ "target_table": "target_table",
+ }
+ ],
+ "tables": [
+ {
+ "description": "description",
+ "name": "name",
+ "properties": [
+ {
+ "description": "description",
+ "name": "name",
+ }
+ ],
+ }
+ ],
+ },
+ "extracted_entities": [
+ {
+ "entities": [
+ {
+ "id": 0,
+ "properties": {"foo": "string"},
+ "type": "type",
+ }
+ ]
+ }
+ ],
+ "extraction_criteria": [{"relationship_name": "relationship_name"}],
+ "formatter_specific": {"image_meta": {"image": "image"}},
+ },
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(SimulatePromptResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_simulate_prompt(self, client: Structify) -> None:
+ with client.chat.with_streaming_response.simulate_prompt(
+ chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ chat_prompt={
+ "decoding_params": {"parameters": [{"max_tokens": 0}]},
+ "messages": [
+ {
+ "content": [{"text": "Text"}],
+ "role": "user",
+ }
+ ],
+ "metadata": {
+ "dataset_descriptor": {
+ "description": "description",
+ "name": "name",
+ "relationships": [
+ {
+ "description": "description",
+ "name": "name",
+ "source_table": "source_table",
+ "target_table": "target_table",
+ }
+ ],
+ "tables": [
+ {
+ "description": "description",
+ "name": "name",
+ "properties": [
+ {
+ "description": "description",
+ "name": "name",
+ }
+ ],
+ }
+ ],
+ },
+ "extracted_entities": [
+ {
+ "entities": [
+ {
+ "id": 0,
+ "properties": {"foo": "string"},
+ "type": "type",
+ }
+ ]
+ }
+ ],
+ "extraction_criteria": [{"relationship_name": "relationship_name"}],
+ "formatter_specific": {"image_meta": {"image": "image"}},
+ },
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(SimulatePromptResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_simulate_prompt(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_session_id` but received ''"):
+ client.chat.with_raw_response.simulate_prompt(
+ chat_session_id="",
+ chat_prompt={
+ "decoding_params": {"parameters": [{"max_tokens": 0}]},
+ "messages": [
+ {
+ "content": [{"text": "Text"}],
+ "role": "user",
+ }
+ ],
+ "metadata": {
+ "dataset_descriptor": {
+ "description": "description",
+ "name": "name",
+ "relationships": [
+ {
+ "description": "description",
+ "name": "name",
+ "source_table": "source_table",
+ "target_table": "target_table",
+ }
+ ],
+ "tables": [
+ {
+ "description": "description",
+ "name": "name",
+ "properties": [
+ {
+ "description": "description",
+ "name": "name",
+ }
+ ],
+ }
+ ],
+ },
+ "extracted_entities": [
+ {
+ "entities": [
+ {
+ "id": 0,
+ "properties": {"foo": "string"},
+ "type": "type",
+ }
+ ]
+ }
+ ],
+ "extraction_criteria": [{"relationship_name": "relationship_name"}],
+ "formatter_specific": {"image_meta": {"image": "image"}},
+ },
+ },
+ )
+
@parametrize
def test_method_update_session(self, client: Structify) -> None:
chat = client.chat.update_session(
@@ -959,6 +1443,7 @@ def test_method_update_session(self, client: Structify) -> None:
def test_method_update_session_with_all_params(self, client: Structify) -> None:
chat = client.chat.update_session(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ message_head="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
name="name",
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
skip_confirmations=True,
@@ -1080,6 +1565,56 @@ def test_path_params_update_visibility(self, client: Structify) -> None:
visibility="private",
)
+ @parametrize
+ def test_method_upload_input_file(self, client: Structify) -> None:
+ chat = client.chat.upload_input_file(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ content=b"Example data",
+ content_type="content_type",
+ file_name="file_name",
+ )
+ assert_matches_type(ChatUploadInputFileResponse, chat, path=["response"])
+
+ @parametrize
+ def test_raw_response_upload_input_file(self, client: Structify) -> None:
+ response = client.chat.with_raw_response.upload_input_file(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ content=b"Example data",
+ content_type="content_type",
+ file_name="file_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = response.parse()
+ assert_matches_type(ChatUploadInputFileResponse, chat, path=["response"])
+
+ @parametrize
+ def test_streaming_response_upload_input_file(self, client: Structify) -> None:
+ with client.chat.with_streaming_response.upload_input_file(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ content=b"Example data",
+ content_type="content_type",
+ file_name="file_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = response.parse()
+ assert_matches_type(ChatUploadInputFileResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_upload_input_file(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ client.chat.with_raw_response.upload_input_file(
+ chat_id="",
+ content=b"Example data",
+ content_type="content_type",
+ file_name="file_name",
+ )
+
class TestAsyncChat:
parametrize = pytest.mark.parametrize(
@@ -1174,44 +1709,6 @@ async def test_path_params_add_git_commit(self, async_client: AsyncStructify) ->
commit_hash="commit_hash",
)
- @parametrize
- async def test_method_admin_get_chat_prompt(self, async_client: AsyncStructify) -> None:
- chat = await async_client.chat.admin_get_chat_prompt(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(ChatPrompt, chat, path=["response"])
-
- @parametrize
- async def test_raw_response_admin_get_chat_prompt(self, async_client: AsyncStructify) -> None:
- response = await async_client.chat.with_raw_response.admin_get_chat_prompt(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- chat = await response.parse()
- assert_matches_type(ChatPrompt, chat, path=["response"])
-
- @parametrize
- async def test_streaming_response_admin_get_chat_prompt(self, async_client: AsyncStructify) -> None:
- async with async_client.chat.with_streaming_response.admin_get_chat_prompt(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- chat = await response.parse()
- assert_matches_type(ChatPrompt, chat, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_admin_get_chat_prompt(self, async_client: AsyncStructify) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
- await async_client.chat.with_raw_response.admin_get_chat_prompt(
- "",
- )
-
@parametrize
async def test_method_admin_issue_found(self, async_client: AsyncStructify) -> None:
chat = await async_client.chat.admin_issue_found(
@@ -1258,6 +1755,44 @@ async def test_path_params_admin_issue_found(self, async_client: AsyncStructify)
title="title",
)
+ @parametrize
+ async def test_method_compress(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.compress(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(CompressChatResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_compress(self, async_client: AsyncStructify) -> None:
+ response = await async_client.chat.with_raw_response.compress(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(CompressChatResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_compress(self, async_client: AsyncStructify) -> None:
+ async with async_client.chat.with_streaming_response.compress(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(CompressChatResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_compress(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
+ await async_client.chat.with_raw_response.compress(
+ "",
+ )
+
@parametrize
async def test_method_copy(self, async_client: AsyncStructify) -> None:
chat = await async_client.chat.copy(
@@ -1275,6 +1810,7 @@ async def test_method_copy_with_all_params(self, async_client: AsyncStructify) -
team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
copy_inputs=True,
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ template_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(ChatSessionWithMessages, chat, path=["response"])
@@ -1313,7 +1849,7 @@ async def test_method_copy_node_output_by_code_hash(self, async_client: AsyncStr
code_md5_hash="code_md5_hash",
new_node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(str, chat, path=["response"])
+ assert_matches_type(ChatCopyNodeOutputByCodeHashResponse, chat, path=["response"])
@parametrize
async def test_raw_response_copy_node_output_by_code_hash(self, async_client: AsyncStructify) -> None:
@@ -1326,7 +1862,7 @@ async def test_raw_response_copy_node_output_by_code_hash(self, async_client: As
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
chat = await response.parse()
- assert_matches_type(str, chat, path=["response"])
+ assert_matches_type(ChatCopyNodeOutputByCodeHashResponse, chat, path=["response"])
@parametrize
async def test_streaming_response_copy_node_output_by_code_hash(self, async_client: AsyncStructify) -> None:
@@ -1339,7 +1875,7 @@ async def test_streaming_response_copy_node_output_by_code_hash(self, async_clie
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
chat = await response.parse()
- assert_matches_type(str, chat, path=["response"])
+ assert_matches_type(ChatCopyNodeOutputByCodeHashResponse, chat, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -1371,7 +1907,6 @@ async def test_method_create_session_with_all_params(self, async_client: AsyncSt
"system_prompt": "system_prompt",
},
ephemeral=True,
- initial_message="initial_message",
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(CreateChatSessionResponse, chat, path=["response"])
@@ -1401,45 +1936,45 @@ async def test_streaming_response_create_session(self, async_client: AsyncStruct
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_method_delete_files(self, async_client: AsyncStructify) -> None:
- chat = await async_client.chat.delete_files(
+ async def test_method_delete_input_file(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.delete_input_file(
chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- paths=["string"],
+ filenames=["string"],
)
- assert_matches_type(ChatDeleteFilesResponse, chat, path=["response"])
+ assert_matches_type(ChatDeleteInputFileResponse, chat, path=["response"])
@parametrize
- async def test_raw_response_delete_files(self, async_client: AsyncStructify) -> None:
- response = await async_client.chat.with_raw_response.delete_files(
+ async def test_raw_response_delete_input_file(self, async_client: AsyncStructify) -> None:
+ response = await async_client.chat.with_raw_response.delete_input_file(
chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- paths=["string"],
+ filenames=["string"],
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
chat = await response.parse()
- assert_matches_type(ChatDeleteFilesResponse, chat, path=["response"])
+ assert_matches_type(ChatDeleteInputFileResponse, chat, path=["response"])
@parametrize
- async def test_streaming_response_delete_files(self, async_client: AsyncStructify) -> None:
- async with async_client.chat.with_streaming_response.delete_files(
+ async def test_streaming_response_delete_input_file(self, async_client: AsyncStructify) -> None:
+ async with async_client.chat.with_streaming_response.delete_input_file(
chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- paths=["string"],
+ filenames=["string"],
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
chat = await response.parse()
- assert_matches_type(ChatDeleteFilesResponse, chat, path=["response"])
+ assert_matches_type(ChatDeleteInputFileResponse, chat, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_delete_files(self, async_client: AsyncStructify) -> None:
+ async def test_path_params_delete_input_file(self, async_client: AsyncStructify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
- await async_client.chat.with_raw_response.delete_files(
+ await async_client.chat.with_raw_response.delete_input_file(
chat_id="",
- paths=["string"],
+ filenames=["string"],
)
@parametrize
@@ -1680,6 +2215,44 @@ async def test_path_params_get_session_timeline(self, async_client: AsyncStructi
"",
)
+ @parametrize
+ async def test_method_get_template(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.get_template(
+ "template_id",
+ )
+ assert_matches_type(ChatTemplate, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get_template(self, async_client: AsyncStructify) -> None:
+ response = await async_client.chat.with_raw_response.get_template(
+ "template_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ChatTemplate, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get_template(self, async_client: AsyncStructify) -> None:
+ async with async_client.chat.with_streaming_response.get_template(
+ "template_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ChatTemplate, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get_template(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `template_id` but received ''"):
+ await async_client.chat.with_raw_response.get_template(
+ "",
+ )
+
@parametrize
async def test_method_grant_admin_override(self, async_client: AsyncStructify) -> None:
chat = await async_client.chat.grant_admin_override(
@@ -1764,6 +2337,90 @@ async def test_path_params_list_collaborators(self, async_client: AsyncStructify
"",
)
+ @parametrize
+ async def test_method_list_dashboards(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.list_dashboards(
+ chat_id="chat_id",
+ )
+ assert_matches_type(ListDashboardsResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_method_list_dashboards_with_all_params(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.list_dashboards(
+ chat_id="chat_id",
+ commit_hash="commit_hash",
+ )
+ assert_matches_type(ListDashboardsResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list_dashboards(self, async_client: AsyncStructify) -> None:
+ response = await async_client.chat.with_raw_response.list_dashboards(
+ chat_id="chat_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ListDashboardsResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list_dashboards(self, async_client: AsyncStructify) -> None:
+ async with async_client.chat.with_streaming_response.list_dashboards(
+ chat_id="chat_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ListDashboardsResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list_dashboards(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ await async_client.chat.with_raw_response.list_dashboards(
+ chat_id="",
+ )
+
+ @parametrize
+ async def test_method_list_input_files(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.list_input_files(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(ChatListInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list_input_files(self, async_client: AsyncStructify) -> None:
+ response = await async_client.chat.with_raw_response.list_input_files(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ChatListInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list_input_files(self, async_client: AsyncStructify) -> None:
+ async with async_client.chat.with_streaming_response.list_input_files(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ChatListInputFilesResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list_input_files(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ await async_client.chat.with_raw_response.list_input_files(
+ "",
+ )
+
@parametrize
async def test_method_list_sessions(self, async_client: AsyncStructify) -> None:
chat = await async_client.chat.list_sessions(
@@ -1775,8 +2432,12 @@ async def test_method_list_sessions(self, async_client: AsyncStructify) -> None:
async def test_method_list_sessions_with_all_params(self, async_client: AsyncStructify) -> None:
chat = await async_client.chat.list_sessions(
team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
limit=0,
+ offset=0,
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ search="search",
+ tab="my_chats",
)
assert_matches_type(ListChatSessionsResponse, chat, path=["response"])
@@ -1868,6 +2529,120 @@ async def test_streaming_response_load_files(self, async_client: AsyncStructify)
assert cast(Any, response.is_closed) is True
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_load_input_file(self, async_client: AsyncStructify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/chat/input-files/download/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/filename").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ chat = await async_client.chat.load_input_file(
+ filename="filename",
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert chat.is_closed
+ assert await chat.json() == {"foo": "bar"}
+ assert cast(Any, chat.is_closed) is True
+ assert isinstance(chat, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_raw_response_load_input_file(self, async_client: AsyncStructify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/chat/input-files/download/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/filename").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+
+ chat = await async_client.chat.with_raw_response.load_input_file(
+ filename="filename",
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert chat.is_closed is True
+ assert chat.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert await chat.json() == {"foo": "bar"}
+ assert isinstance(chat, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_streaming_response_load_input_file(
+ self, async_client: AsyncStructify, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.get("/chat/input-files/download/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/filename").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ async with async_client.chat.with_streaming_response.load_input_file(
+ filename="filename",
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as chat:
+ assert not chat.is_closed
+ assert chat.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert await chat.json() == {"foo": "bar"}
+ assert cast(Any, chat.is_closed) is True
+ assert isinstance(chat, AsyncStreamedBinaryAPIResponse)
+
+ assert cast(Any, chat.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_path_params_load_input_file(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ await async_client.chat.with_raw_response.load_input_file(
+ filename="filename",
+ chat_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `filename` but received ''"):
+ await async_client.chat.with_raw_response.load_input_file(
+ filename="",
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ @parametrize
+ async def test_method_load_input_files(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.load_input_files(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(ChatLoadInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_method_load_input_files_with_all_params(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.load_input_files(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ since=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(ChatLoadInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_load_input_files(self, async_client: AsyncStructify) -> None:
+ response = await async_client.chat.with_raw_response.load_input_files(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ChatLoadInputFilesResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_load_input_files(self, async_client: AsyncStructify) -> None:
+ async with async_client.chat.with_streaming_response.load_input_files(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ChatLoadInputFilesResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_load_input_files(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ await async_client.chat.with_raw_response.load_input_files(
+ chat_id="",
+ )
+
@parametrize
async def test_method_make_permanent(self, async_client: AsyncStructify) -> None:
chat = await async_client.chat.make_permanent(
@@ -1996,6 +2771,236 @@ async def test_path_params_revert_to_commit(self, async_client: AsyncStructify)
commit_hash="commit_hash",
)
+ @parametrize
+ async def test_method_simulate_prompt(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.simulate_prompt(
+ chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ chat_prompt={
+ "decoding_params": {"parameters": [{"max_tokens": 0}]},
+ "messages": [
+ {
+ "content": [{"text": "Text"}],
+ "role": "user",
+ }
+ ],
+ "metadata": {
+ "dataset_descriptor": {
+ "description": "description",
+ "name": "name",
+ "relationships": [
+ {
+ "description": "description",
+ "name": "name",
+ "source_table": "source_table",
+ "target_table": "target_table",
+ }
+ ],
+ "tables": [
+ {
+ "description": "description",
+ "name": "name",
+ "properties": [
+ {
+ "description": "description",
+ "name": "name",
+ }
+ ],
+ }
+ ],
+ },
+ "extracted_entities": [
+ {
+ "entities": [
+ {
+ "id": 0,
+ "properties": {"foo": "string"},
+ "type": "type",
+ }
+ ]
+ }
+ ],
+ "extraction_criteria": [{"relationship_name": "relationship_name"}],
+ "formatter_specific": {"image_meta": {"image": "image"}},
+ },
+ },
+ )
+ assert_matches_type(SimulatePromptResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_simulate_prompt(self, async_client: AsyncStructify) -> None:
+ response = await async_client.chat.with_raw_response.simulate_prompt(
+ chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ chat_prompt={
+ "decoding_params": {"parameters": [{"max_tokens": 0}]},
+ "messages": [
+ {
+ "content": [{"text": "Text"}],
+ "role": "user",
+ }
+ ],
+ "metadata": {
+ "dataset_descriptor": {
+ "description": "description",
+ "name": "name",
+ "relationships": [
+ {
+ "description": "description",
+ "name": "name",
+ "source_table": "source_table",
+ "target_table": "target_table",
+ }
+ ],
+ "tables": [
+ {
+ "description": "description",
+ "name": "name",
+ "properties": [
+ {
+ "description": "description",
+ "name": "name",
+ }
+ ],
+ }
+ ],
+ },
+ "extracted_entities": [
+ {
+ "entities": [
+ {
+ "id": 0,
+ "properties": {"foo": "string"},
+ "type": "type",
+ }
+ ]
+ }
+ ],
+ "extraction_criteria": [{"relationship_name": "relationship_name"}],
+ "formatter_specific": {"image_meta": {"image": "image"}},
+ },
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(SimulatePromptResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_simulate_prompt(self, async_client: AsyncStructify) -> None:
+ async with async_client.chat.with_streaming_response.simulate_prompt(
+ chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ chat_prompt={
+ "decoding_params": {"parameters": [{"max_tokens": 0}]},
+ "messages": [
+ {
+ "content": [{"text": "Text"}],
+ "role": "user",
+ }
+ ],
+ "metadata": {
+ "dataset_descriptor": {
+ "description": "description",
+ "name": "name",
+ "relationships": [
+ {
+ "description": "description",
+ "name": "name",
+ "source_table": "source_table",
+ "target_table": "target_table",
+ }
+ ],
+ "tables": [
+ {
+ "description": "description",
+ "name": "name",
+ "properties": [
+ {
+ "description": "description",
+ "name": "name",
+ }
+ ],
+ }
+ ],
+ },
+ "extracted_entities": [
+ {
+ "entities": [
+ {
+ "id": 0,
+ "properties": {"foo": "string"},
+ "type": "type",
+ }
+ ]
+ }
+ ],
+ "extraction_criteria": [{"relationship_name": "relationship_name"}],
+ "formatter_specific": {"image_meta": {"image": "image"}},
+ },
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(SimulatePromptResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_simulate_prompt(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_session_id` but received ''"):
+ await async_client.chat.with_raw_response.simulate_prompt(
+ chat_session_id="",
+ chat_prompt={
+ "decoding_params": {"parameters": [{"max_tokens": 0}]},
+ "messages": [
+ {
+ "content": [{"text": "Text"}],
+ "role": "user",
+ }
+ ],
+ "metadata": {
+ "dataset_descriptor": {
+ "description": "description",
+ "name": "name",
+ "relationships": [
+ {
+ "description": "description",
+ "name": "name",
+ "source_table": "source_table",
+ "target_table": "target_table",
+ }
+ ],
+ "tables": [
+ {
+ "description": "description",
+ "name": "name",
+ "properties": [
+ {
+ "description": "description",
+ "name": "name",
+ }
+ ],
+ }
+ ],
+ },
+ "extracted_entities": [
+ {
+ "entities": [
+ {
+ "id": 0,
+ "properties": {"foo": "string"},
+ "type": "type",
+ }
+ ]
+ }
+ ],
+ "extraction_criteria": [{"relationship_name": "relationship_name"}],
+ "formatter_specific": {"image_meta": {"image": "image"}},
+ },
+ },
+ )
+
@parametrize
async def test_method_update_session(self, async_client: AsyncStructify) -> None:
chat = await async_client.chat.update_session(
@@ -2007,6 +3012,7 @@ async def test_method_update_session(self, async_client: AsyncStructify) -> None
async def test_method_update_session_with_all_params(self, async_client: AsyncStructify) -> None:
chat = await async_client.chat.update_session(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ message_head="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
name="name",
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
skip_confirmations=True,
@@ -2127,3 +3133,53 @@ async def test_path_params_update_visibility(self, async_client: AsyncStructify)
session_id="",
visibility="private",
)
+
+ @parametrize
+ async def test_method_upload_input_file(self, async_client: AsyncStructify) -> None:
+ chat = await async_client.chat.upload_input_file(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ content=b"Example data",
+ content_type="content_type",
+ file_name="file_name",
+ )
+ assert_matches_type(ChatUploadInputFileResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_raw_response_upload_input_file(self, async_client: AsyncStructify) -> None:
+ response = await async_client.chat.with_raw_response.upload_input_file(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ content=b"Example data",
+ content_type="content_type",
+ file_name="file_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ chat = await response.parse()
+ assert_matches_type(ChatUploadInputFileResponse, chat, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_upload_input_file(self, async_client: AsyncStructify) -> None:
+ async with async_client.chat.with_streaming_response.upload_input_file(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ content=b"Example data",
+ content_type="content_type",
+ file_name="file_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ chat = await response.parse()
+ assert_matches_type(ChatUploadInputFileResponse, chat, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_upload_input_file(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ await async_client.chat.with_raw_response.upload_input_file(
+ chat_id="",
+ content=b"Example data",
+ content_type="content_type",
+ file_name="file_name",
+ )
diff --git a/tests/api_resources/test_code.py b/tests/api_resources/test_code.py
index ae45f5a7d..ee3fd18c4 100644
--- a/tests/api_resources/test_code.py
+++ b/tests/api_resources/test_code.py
@@ -15,6 +15,52 @@
class TestCode:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+ @parametrize
+ def test_method_apply_manual_edit(self, client: Structify) -> None:
+ code = client.code.apply_manual_edit(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ code="code",
+ filename="filename",
+ )
+ assert code is None
+
+ @parametrize
+ def test_raw_response_apply_manual_edit(self, client: Structify) -> None:
+ response = client.code.with_raw_response.apply_manual_edit(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ code="code",
+ filename="filename",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ code = response.parse()
+ assert code is None
+
+ @parametrize
+ def test_streaming_response_apply_manual_edit(self, client: Structify) -> None:
+ with client.code.with_streaming_response.apply_manual_edit(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ code="code",
+ filename="filename",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ code = response.parse()
+ assert code is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_apply_manual_edit(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ client.code.with_raw_response.apply_manual_edit(
+ chat_id="",
+ code="code",
+ filename="filename",
+ )
+
@parametrize
def test_method_generate_code(self, client: Structify) -> None:
code = client.code.generate_code(
@@ -107,6 +153,52 @@ class TestAsyncCode:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
+ @parametrize
+ async def test_method_apply_manual_edit(self, async_client: AsyncStructify) -> None:
+ code = await async_client.code.apply_manual_edit(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ code="code",
+ filename="filename",
+ )
+ assert code is None
+
+ @parametrize
+ async def test_raw_response_apply_manual_edit(self, async_client: AsyncStructify) -> None:
+ response = await async_client.code.with_raw_response.apply_manual_edit(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ code="code",
+ filename="filename",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ code = await response.parse()
+ assert code is None
+
+ @parametrize
+ async def test_streaming_response_apply_manual_edit(self, async_client: AsyncStructify) -> None:
+ async with async_client.code.with_streaming_response.apply_manual_edit(
+ chat_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ code="code",
+ filename="filename",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ code = await response.parse()
+ assert code is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_apply_manual_edit(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `chat_id` but received ''"):
+ await async_client.code.with_raw_response.apply_manual_edit(
+ chat_id="",
+ code="code",
+ filename="filename",
+ )
+
@parametrize
async def test_method_generate_code(self, async_client: AsyncStructify) -> None:
code = await async_client.code.generate_code(
diff --git a/tests/api_resources/test_connector_catalog.py b/tests/api_resources/test_connector_catalog.py
index 632fe5174..bae5c1420 100644
--- a/tests/api_resources/test_connector_catalog.py
+++ b/tests/api_resources/test_connector_catalog.py
@@ -33,6 +33,7 @@ def test_method_list(self, client: Structify) -> None:
@parametrize
def test_method_list_with_all_params(self, client: Structify) -> None:
connector_catalog = client.connector_catalog.list(
+ categories=["string"],
include_inactive=True,
limit=0,
offset=0,
@@ -162,6 +163,7 @@ async def test_method_list(self, async_client: AsyncStructify) -> None:
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncStructify) -> None:
connector_catalog = await async_client.connector_catalog.list(
+ categories=["string"],
include_inactive=True,
limit=0,
offset=0,
diff --git a/tests/api_resources/test_connectors.py b/tests/api_resources/test_connectors.py
index c1cd9fe39..138becde0 100644
--- a/tests/api_resources/test_connectors.py
+++ b/tests/api_resources/test_connectors.py
@@ -3,29 +3,41 @@
from __future__ import annotations
import os
-from typing import Any, cast
+from typing import Any, Optional, cast
+import httpx
import pytest
+from respx import MockRouter
from structify import Structify, AsyncStructify
from tests.utils import assert_matches_type
from structify.types import (
Connector,
+ ExplorationRun,
ListTablesResponse,
+ ExplorationProgress,
UpdateTableResponse,
ConnectorGetResponse,
ConnectorWithSecrets,
ExplorerChatResponse,
- ExploreStatusResponse,
ConnectorStoreResponse,
ExplorationRunsResponse,
+ ConnectorExploreResponse,
ConnectorSummariesResponse,
+ ConnectorTablePathResponse,
DeleteSchemaObjectResponse,
+ ConnectorListStoresResponse,
ConnectorSearchTablesResponse,
ConnectorAddSchemaObjectResponse,
ConnectorListWithSnippetsResponse,
ConnectorGetClarificationRequestsResponse,
)
+from structify._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
+)
from structify.pagination import SyncJobsList, AsyncJobsList
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -39,7 +51,6 @@ def test_method_create(self, client: Structify) -> None:
connector = client.connectors.create(
known_connector_type="known_connector_type",
name="name",
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(Connector, connector, path=["response"])
@@ -48,14 +59,8 @@ def test_method_create_with_all_params(self, client: Structify) -> None:
connector = client.connectors.create(
known_connector_type="known_connector_type",
name="name",
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
description="description",
nango_connection_id="nango_connection_id",
- nango_integration_id="nango_integration_id",
- pipedream_account_id="pipedream_account_id",
- pipedream_external_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- pipedream_project_id="pipedream_project_id",
- refresh_script="refresh_script",
secrets={"foo": "string"},
)
assert_matches_type(Connector, connector, path=["response"])
@@ -65,7 +70,6 @@ def test_raw_response_create(self, client: Structify) -> None:
response = client.connectors.with_raw_response.create(
known_connector_type="known_connector_type",
name="name",
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
@@ -78,7 +82,6 @@ def test_streaming_response_create(self, client: Structify) -> None:
with client.connectors.with_streaming_response.create(
known_connector_type="known_connector_type",
name="name",
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -99,11 +102,20 @@ def test_method_update(self, client: Structify) -> None:
def test_method_update_with_all_params(self, client: Structify) -> None:
connector = client.connectors.update(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_category="RelationalDatabase",
+ datahub_ingestion_type="datahub_ingestion_type",
+ datahub_secret_map={"foo": "string"},
+ datahub_urn="datahub_urn",
description="description",
known_connector_type="known_connector_type",
name="name",
- refresh_script="refresh_script",
+ nango_connection_id="nango_connection_id",
+ oauth_scopes=["string"],
+ owner_user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ refresh_cron_schedule="refresh_cron_schedule",
+ team_visibility="Team",
usage_snippet_override="usage_snippet_override",
+ user_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert connector is None
@@ -140,15 +152,12 @@ def test_path_params_update(self, client: Structify) -> None:
@parametrize
def test_method_list(self, client: Structify) -> None:
- connector = client.connectors.list(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
+ connector = client.connectors.list()
assert_matches_type(SyncJobsList[ConnectorWithSecrets], connector, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Structify) -> None:
connector = client.connectors.list(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
limit=0,
offset=0,
)
@@ -156,9 +165,7 @@ def test_method_list_with_all_params(self, client: Structify) -> None:
@parametrize
def test_raw_response_list(self, client: Structify) -> None:
- response = client.connectors.with_raw_response.list(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
+ response = client.connectors.with_raw_response.list()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -167,9 +174,7 @@ def test_raw_response_list(self, client: Structify) -> None:
@parametrize
def test_streaming_response_list(self, client: Structify) -> None:
- with client.connectors.with_streaming_response.list(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
+ with client.connectors.with_streaming_response.list() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -742,23 +747,105 @@ def test_path_params_delete_secret(self, client: Structify) -> None:
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_download_datahub_artifact(self, client: Structify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/internal/connectors/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/datahub-artifacts/kind").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ connector = client.connectors.download_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert connector.is_closed
+ assert connector.json() == {"foo": "bar"}
+ assert cast(Any, connector.is_closed) is True
+ assert isinstance(connector, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_download_datahub_artifact_with_all_params(self, client: Structify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/internal/connectors/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/datahub-artifacts/kind").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ connector = client.connectors.download_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert connector.is_closed
+ assert connector.json() == {"foo": "bar"}
+ assert cast(Any, connector.is_closed) is True
+ assert isinstance(connector, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_raw_response_download_datahub_artifact(self, client: Structify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/internal/connectors/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/datahub-artifacts/kind").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+
+ connector = client.connectors.with_raw_response.download_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert connector.is_closed is True
+ assert connector.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert connector.json() == {"foo": "bar"}
+ assert isinstance(connector, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_streaming_response_download_datahub_artifact(self, client: Structify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/internal/connectors/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/datahub-artifacts/kind").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ with client.connectors.with_streaming_response.download_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as connector:
+ assert not connector.is_closed
+ assert connector.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert connector.json() == {"foo": "bar"}
+ assert cast(Any, connector.is_closed) is True
+ assert isinstance(connector, StreamedBinaryAPIResponse)
+
+ assert cast(Any, connector.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_path_params_download_datahub_artifact(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
+ client.connectors.with_raw_response.download_datahub_artifact(
+ kind="kind",
+ connector_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `kind` but received ''"):
+ client.connectors.with_raw_response.download_datahub_artifact(
+ kind="",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
@parametrize
def test_method_explore(self, client: Structify) -> None:
connector = client.connectors.explore(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert connector is None
+ assert_matches_type(ConnectorExploreResponse, connector, path=["response"])
@parametrize
def test_method_explore_with_all_params(self, client: Structify) -> None:
connector = client.connectors.explore(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
database_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ only_do_datahub=True,
schema_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- stage="both",
table_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert connector is None
+ assert_matches_type(ConnectorExploreResponse, connector, path=["response"])
@parametrize
def test_raw_response_explore(self, client: Structify) -> None:
@@ -769,7 +856,7 @@ def test_raw_response_explore(self, client: Structify) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = response.parse()
- assert connector is None
+ assert_matches_type(ConnectorExploreResponse, connector, path=["response"])
@parametrize
def test_streaming_response_explore(self, client: Structify) -> None:
@@ -780,7 +867,7 @@ def test_streaming_response_explore(self, client: Structify) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = response.parse()
- assert connector is None
+ assert_matches_type(ConnectorExploreResponse, connector, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -829,6 +916,44 @@ def test_path_params_get(self, client: Structify) -> None:
"",
)
+ @parametrize
+ def test_method_get_active_exploration_run(self, client: Structify) -> None:
+ connector = client.connectors.get_active_exploration_run(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(Optional[ExplorationRun], connector, path=["response"])
+
+ @parametrize
+ def test_raw_response_get_active_exploration_run(self, client: Structify) -> None:
+ response = client.connectors.with_raw_response.get_active_exploration_run(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = response.parse()
+ assert_matches_type(Optional[ExplorationRun], connector, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get_active_exploration_run(self, client: Structify) -> None:
+ with client.connectors.with_streaming_response.get_active_exploration_run(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = response.parse()
+ assert_matches_type(Optional[ExplorationRun], connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get_active_exploration_run(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
+ client.connectors.with_raw_response.get_active_exploration_run(
+ "",
+ )
+
@parametrize
def test_method_get_clarification_requests(self, client: Structify) -> None:
connector = client.connectors.get_clarification_requests(
@@ -868,78 +993,88 @@ def test_path_params_get_clarification_requests(self, client: Structify) -> None
)
@parametrize
- def test_method_get_exploration_runs(self, client: Structify) -> None:
- connector = client.connectors.get_exploration_runs(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ def test_method_get_exploration_run_progress(self, client: Structify) -> None:
+ connector = client.connectors.get_exploration_run_progress(
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
+ assert_matches_type(ExplorationProgress, connector, path=["response"])
@parametrize
- def test_raw_response_get_exploration_runs(self, client: Structify) -> None:
- response = client.connectors.with_raw_response.get_exploration_runs(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ def test_raw_response_get_exploration_run_progress(self, client: Structify) -> None:
+ response = client.connectors.with_raw_response.get_exploration_run_progress(
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = response.parse()
- assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
+ assert_matches_type(ExplorationProgress, connector, path=["response"])
@parametrize
- def test_streaming_response_get_exploration_runs(self, client: Structify) -> None:
- with client.connectors.with_streaming_response.get_exploration_runs(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ def test_streaming_response_get_exploration_run_progress(self, client: Structify) -> None:
+ with client.connectors.with_streaming_response.get_exploration_run_progress(
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = response.parse()
- assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
+ assert_matches_type(ExplorationProgress, connector, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_get_exploration_runs(self, client: Structify) -> None:
+ def test_path_params_get_exploration_run_progress(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
- client.connectors.with_raw_response.get_exploration_runs(
- "",
+ client.connectors.with_raw_response.get_exploration_run_progress(
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `run_id` but received ''"):
+ client.connectors.with_raw_response.get_exploration_run_progress(
+ run_id="",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@parametrize
- def test_method_get_exploration_status(self, client: Structify) -> None:
- connector = client.connectors.get_exploration_status(
+ def test_method_get_exploration_runs(self, client: Structify) -> None:
+ connector = client.connectors.get_exploration_runs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(ExploreStatusResponse, connector, path=["response"])
+ assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
@parametrize
- def test_raw_response_get_exploration_status(self, client: Structify) -> None:
- response = client.connectors.with_raw_response.get_exploration_status(
+ def test_raw_response_get_exploration_runs(self, client: Structify) -> None:
+ response = client.connectors.with_raw_response.get_exploration_runs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = response.parse()
- assert_matches_type(ExploreStatusResponse, connector, path=["response"])
+ assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
@parametrize
- def test_streaming_response_get_exploration_status(self, client: Structify) -> None:
- with client.connectors.with_streaming_response.get_exploration_status(
+ def test_streaming_response_get_exploration_runs(self, client: Structify) -> None:
+ with client.connectors.with_streaming_response.get_exploration_runs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = response.parse()
- assert_matches_type(ExploreStatusResponse, connector, path=["response"])
+ assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_get_exploration_status(self, client: Structify) -> None:
+ def test_path_params_get_exploration_runs(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
- client.connectors.with_raw_response.get_exploration_status(
+ client.connectors.with_raw_response.get_exploration_runs(
"",
)
@@ -947,7 +1082,17 @@ def test_path_params_get_exploration_status(self, client: Structify) -> None:
def test_method_get_explorer_chat(self, client: Structify) -> None:
connector = client.connectors.get_explorer_chat(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- run_id="run_id",
+ )
+ assert_matches_type(ExplorerChatResponse, connector, path=["response"])
+
+ @parametrize
+ def test_method_get_explorer_chat_with_all_params(self, client: Structify) -> None:
+ connector = client.connectors.get_explorer_chat(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ database_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ schema_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ table_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(ExplorerChatResponse, connector, path=["response"])
@@ -955,7 +1100,6 @@ def test_method_get_explorer_chat(self, client: Structify) -> None:
def test_raw_response_get_explorer_chat(self, client: Structify) -> None:
response = client.connectors.with_raw_response.get_explorer_chat(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- run_id="run_id",
)
assert response.is_closed is True
@@ -967,7 +1111,6 @@ def test_raw_response_get_explorer_chat(self, client: Structify) -> None:
def test_streaming_response_get_explorer_chat(self, client: Structify) -> None:
with client.connectors.with_streaming_response.get_explorer_chat(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- run_id="run_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -982,7 +1125,6 @@ def test_path_params_get_explorer_chat(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
client.connectors.with_raw_response.get_explorer_chat(
connector_id="",
- run_id="run_id",
)
@parametrize
@@ -1023,6 +1165,69 @@ def test_path_params_get_store(self, client: Structify) -> None:
"",
)
+ @parametrize
+ def test_method_get_table_path(self, client: Structify) -> None:
+ connector = client.connectors.get_table_path(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(ConnectorTablePathResponse, connector, path=["response"])
+
+ @parametrize
+ def test_raw_response_get_table_path(self, client: Structify) -> None:
+ response = client.connectors.with_raw_response.get_table_path(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = response.parse()
+ assert_matches_type(ConnectorTablePathResponse, connector, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get_table_path(self, client: Structify) -> None:
+ with client.connectors.with_streaming_response.get_table_path(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = response.parse()
+ assert_matches_type(ConnectorTablePathResponse, connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get_table_path(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `table_id` but received ''"):
+ client.connectors.with_raw_response.get_table_path(
+ "",
+ )
+
+ @parametrize
+ def test_method_list_stores(self, client: Structify) -> None:
+ connector = client.connectors.list_stores()
+ assert_matches_type(ConnectorListStoresResponse, connector, path=["response"])
+
+ @parametrize
+ def test_raw_response_list_stores(self, client: Structify) -> None:
+ response = client.connectors.with_raw_response.list_stores()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = response.parse()
+ assert_matches_type(ConnectorListStoresResponse, connector, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list_stores(self, client: Structify) -> None:
+ with client.connectors.with_streaming_response.list_stores() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = response.parse()
+ assert_matches_type(ConnectorListStoresResponse, connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@parametrize
def test_method_list_tables(self, client: Structify) -> None:
connector = client.connectors.list_tables(
@@ -1063,16 +1268,12 @@ def test_path_params_list_tables(self, client: Structify) -> None:
@parametrize
def test_method_list_with_snippets(self, client: Structify) -> None:
- connector = client.connectors.list_with_snippets(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
+ connector = client.connectors.list_with_snippets()
assert_matches_type(ConnectorListWithSnippetsResponse, connector, path=["response"])
@parametrize
def test_raw_response_list_with_snippets(self, client: Structify) -> None:
- response = client.connectors.with_raw_response.list_with_snippets(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
+ response = client.connectors.with_raw_response.list_with_snippets()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1081,9 +1282,7 @@ def test_raw_response_list_with_snippets(self, client: Structify) -> None:
@parametrize
def test_streaming_response_list_with_snippets(self, client: Structify) -> None:
- with client.connectors.with_streaming_response.list_with_snippets(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
+ with client.connectors.with_streaming_response.list_with_snippets() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1168,7 +1367,6 @@ def test_streaming_response_search_tables(self, client: Structify) -> None:
def test_method_summaries(self, client: Structify) -> None:
connector = client.connectors.summaries(
connector_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(ConnectorSummariesResponse, connector, path=["response"])
@@ -1176,7 +1374,6 @@ def test_method_summaries(self, client: Structify) -> None:
def test_raw_response_summaries(self, client: Structify) -> None:
response = client.connectors.with_raw_response.summaries(
connector_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
@@ -1188,7 +1385,6 @@ def test_raw_response_summaries(self, client: Structify) -> None:
def test_streaming_response_summaries(self, client: Structify) -> None:
with client.connectors.with_streaming_response.summaries(
connector_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1291,6 +1487,64 @@ def test_path_params_update_table(self, client: Structify) -> None:
table_id="",
)
+ @parametrize
+ def test_method_upload_datahub_artifact(self, client: Structify) -> None:
+ connector = client.connectors.upload_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ )
+ assert connector is None
+
+ @parametrize
+ def test_raw_response_upload_datahub_artifact(self, client: Structify) -> None:
+ response = client.connectors.with_raw_response.upload_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = response.parse()
+ assert connector is None
+
+ @parametrize
+ def test_streaming_response_upload_datahub_artifact(self, client: Structify) -> None:
+ with client.connectors.with_streaming_response.upload_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = response.parse()
+ assert connector is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_upload_datahub_artifact(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
+ client.connectors.with_raw_response.upload_datahub_artifact(
+ kind="kind",
+ connector_id="",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `kind` but received ''"):
+ client.connectors.with_raw_response.upload_datahub_artifact(
+ kind="",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ )
+
class TestAsyncConnectors:
parametrize = pytest.mark.parametrize(
@@ -1302,7 +1556,6 @@ async def test_method_create(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.create(
known_connector_type="known_connector_type",
name="name",
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(Connector, connector, path=["response"])
@@ -1311,14 +1564,8 @@ async def test_method_create_with_all_params(self, async_client: AsyncStructify)
connector = await async_client.connectors.create(
known_connector_type="known_connector_type",
name="name",
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
description="description",
nango_connection_id="nango_connection_id",
- nango_integration_id="nango_integration_id",
- pipedream_account_id="pipedream_account_id",
- pipedream_external_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- pipedream_project_id="pipedream_project_id",
- refresh_script="refresh_script",
secrets={"foo": "string"},
)
assert_matches_type(Connector, connector, path=["response"])
@@ -1328,7 +1575,6 @@ async def test_raw_response_create(self, async_client: AsyncStructify) -> None:
response = await async_client.connectors.with_raw_response.create(
known_connector_type="known_connector_type",
name="name",
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
@@ -1341,7 +1587,6 @@ async def test_streaming_response_create(self, async_client: AsyncStructify) ->
async with async_client.connectors.with_streaming_response.create(
known_connector_type="known_connector_type",
name="name",
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1362,11 +1607,20 @@ async def test_method_update(self, async_client: AsyncStructify) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.update(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_category="RelationalDatabase",
+ datahub_ingestion_type="datahub_ingestion_type",
+ datahub_secret_map={"foo": "string"},
+ datahub_urn="datahub_urn",
description="description",
known_connector_type="known_connector_type",
name="name",
- refresh_script="refresh_script",
+ nango_connection_id="nango_connection_id",
+ oauth_scopes=["string"],
+ owner_user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ refresh_cron_schedule="refresh_cron_schedule",
+ team_visibility="Team",
usage_snippet_override="usage_snippet_override",
+ user_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
)
assert connector is None
@@ -1403,15 +1657,12 @@ async def test_path_params_update(self, async_client: AsyncStructify) -> None:
@parametrize
async def test_method_list(self, async_client: AsyncStructify) -> None:
- connector = await async_client.connectors.list(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
+ connector = await async_client.connectors.list()
assert_matches_type(AsyncJobsList[ConnectorWithSecrets], connector, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.list(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
limit=0,
offset=0,
)
@@ -1419,9 +1670,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncStructify) -
@parametrize
async def test_raw_response_list(self, async_client: AsyncStructify) -> None:
- response = await async_client.connectors.with_raw_response.list(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
+ response = await async_client.connectors.with_raw_response.list()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1430,9 +1679,7 @@ async def test_raw_response_list(self, async_client: AsyncStructify) -> None:
@parametrize
async def test_streaming_response_list(self, async_client: AsyncStructify) -> None:
- async with async_client.connectors.with_streaming_response.list(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
+ async with async_client.connectors.with_streaming_response.list() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -2005,23 +2252,111 @@ async def test_path_params_delete_secret(self, async_client: AsyncStructify) ->
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_download_datahub_artifact(self, async_client: AsyncStructify, respx_mock: MockRouter) -> None:
+ respx_mock.get("/internal/connectors/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/datahub-artifacts/kind").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ connector = await async_client.connectors.download_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert connector.is_closed
+ assert await connector.json() == {"foo": "bar"}
+ assert cast(Any, connector.is_closed) is True
+ assert isinstance(connector, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_download_datahub_artifact_with_all_params(
+ self, async_client: AsyncStructify, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.get("/internal/connectors/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/datahub-artifacts/kind").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ connector = await async_client.connectors.download_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert connector.is_closed
+ assert await connector.json() == {"foo": "bar"}
+ assert cast(Any, connector.is_closed) is True
+ assert isinstance(connector, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_raw_response_download_datahub_artifact(
+ self, async_client: AsyncStructify, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.get("/internal/connectors/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/datahub-artifacts/kind").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+
+ connector = await async_client.connectors.with_raw_response.download_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert connector.is_closed is True
+ assert connector.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert await connector.json() == {"foo": "bar"}
+ assert isinstance(connector, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_streaming_response_download_datahub_artifact(
+ self, async_client: AsyncStructify, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.get("/internal/connectors/182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e/datahub-artifacts/kind").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ async with async_client.connectors.with_streaming_response.download_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as connector:
+ assert not connector.is_closed
+ assert connector.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert await connector.json() == {"foo": "bar"}
+ assert cast(Any, connector.is_closed) is True
+ assert isinstance(connector, AsyncStreamedBinaryAPIResponse)
+
+ assert cast(Any, connector.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_path_params_download_datahub_artifact(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
+ await async_client.connectors.with_raw_response.download_datahub_artifact(
+ kind="kind",
+ connector_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `kind` but received ''"):
+ await async_client.connectors.with_raw_response.download_datahub_artifact(
+ kind="",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
@parametrize
async def test_method_explore(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.explore(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert connector is None
+ assert_matches_type(ConnectorExploreResponse, connector, path=["response"])
@parametrize
async def test_method_explore_with_all_params(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.explore(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
database_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ only_do_datahub=True,
schema_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- stage="both",
table_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert connector is None
+ assert_matches_type(ConnectorExploreResponse, connector, path=["response"])
@parametrize
async def test_raw_response_explore(self, async_client: AsyncStructify) -> None:
@@ -2032,7 +2367,7 @@ async def test_raw_response_explore(self, async_client: AsyncStructify) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = await response.parse()
- assert connector is None
+ assert_matches_type(ConnectorExploreResponse, connector, path=["response"])
@parametrize
async def test_streaming_response_explore(self, async_client: AsyncStructify) -> None:
@@ -2043,7 +2378,7 @@ async def test_streaming_response_explore(self, async_client: AsyncStructify) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = await response.parse()
- assert connector is None
+ assert_matches_type(ConnectorExploreResponse, connector, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -2092,6 +2427,44 @@ async def test_path_params_get(self, async_client: AsyncStructify) -> None:
"",
)
+ @parametrize
+ async def test_method_get_active_exploration_run(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.connectors.get_active_exploration_run(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(Optional[ExplorationRun], connector, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get_active_exploration_run(self, async_client: AsyncStructify) -> None:
+ response = await async_client.connectors.with_raw_response.get_active_exploration_run(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = await response.parse()
+ assert_matches_type(Optional[ExplorationRun], connector, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get_active_exploration_run(self, async_client: AsyncStructify) -> None:
+ async with async_client.connectors.with_streaming_response.get_active_exploration_run(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = await response.parse()
+ assert_matches_type(Optional[ExplorationRun], connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get_active_exploration_run(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
+ await async_client.connectors.with_raw_response.get_active_exploration_run(
+ "",
+ )
+
@parametrize
async def test_method_get_clarification_requests(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.get_clarification_requests(
@@ -2131,78 +2504,88 @@ async def test_path_params_get_clarification_requests(self, async_client: AsyncS
)
@parametrize
- async def test_method_get_exploration_runs(self, async_client: AsyncStructify) -> None:
- connector = await async_client.connectors.get_exploration_runs(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ async def test_method_get_exploration_run_progress(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.connectors.get_exploration_run_progress(
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
+ assert_matches_type(ExplorationProgress, connector, path=["response"])
@parametrize
- async def test_raw_response_get_exploration_runs(self, async_client: AsyncStructify) -> None:
- response = await async_client.connectors.with_raw_response.get_exploration_runs(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ async def test_raw_response_get_exploration_run_progress(self, async_client: AsyncStructify) -> None:
+ response = await async_client.connectors.with_raw_response.get_exploration_run_progress(
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = await response.parse()
- assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
+ assert_matches_type(ExplorationProgress, connector, path=["response"])
@parametrize
- async def test_streaming_response_get_exploration_runs(self, async_client: AsyncStructify) -> None:
- async with async_client.connectors.with_streaming_response.get_exploration_runs(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ async def test_streaming_response_get_exploration_run_progress(self, async_client: AsyncStructify) -> None:
+ async with async_client.connectors.with_streaming_response.get_exploration_run_progress(
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = await response.parse()
- assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
+ assert_matches_type(ExplorationProgress, connector, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_get_exploration_runs(self, async_client: AsyncStructify) -> None:
+ async def test_path_params_get_exploration_run_progress(self, async_client: AsyncStructify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
- await async_client.connectors.with_raw_response.get_exploration_runs(
- "",
+ await async_client.connectors.with_raw_response.get_exploration_run_progress(
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ connector_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `run_id` but received ''"):
+ await async_client.connectors.with_raw_response.get_exploration_run_progress(
+ run_id="",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@parametrize
- async def test_method_get_exploration_status(self, async_client: AsyncStructify) -> None:
- connector = await async_client.connectors.get_exploration_status(
+ async def test_method_get_exploration_runs(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.connectors.get_exploration_runs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(ExploreStatusResponse, connector, path=["response"])
+ assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
@parametrize
- async def test_raw_response_get_exploration_status(self, async_client: AsyncStructify) -> None:
- response = await async_client.connectors.with_raw_response.get_exploration_status(
+ async def test_raw_response_get_exploration_runs(self, async_client: AsyncStructify) -> None:
+ response = await async_client.connectors.with_raw_response.get_exploration_runs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = await response.parse()
- assert_matches_type(ExploreStatusResponse, connector, path=["response"])
+ assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
@parametrize
- async def test_streaming_response_get_exploration_status(self, async_client: AsyncStructify) -> None:
- async with async_client.connectors.with_streaming_response.get_exploration_status(
+ async def test_streaming_response_get_exploration_runs(self, async_client: AsyncStructify) -> None:
+ async with async_client.connectors.with_streaming_response.get_exploration_runs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
connector = await response.parse()
- assert_matches_type(ExploreStatusResponse, connector, path=["response"])
+ assert_matches_type(ExplorationRunsResponse, connector, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_get_exploration_status(self, async_client: AsyncStructify) -> None:
+ async def test_path_params_get_exploration_runs(self, async_client: AsyncStructify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
- await async_client.connectors.with_raw_response.get_exploration_status(
+ await async_client.connectors.with_raw_response.get_exploration_runs(
"",
)
@@ -2210,7 +2593,17 @@ async def test_path_params_get_exploration_status(self, async_client: AsyncStruc
async def test_method_get_explorer_chat(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.get_explorer_chat(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- run_id="run_id",
+ )
+ assert_matches_type(ExplorerChatResponse, connector, path=["response"])
+
+ @parametrize
+ async def test_method_get_explorer_chat_with_all_params(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.connectors.get_explorer_chat(
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ database_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ schema_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ table_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(ExplorerChatResponse, connector, path=["response"])
@@ -2218,7 +2611,6 @@ async def test_method_get_explorer_chat(self, async_client: AsyncStructify) -> N
async def test_raw_response_get_explorer_chat(self, async_client: AsyncStructify) -> None:
response = await async_client.connectors.with_raw_response.get_explorer_chat(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- run_id="run_id",
)
assert response.is_closed is True
@@ -2230,7 +2622,6 @@ async def test_raw_response_get_explorer_chat(self, async_client: AsyncStructify
async def test_streaming_response_get_explorer_chat(self, async_client: AsyncStructify) -> None:
async with async_client.connectors.with_streaming_response.get_explorer_chat(
connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- run_id="run_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -2245,7 +2636,6 @@ async def test_path_params_get_explorer_chat(self, async_client: AsyncStructify)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
await async_client.connectors.with_raw_response.get_explorer_chat(
connector_id="",
- run_id="run_id",
)
@parametrize
@@ -2286,6 +2676,69 @@ async def test_path_params_get_store(self, async_client: AsyncStructify) -> None
"",
)
+ @parametrize
+ async def test_method_get_table_path(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.connectors.get_table_path(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(ConnectorTablePathResponse, connector, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get_table_path(self, async_client: AsyncStructify) -> None:
+ response = await async_client.connectors.with_raw_response.get_table_path(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = await response.parse()
+ assert_matches_type(ConnectorTablePathResponse, connector, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get_table_path(self, async_client: AsyncStructify) -> None:
+ async with async_client.connectors.with_streaming_response.get_table_path(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = await response.parse()
+ assert_matches_type(ConnectorTablePathResponse, connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get_table_path(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `table_id` but received ''"):
+ await async_client.connectors.with_raw_response.get_table_path(
+ "",
+ )
+
+ @parametrize
+ async def test_method_list_stores(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.connectors.list_stores()
+ assert_matches_type(ConnectorListStoresResponse, connector, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list_stores(self, async_client: AsyncStructify) -> None:
+ response = await async_client.connectors.with_raw_response.list_stores()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = await response.parse()
+ assert_matches_type(ConnectorListStoresResponse, connector, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list_stores(self, async_client: AsyncStructify) -> None:
+ async with async_client.connectors.with_streaming_response.list_stores() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = await response.parse()
+ assert_matches_type(ConnectorListStoresResponse, connector, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@parametrize
async def test_method_list_tables(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.list_tables(
@@ -2326,16 +2779,12 @@ async def test_path_params_list_tables(self, async_client: AsyncStructify) -> No
@parametrize
async def test_method_list_with_snippets(self, async_client: AsyncStructify) -> None:
- connector = await async_client.connectors.list_with_snippets(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
+ connector = await async_client.connectors.list_with_snippets()
assert_matches_type(ConnectorListWithSnippetsResponse, connector, path=["response"])
@parametrize
async def test_raw_response_list_with_snippets(self, async_client: AsyncStructify) -> None:
- response = await async_client.connectors.with_raw_response.list_with_snippets(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
+ response = await async_client.connectors.with_raw_response.list_with_snippets()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -2344,9 +2793,7 @@ async def test_raw_response_list_with_snippets(self, async_client: AsyncStructif
@parametrize
async def test_streaming_response_list_with_snippets(self, async_client: AsyncStructify) -> None:
- async with async_client.connectors.with_streaming_response.list_with_snippets(
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
+ async with async_client.connectors.with_streaming_response.list_with_snippets() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -2431,7 +2878,6 @@ async def test_streaming_response_search_tables(self, async_client: AsyncStructi
async def test_method_summaries(self, async_client: AsyncStructify) -> None:
connector = await async_client.connectors.summaries(
connector_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(ConnectorSummariesResponse, connector, path=["response"])
@@ -2439,7 +2885,6 @@ async def test_method_summaries(self, async_client: AsyncStructify) -> None:
async def test_raw_response_summaries(self, async_client: AsyncStructify) -> None:
response = await async_client.connectors.with_raw_response.summaries(
connector_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
@@ -2451,7 +2896,6 @@ async def test_raw_response_summaries(self, async_client: AsyncStructify) -> Non
async def test_streaming_response_summaries(self, async_client: AsyncStructify) -> None:
async with async_client.connectors.with_streaming_response.summaries(
connector_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"],
- team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -2553,3 +2997,61 @@ async def test_path_params_update_table(self, async_client: AsyncStructify) -> N
await async_client.connectors.with_raw_response.update_table(
table_id="",
)
+
+ @parametrize
+ async def test_method_upload_datahub_artifact(self, async_client: AsyncStructify) -> None:
+ connector = await async_client.connectors.upload_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ )
+ assert connector is None
+
+ @parametrize
+ async def test_raw_response_upload_datahub_artifact(self, async_client: AsyncStructify) -> None:
+ response = await async_client.connectors.with_raw_response.upload_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connector = await response.parse()
+ assert connector is None
+
+ @parametrize
+ async def test_streaming_response_upload_datahub_artifact(self, async_client: AsyncStructify) -> None:
+ async with async_client.connectors.with_streaming_response.upload_datahub_artifact(
+ kind="kind",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ connector = await response.parse()
+ assert connector is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_upload_datahub_artifact(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `connector_id` but received ''"):
+ await async_client.connectors.with_raw_response.upload_datahub_artifact(
+ kind="kind",
+ connector_id="",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `kind` but received ''"):
+ await async_client.connectors.with_raw_response.upload_datahub_artifact(
+ kind="",
+ connector_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ exploration_run_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ file=b"Example data",
+ )
diff --git a/tests/api_resources/test_dataframe.py b/tests/api_resources/test_dataframe.py
index 89b13a0f3..2b90d2fb4 100644
--- a/tests/api_resources/test_dataframe.py
+++ b/tests/api_resources/test_dataframe.py
@@ -115,9 +115,9 @@ def test_method_enhance_relationships(self, client: Structify) -> None:
mock_source_3 = Mock(id="entity-3", properties={"company_name": "Microsoft"})
# Target/connected entities
- mock_target_1 = Mock(id="target-1", properties={"employee_name": "Alex", "position": "CEO"}, job_ids=["job-1"])
- mock_target_2 = Mock(id="target-2", properties={"employee_name": "Alex", "position": "SWE"}, job_ids=["job-2"])
- mock_target_3 = Mock(id="target-3", properties={"employee_name": "Alex", "position": "PM"}, job_ids=["job-3"])
+ mock_target_1 = Mock(id="target-1", properties={"employee_name": "Alex", "position": "CEO"}, job_id="job-1")
+ mock_target_2 = Mock(id="target-2", properties={"employee_name": "Alex", "position": "SWE"}, job_id="job-2")
+ mock_target_3 = Mock(id="target-3", properties={"employee_name": "Alex", "position": "PM"}, job_id="job-3")
# Relationships connecting sources to targets
rel1 = Mock(from_id="entity-1", to_id="target-1")
diff --git a/tests/api_resources/test_documents.py b/tests/api_resources/test_documents.py
index 0882dfaf9..6562d8463 100644
--- a/tests/api_resources/test_documents.py
+++ b/tests/api_resources/test_documents.py
@@ -118,18 +118,18 @@ def test_streaming_response_download(self, client: Structify) -> None:
@parametrize
def test_method_upload(self, client: Structify) -> None:
document = client.documents.upload(
- content=b"raw file contents",
+ content=b"Example data",
file_type="Text",
- path=b"raw file contents",
+ path=b"Example data",
)
assert document is None
@parametrize
def test_method_upload_with_all_params(self, client: Structify) -> None:
document = client.documents.upload(
- content=b"raw file contents",
+ content=b"Example data",
file_type="Text",
- path=b"raw file contents",
+ path=b"Example data",
dataset="dataset",
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -138,9 +138,9 @@ def test_method_upload_with_all_params(self, client: Structify) -> None:
@parametrize
def test_raw_response_upload(self, client: Structify) -> None:
response = client.documents.with_raw_response.upload(
- content=b"raw file contents",
+ content=b"Example data",
file_type="Text",
- path=b"raw file contents",
+ path=b"Example data",
)
assert response.is_closed is True
@@ -151,9 +151,9 @@ def test_raw_response_upload(self, client: Structify) -> None:
@parametrize
def test_streaming_response_upload(self, client: Structify) -> None:
with client.documents.with_streaming_response.upload(
- content=b"raw file contents",
+ content=b"Example data",
file_type="Text",
- path=b"raw file contents",
+ path=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -267,18 +267,18 @@ async def test_streaming_response_download(self, async_client: AsyncStructify) -
@parametrize
async def test_method_upload(self, async_client: AsyncStructify) -> None:
document = await async_client.documents.upload(
- content=b"raw file contents",
+ content=b"Example data",
file_type="Text",
- path=b"raw file contents",
+ path=b"Example data",
)
assert document is None
@parametrize
async def test_method_upload_with_all_params(self, async_client: AsyncStructify) -> None:
document = await async_client.documents.upload(
- content=b"raw file contents",
+ content=b"Example data",
file_type="Text",
- path=b"raw file contents",
+ path=b"Example data",
dataset="dataset",
project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -287,9 +287,9 @@ async def test_method_upload_with_all_params(self, async_client: AsyncStructify)
@parametrize
async def test_raw_response_upload(self, async_client: AsyncStructify) -> None:
response = await async_client.documents.with_raw_response.upload(
- content=b"raw file contents",
+ content=b"Example data",
file_type="Text",
- path=b"raw file contents",
+ path=b"Example data",
)
assert response.is_closed is True
@@ -300,9 +300,9 @@ async def test_raw_response_upload(self, async_client: AsyncStructify) -> None:
@parametrize
async def test_streaming_response_upload(self, async_client: AsyncStructify) -> None:
async with async_client.documents.with_streaming_response.upload(
- content=b"raw file contents",
+ content=b"Example data",
file_type="Text",
- path=b"raw file contents",
+ path=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/api_resources/test_entities.py b/tests/api_resources/test_entities.py
index 0e408f166..0db32a661 100644
--- a/tests/api_resources/test_entities.py
+++ b/tests/api_resources/test_entities.py
@@ -819,7 +819,7 @@ def test_method_upload_parquet(self, client: Structify) -> None:
entity = client.entities.upload_parquet(
dataset="dataset",
table_name="table_name",
- content=b"raw file contents",
+ content=b"Example data",
)
assert entity is None
@@ -828,7 +828,7 @@ def test_method_upload_parquet_with_all_params(self, client: Structify) -> None:
entity = client.entities.upload_parquet(
dataset="dataset",
table_name="table_name",
- content=b"raw file contents",
+ content=b"Example data",
start_embedding=True,
)
assert entity is None
@@ -838,7 +838,7 @@ def test_raw_response_upload_parquet(self, client: Structify) -> None:
response = client.entities.with_raw_response.upload_parquet(
dataset="dataset",
table_name="table_name",
- content=b"raw file contents",
+ content=b"Example data",
)
assert response.is_closed is True
@@ -851,7 +851,7 @@ def test_streaming_response_upload_parquet(self, client: Structify) -> None:
with client.entities.with_streaming_response.upload_parquet(
dataset="dataset",
table_name="table_name",
- content=b"raw file contents",
+ content=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1773,7 +1773,7 @@ async def test_method_upload_parquet(self, async_client: AsyncStructify) -> None
entity = await async_client.entities.upload_parquet(
dataset="dataset",
table_name="table_name",
- content=b"raw file contents",
+ content=b"Example data",
)
assert entity is None
@@ -1782,7 +1782,7 @@ async def test_method_upload_parquet_with_all_params(self, async_client: AsyncSt
entity = await async_client.entities.upload_parquet(
dataset="dataset",
table_name="table_name",
- content=b"raw file contents",
+ content=b"Example data",
start_embedding=True,
)
assert entity is None
@@ -1792,7 +1792,7 @@ async def test_raw_response_upload_parquet(self, async_client: AsyncStructify) -
response = await async_client.entities.with_raw_response.upload_parquet(
dataset="dataset",
table_name="table_name",
- content=b"raw file contents",
+ content=b"Example data",
)
assert response.is_closed is True
@@ -1805,7 +1805,7 @@ async def test_streaming_response_upload_parquet(self, async_client: AsyncStruct
async with async_client.entities.with_streaming_response.upload_parquet(
dataset="dataset",
table_name="table_name",
- content=b"raw file contents",
+ content=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/api_resources/test_jobs.py b/tests/api_resources/test_jobs.py
index 5db5dbf6f..e3119fd98 100644
--- a/tests/api_resources/test_jobs.py
+++ b/tests/api_resources/test_jobs.py
@@ -10,12 +10,11 @@
from structify import Structify, AsyncStructify
from tests.utils import assert_matches_type
from structify.types import (
+ JobGetResponse,
JobListResponse,
JobCancelResponse,
JobStatusResponse,
GetJobEventsResponse,
- JobGetScrapersResponse,
- JobGetSourceEntitiesResponse,
)
from structify._utils import parse_datetime
from structify.pagination import SyncJobsList, AsyncJobsList
@@ -104,116 +103,78 @@ def test_path_params_cancel(self, client: Structify) -> None:
)
@parametrize
- def test_method_get_events(self, client: Structify) -> None:
- job = client.jobs.get_events(
+ def test_method_get(self, client: Structify) -> None:
+ job = client.jobs.get(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(GetJobEventsResponse, job, path=["response"])
+ assert_matches_type(JobGetResponse, job, path=["response"])
@parametrize
- def test_raw_response_get_events(self, client: Structify) -> None:
- response = client.jobs.with_raw_response.get_events(
+ def test_raw_response_get(self, client: Structify) -> None:
+ response = client.jobs.with_raw_response.get(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = response.parse()
- assert_matches_type(GetJobEventsResponse, job, path=["response"])
+ assert_matches_type(JobGetResponse, job, path=["response"])
@parametrize
- def test_streaming_response_get_events(self, client: Structify) -> None:
- with client.jobs.with_streaming_response.get_events(
+ def test_streaming_response_get(self, client: Structify) -> None:
+ with client.jobs.with_streaming_response.get(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = response.parse()
- assert_matches_type(GetJobEventsResponse, job, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_get_events(self, client: Structify) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"):
- client.jobs.with_raw_response.get_events(
- "",
- )
-
- @parametrize
- def test_method_get_scrapers(self, client: Structify) -> None:
- job = client.jobs.get_scrapers(
- "job_id",
- )
- assert_matches_type(JobGetScrapersResponse, job, path=["response"])
-
- @parametrize
- def test_raw_response_get_scrapers(self, client: Structify) -> None:
- response = client.jobs.with_raw_response.get_scrapers(
- "job_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- job = response.parse()
- assert_matches_type(JobGetScrapersResponse, job, path=["response"])
-
- @parametrize
- def test_streaming_response_get_scrapers(self, client: Structify) -> None:
- with client.jobs.with_streaming_response.get_scrapers(
- "job_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- job = response.parse()
- assert_matches_type(JobGetScrapersResponse, job, path=["response"])
+ assert_matches_type(JobGetResponse, job, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_get_scrapers(self, client: Structify) -> None:
+ def test_path_params_get(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"):
- client.jobs.with_raw_response.get_scrapers(
+ client.jobs.with_raw_response.get(
"",
)
@parametrize
- def test_method_get_source_entities(self, client: Structify) -> None:
- job = client.jobs.get_source_entities(
+ def test_method_get_events(self, client: Structify) -> None:
+ job = client.jobs.get_events(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(JobGetSourceEntitiesResponse, job, path=["response"])
+ assert_matches_type(GetJobEventsResponse, job, path=["response"])
@parametrize
- def test_raw_response_get_source_entities(self, client: Structify) -> None:
- response = client.jobs.with_raw_response.get_source_entities(
+ def test_raw_response_get_events(self, client: Structify) -> None:
+ response = client.jobs.with_raw_response.get_events(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = response.parse()
- assert_matches_type(JobGetSourceEntitiesResponse, job, path=["response"])
+ assert_matches_type(GetJobEventsResponse, job, path=["response"])
@parametrize
- def test_streaming_response_get_source_entities(self, client: Structify) -> None:
- with client.jobs.with_streaming_response.get_source_entities(
+ def test_streaming_response_get_events(self, client: Structify) -> None:
+ with client.jobs.with_streaming_response.get_events(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = response.parse()
- assert_matches_type(JobGetSourceEntitiesResponse, job, path=["response"])
+ assert_matches_type(GetJobEventsResponse, job, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_get_source_entities(self, client: Structify) -> None:
+ def test_path_params_get_events(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"):
- client.jobs.with_raw_response.get_source_entities(
+ client.jobs.with_raw_response.get_events(
"",
)
@@ -360,116 +321,78 @@ async def test_path_params_cancel(self, async_client: AsyncStructify) -> None:
)
@parametrize
- async def test_method_get_events(self, async_client: AsyncStructify) -> None:
- job = await async_client.jobs.get_events(
+ async def test_method_get(self, async_client: AsyncStructify) -> None:
+ job = await async_client.jobs.get(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(GetJobEventsResponse, job, path=["response"])
+ assert_matches_type(JobGetResponse, job, path=["response"])
@parametrize
- async def test_raw_response_get_events(self, async_client: AsyncStructify) -> None:
- response = await async_client.jobs.with_raw_response.get_events(
+ async def test_raw_response_get(self, async_client: AsyncStructify) -> None:
+ response = await async_client.jobs.with_raw_response.get(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = await response.parse()
- assert_matches_type(GetJobEventsResponse, job, path=["response"])
+ assert_matches_type(JobGetResponse, job, path=["response"])
@parametrize
- async def test_streaming_response_get_events(self, async_client: AsyncStructify) -> None:
- async with async_client.jobs.with_streaming_response.get_events(
+ async def test_streaming_response_get(self, async_client: AsyncStructify) -> None:
+ async with async_client.jobs.with_streaming_response.get(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = await response.parse()
- assert_matches_type(GetJobEventsResponse, job, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_get_events(self, async_client: AsyncStructify) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"):
- await async_client.jobs.with_raw_response.get_events(
- "",
- )
-
- @parametrize
- async def test_method_get_scrapers(self, async_client: AsyncStructify) -> None:
- job = await async_client.jobs.get_scrapers(
- "job_id",
- )
- assert_matches_type(JobGetScrapersResponse, job, path=["response"])
-
- @parametrize
- async def test_raw_response_get_scrapers(self, async_client: AsyncStructify) -> None:
- response = await async_client.jobs.with_raw_response.get_scrapers(
- "job_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- job = await response.parse()
- assert_matches_type(JobGetScrapersResponse, job, path=["response"])
-
- @parametrize
- async def test_streaming_response_get_scrapers(self, async_client: AsyncStructify) -> None:
- async with async_client.jobs.with_streaming_response.get_scrapers(
- "job_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- job = await response.parse()
- assert_matches_type(JobGetScrapersResponse, job, path=["response"])
+ assert_matches_type(JobGetResponse, job, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_get_scrapers(self, async_client: AsyncStructify) -> None:
+ async def test_path_params_get(self, async_client: AsyncStructify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"):
- await async_client.jobs.with_raw_response.get_scrapers(
+ await async_client.jobs.with_raw_response.get(
"",
)
@parametrize
- async def test_method_get_source_entities(self, async_client: AsyncStructify) -> None:
- job = await async_client.jobs.get_source_entities(
+ async def test_method_get_events(self, async_client: AsyncStructify) -> None:
+ job = await async_client.jobs.get_events(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(JobGetSourceEntitiesResponse, job, path=["response"])
+ assert_matches_type(GetJobEventsResponse, job, path=["response"])
@parametrize
- async def test_raw_response_get_source_entities(self, async_client: AsyncStructify) -> None:
- response = await async_client.jobs.with_raw_response.get_source_entities(
+ async def test_raw_response_get_events(self, async_client: AsyncStructify) -> None:
+ response = await async_client.jobs.with_raw_response.get_events(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = await response.parse()
- assert_matches_type(JobGetSourceEntitiesResponse, job, path=["response"])
+ assert_matches_type(GetJobEventsResponse, job, path=["response"])
@parametrize
- async def test_streaming_response_get_source_entities(self, async_client: AsyncStructify) -> None:
- async with async_client.jobs.with_streaming_response.get_source_entities(
+ async def test_streaming_response_get_events(self, async_client: AsyncStructify) -> None:
+ async with async_client.jobs.with_streaming_response.get_events(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
job = await response.parse()
- assert_matches_type(JobGetSourceEntitiesResponse, job, path=["response"])
+ assert_matches_type(GetJobEventsResponse, job, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_get_source_entities(self, async_client: AsyncStructify) -> None:
+ async def test_path_params_get_events(self, async_client: AsyncStructify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `job_id` but received ''"):
- await async_client.jobs.with_raw_response.get_source_entities(
+ await async_client.jobs.with_raw_response.get_events(
"",
)
diff --git a/tests/api_resources/test_sandbox.py b/tests/api_resources/test_sandbox.py
index a278863de..a485ed22b 100644
--- a/tests/api_resources/test_sandbox.py
+++ b/tests/api_resources/test_sandbox.py
@@ -9,7 +9,11 @@
from structify import Structify, AsyncStructify
from tests.utils import assert_matches_type
-from structify.types import Sandbox, SandboxListResponse
+from structify.types import (
+ Sandbox,
+ SandboxListResponse,
+ SandboxGetMetricsResponse,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -101,6 +105,44 @@ def test_path_params_get(self, client: Structify) -> None:
chat_id="",
)
+ @parametrize
+ def test_method_get_metrics(self, client: Structify) -> None:
+ sandbox = client.sandbox.get_metrics(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(SandboxGetMetricsResponse, sandbox, path=["response"])
+
+ @parametrize
+ def test_raw_response_get_metrics(self, client: Structify) -> None:
+ response = client.sandbox.with_raw_response.get_metrics(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ sandbox = response.parse()
+ assert_matches_type(SandboxGetMetricsResponse, sandbox, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get_metrics(self, client: Structify) -> None:
+ with client.sandbox.with_streaming_response.get_metrics(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ sandbox = response.parse()
+ assert_matches_type(SandboxGetMetricsResponse, sandbox, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get_metrics(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `sandbox_id` but received ''"):
+ client.sandbox.with_raw_response.get_metrics(
+ "",
+ )
+
@parametrize
def test_method_update_status(self, client: Structify) -> None:
sandbox = client.sandbox.update_status(
@@ -233,6 +275,44 @@ async def test_path_params_get(self, async_client: AsyncStructify) -> None:
chat_id="",
)
+ @parametrize
+ async def test_method_get_metrics(self, async_client: AsyncStructify) -> None:
+ sandbox = await async_client.sandbox.get_metrics(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(SandboxGetMetricsResponse, sandbox, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get_metrics(self, async_client: AsyncStructify) -> None:
+ response = await async_client.sandbox.with_raw_response.get_metrics(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ sandbox = await response.parse()
+ assert_matches_type(SandboxGetMetricsResponse, sandbox, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get_metrics(self, async_client: AsyncStructify) -> None:
+ async with async_client.sandbox.with_streaming_response.get_metrics(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ sandbox = await response.parse()
+ assert_matches_type(SandboxGetMetricsResponse, sandbox, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get_metrics(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `sandbox_id` but received ''"):
+ await async_client.sandbox.with_raw_response.get_metrics(
+ "",
+ )
+
@parametrize
async def test_method_update_status(self, async_client: AsyncStructify) -> None:
sandbox = await async_client.sandbox.update_status(
diff --git a/tests/api_resources/test_sessions.py b/tests/api_resources/test_sessions.py
index 97cdd8f69..f960c82df 100644
--- a/tests/api_resources/test_sessions.py
+++ b/tests/api_resources/test_sessions.py
@@ -18,6 +18,7 @@
FinalizeDagResponse,
GetNodeLogsResponse,
WorkflowSessionNode,
+ TriggerReviewResponse,
SessionKillJobsResponse,
SessionGetEventsResponse,
SessionEditNodeOutputResponse,
@@ -82,7 +83,6 @@ def test_path_params_confirm_node(self, client: Structify) -> None:
def test_method_create_session(self, client: Structify) -> None:
session = client.sessions.create_session(
chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- git_commit="git_commit",
)
assert_matches_type(WorkflowSession, session, path=["response"])
@@ -90,7 +90,7 @@ def test_method_create_session(self, client: Structify) -> None:
def test_method_create_session_with_all_params(self, client: Structify) -> None:
session = client.sessions.create_session(
chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- git_commit="git_commit",
+ parent_chat_message_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
workflow_schedule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(WorkflowSession, session, path=["response"])
@@ -99,7 +99,6 @@ def test_method_create_session_with_all_params(self, client: Structify) -> None:
def test_raw_response_create_session(self, client: Structify) -> None:
response = client.sessions.with_raw_response.create_session(
chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- git_commit="git_commit",
)
assert response.is_closed is True
@@ -111,7 +110,6 @@ def test_raw_response_create_session(self, client: Structify) -> None:
def test_streaming_response_create_session(self, client: Structify) -> None:
with client.sessions.with_streaming_response.create_session(
chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- git_commit="git_commit",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -743,6 +741,44 @@ def test_path_params_request_confirmation(self, client: Structify) -> None:
row_count=0,
)
+ @parametrize
+ def test_method_trigger_review(self, client: Structify) -> None:
+ session = client.sessions.trigger_review(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(TriggerReviewResponse, session, path=["response"])
+
+ @parametrize
+ def test_raw_response_trigger_review(self, client: Structify) -> None:
+ response = client.sessions.with_raw_response.trigger_review(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert_matches_type(TriggerReviewResponse, session, path=["response"])
+
+ @parametrize
+ def test_streaming_response_trigger_review(self, client: Structify) -> None:
+ with client.sessions.with_streaming_response.trigger_review(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert_matches_type(TriggerReviewResponse, session, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_trigger_review(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
+ client.sessions.with_raw_response.trigger_review(
+ "",
+ )
+
@parametrize
def test_method_update_node(self, client: Structify) -> None:
session = client.sessions.update_node(
@@ -858,7 +894,7 @@ def test_path_params_update_node_progress(self, client: Structify) -> None:
)
@parametrize
- def test_method_upload_dashboard_layout(self, client: Structify) -> None:
+ def test_method_upload_dashboard_layout_overload_1(self, client: Structify) -> None:
session = client.sessions.upload_dashboard_layout(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
layout={
@@ -878,7 +914,7 @@ def test_method_upload_dashboard_layout(self, client: Structify) -> None:
assert_matches_type(WorkflowSession, session, path=["response"])
@parametrize
- def test_method_upload_dashboard_layout_with_all_params(self, client: Structify) -> None:
+ def test_method_upload_dashboard_layout_with_all_params_overload_1(self, client: Structify) -> None:
session = client.sessions.upload_dashboard_layout(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
layout={
@@ -919,7 +955,7 @@ def test_method_upload_dashboard_layout_with_all_params(self, client: Structify)
assert_matches_type(WorkflowSession, session, path=["response"])
@parametrize
- def test_raw_response_upload_dashboard_layout(self, client: Structify) -> None:
+ def test_raw_response_upload_dashboard_layout_overload_1(self, client: Structify) -> None:
response = client.sessions.with_raw_response.upload_dashboard_layout(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
layout={
@@ -943,7 +979,7 @@ def test_raw_response_upload_dashboard_layout(self, client: Structify) -> None:
assert_matches_type(WorkflowSession, session, path=["response"])
@parametrize
- def test_streaming_response_upload_dashboard_layout(self, client: Structify) -> None:
+ def test_streaming_response_upload_dashboard_layout_overload_1(self, client: Structify) -> None:
with client.sessions.with_streaming_response.upload_dashboard_layout(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
layout={
@@ -969,7 +1005,7 @@ def test_streaming_response_upload_dashboard_layout(self, client: Structify) ->
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_upload_dashboard_layout(self, client: Structify) -> None:
+ def test_path_params_upload_dashboard_layout_overload_1(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
client.sessions.with_raw_response.upload_dashboard_layout(
session_id="",
@@ -988,11 +1024,177 @@ def test_path_params_upload_dashboard_layout(self, client: Structify) -> None:
},
)
+ @parametrize
+ def test_method_upload_dashboard_layout_overload_2(self, client: Structify) -> None:
+ session = client.sessions.upload_dashboard_layout(
+ session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ dashboard_specs=[
+ {
+ "file_name": "file_name",
+ "spec": {
+ "dataset": "dataset",
+ "description": "description",
+ "figures": [
+ {
+ "id": "id",
+ "figure": {
+ "expression": "expression",
+ "kind": "js",
+ },
+ }
+ ],
+ "params": {
+ "foo": {
+ "type": "string",
+ "value": "value",
+ }
+ },
+ "queries": [
+ {
+ "id": "id",
+ "sql": "sql",
+ }
+ ],
+ "title": "title",
+ "version": "version",
+ },
+ }
+ ],
+ )
+ assert_matches_type(WorkflowSession, session, path=["response"])
+
+ @parametrize
+ def test_raw_response_upload_dashboard_layout_overload_2(self, client: Structify) -> None:
+ response = client.sessions.with_raw_response.upload_dashboard_layout(
+ session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ dashboard_specs=[
+ {
+ "file_name": "file_name",
+ "spec": {
+ "dataset": "dataset",
+ "description": "description",
+ "figures": [
+ {
+ "id": "id",
+ "figure": {
+ "expression": "expression",
+ "kind": "js",
+ },
+ }
+ ],
+ "params": {
+ "foo": {
+ "type": "string",
+ "value": "value",
+ }
+ },
+ "queries": [
+ {
+ "id": "id",
+ "sql": "sql",
+ }
+ ],
+ "title": "title",
+ "version": "version",
+ },
+ }
+ ],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert_matches_type(WorkflowSession, session, path=["response"])
+
+ @parametrize
+ def test_streaming_response_upload_dashboard_layout_overload_2(self, client: Structify) -> None:
+ with client.sessions.with_streaming_response.upload_dashboard_layout(
+ session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ dashboard_specs=[
+ {
+ "file_name": "file_name",
+ "spec": {
+ "dataset": "dataset",
+ "description": "description",
+ "figures": [
+ {
+ "id": "id",
+ "figure": {
+ "expression": "expression",
+ "kind": "js",
+ },
+ }
+ ],
+ "params": {
+ "foo": {
+ "type": "string",
+ "value": "value",
+ }
+ },
+ "queries": [
+ {
+ "id": "id",
+ "sql": "sql",
+ }
+ ],
+ "title": "title",
+ "version": "version",
+ },
+ }
+ ],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert_matches_type(WorkflowSession, session, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_upload_dashboard_layout_overload_2(self, client: Structify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
+ client.sessions.with_raw_response.upload_dashboard_layout(
+ session_id="",
+ dashboard_specs=[
+ {
+ "file_name": "file_name",
+ "spec": {
+ "dataset": "dataset",
+ "description": "description",
+ "figures": [
+ {
+ "id": "id",
+ "figure": {
+ "expression": "expression",
+ "kind": "js",
+ },
+ }
+ ],
+ "params": {
+ "foo": {
+ "type": "string",
+ "value": "value",
+ }
+ },
+ "queries": [
+ {
+ "id": "id",
+ "sql": "sql",
+ }
+ ],
+ "title": "title",
+ "version": "version",
+ },
+ }
+ ],
+ )
+
@parametrize
def test_method_upload_node_output_data(self, client: Structify) -> None:
session = client.sessions.upload_node_output_data(
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- content=b"raw file contents",
+ content=b"Example data",
)
assert_matches_type(WorkflowSessionNode, session, path=["response"])
@@ -1000,7 +1202,13 @@ def test_method_upload_node_output_data(self, client: Structify) -> None:
def test_method_upload_node_output_data_with_all_params(self, client: Structify) -> None:
session = client.sessions.upload_node_output_data(
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- content=b"raw file contents",
+ content=b"Example data",
+ cache_final_rows=0,
+ cache_final_size_bytes=0,
+ cache_max_bytes=0,
+ cache_original_rows=0,
+ cache_original_size_bytes=0,
+ cache_truncated=True,
output_schema="output_schema",
)
assert_matches_type(WorkflowSessionNode, session, path=["response"])
@@ -1009,7 +1217,7 @@ def test_method_upload_node_output_data_with_all_params(self, client: Structify)
def test_raw_response_upload_node_output_data(self, client: Structify) -> None:
response = client.sessions.with_raw_response.upload_node_output_data(
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- content=b"raw file contents",
+ content=b"Example data",
)
assert response.is_closed is True
@@ -1021,7 +1229,7 @@ def test_raw_response_upload_node_output_data(self, client: Structify) -> None:
def test_streaming_response_upload_node_output_data(self, client: Structify) -> None:
with client.sessions.with_streaming_response.upload_node_output_data(
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- content=b"raw file contents",
+ content=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1036,7 +1244,7 @@ def test_path_params_upload_node_output_data(self, client: Structify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `node_id` but received ''"):
client.sessions.with_raw_response.upload_node_output_data(
node_id="",
- content=b"raw file contents",
+ content=b"Example data",
)
@parametrize
@@ -1133,7 +1341,6 @@ async def test_path_params_confirm_node(self, async_client: AsyncStructify) -> N
async def test_method_create_session(self, async_client: AsyncStructify) -> None:
session = await async_client.sessions.create_session(
chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- git_commit="git_commit",
)
assert_matches_type(WorkflowSession, session, path=["response"])
@@ -1141,7 +1348,7 @@ async def test_method_create_session(self, async_client: AsyncStructify) -> None
async def test_method_create_session_with_all_params(self, async_client: AsyncStructify) -> None:
session = await async_client.sessions.create_session(
chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- git_commit="git_commit",
+ parent_chat_message_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
workflow_schedule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(WorkflowSession, session, path=["response"])
@@ -1150,7 +1357,6 @@ async def test_method_create_session_with_all_params(self, async_client: AsyncSt
async def test_raw_response_create_session(self, async_client: AsyncStructify) -> None:
response = await async_client.sessions.with_raw_response.create_session(
chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- git_commit="git_commit",
)
assert response.is_closed is True
@@ -1162,7 +1368,6 @@ async def test_raw_response_create_session(self, async_client: AsyncStructify) -
async def test_streaming_response_create_session(self, async_client: AsyncStructify) -> None:
async with async_client.sessions.with_streaming_response.create_session(
chat_session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- git_commit="git_commit",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1798,6 +2003,44 @@ async def test_path_params_request_confirmation(self, async_client: AsyncStructi
row_count=0,
)
+ @parametrize
+ async def test_method_trigger_review(self, async_client: AsyncStructify) -> None:
+ session = await async_client.sessions.trigger_review(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(TriggerReviewResponse, session, path=["response"])
+
+ @parametrize
+ async def test_raw_response_trigger_review(self, async_client: AsyncStructify) -> None:
+ response = await async_client.sessions.with_raw_response.trigger_review(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert_matches_type(TriggerReviewResponse, session, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_trigger_review(self, async_client: AsyncStructify) -> None:
+ async with async_client.sessions.with_streaming_response.trigger_review(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert_matches_type(TriggerReviewResponse, session, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_trigger_review(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
+ await async_client.sessions.with_raw_response.trigger_review(
+ "",
+ )
+
@parametrize
async def test_method_update_node(self, async_client: AsyncStructify) -> None:
session = await async_client.sessions.update_node(
@@ -1913,7 +2156,7 @@ async def test_path_params_update_node_progress(self, async_client: AsyncStructi
)
@parametrize
- async def test_method_upload_dashboard_layout(self, async_client: AsyncStructify) -> None:
+ async def test_method_upload_dashboard_layout_overload_1(self, async_client: AsyncStructify) -> None:
session = await async_client.sessions.upload_dashboard_layout(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
layout={
@@ -1933,7 +2176,9 @@ async def test_method_upload_dashboard_layout(self, async_client: AsyncStructify
assert_matches_type(WorkflowSession, session, path=["response"])
@parametrize
- async def test_method_upload_dashboard_layout_with_all_params(self, async_client: AsyncStructify) -> None:
+ async def test_method_upload_dashboard_layout_with_all_params_overload_1(
+ self, async_client: AsyncStructify
+ ) -> None:
session = await async_client.sessions.upload_dashboard_layout(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
layout={
@@ -1974,7 +2219,7 @@ async def test_method_upload_dashboard_layout_with_all_params(self, async_client
assert_matches_type(WorkflowSession, session, path=["response"])
@parametrize
- async def test_raw_response_upload_dashboard_layout(self, async_client: AsyncStructify) -> None:
+ async def test_raw_response_upload_dashboard_layout_overload_1(self, async_client: AsyncStructify) -> None:
response = await async_client.sessions.with_raw_response.upload_dashboard_layout(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
layout={
@@ -1998,7 +2243,7 @@ async def test_raw_response_upload_dashboard_layout(self, async_client: AsyncStr
assert_matches_type(WorkflowSession, session, path=["response"])
@parametrize
- async def test_streaming_response_upload_dashboard_layout(self, async_client: AsyncStructify) -> None:
+ async def test_streaming_response_upload_dashboard_layout_overload_1(self, async_client: AsyncStructify) -> None:
async with async_client.sessions.with_streaming_response.upload_dashboard_layout(
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
layout={
@@ -2024,7 +2269,7 @@ async def test_streaming_response_upload_dashboard_layout(self, async_client: As
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_upload_dashboard_layout(self, async_client: AsyncStructify) -> None:
+ async def test_path_params_upload_dashboard_layout_overload_1(self, async_client: AsyncStructify) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
await async_client.sessions.with_raw_response.upload_dashboard_layout(
session_id="",
@@ -2043,11 +2288,177 @@ async def test_path_params_upload_dashboard_layout(self, async_client: AsyncStru
},
)
+ @parametrize
+ async def test_method_upload_dashboard_layout_overload_2(self, async_client: AsyncStructify) -> None:
+ session = await async_client.sessions.upload_dashboard_layout(
+ session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ dashboard_specs=[
+ {
+ "file_name": "file_name",
+ "spec": {
+ "dataset": "dataset",
+ "description": "description",
+ "figures": [
+ {
+ "id": "id",
+ "figure": {
+ "expression": "expression",
+ "kind": "js",
+ },
+ }
+ ],
+ "params": {
+ "foo": {
+ "type": "string",
+ "value": "value",
+ }
+ },
+ "queries": [
+ {
+ "id": "id",
+ "sql": "sql",
+ }
+ ],
+ "title": "title",
+ "version": "version",
+ },
+ }
+ ],
+ )
+ assert_matches_type(WorkflowSession, session, path=["response"])
+
+ @parametrize
+ async def test_raw_response_upload_dashboard_layout_overload_2(self, async_client: AsyncStructify) -> None:
+ response = await async_client.sessions.with_raw_response.upload_dashboard_layout(
+ session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ dashboard_specs=[
+ {
+ "file_name": "file_name",
+ "spec": {
+ "dataset": "dataset",
+ "description": "description",
+ "figures": [
+ {
+ "id": "id",
+ "figure": {
+ "expression": "expression",
+ "kind": "js",
+ },
+ }
+ ],
+ "params": {
+ "foo": {
+ "type": "string",
+ "value": "value",
+ }
+ },
+ "queries": [
+ {
+ "id": "id",
+ "sql": "sql",
+ }
+ ],
+ "title": "title",
+ "version": "version",
+ },
+ }
+ ],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert_matches_type(WorkflowSession, session, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_upload_dashboard_layout_overload_2(self, async_client: AsyncStructify) -> None:
+ async with async_client.sessions.with_streaming_response.upload_dashboard_layout(
+ session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ dashboard_specs=[
+ {
+ "file_name": "file_name",
+ "spec": {
+ "dataset": "dataset",
+ "description": "description",
+ "figures": [
+ {
+ "id": "id",
+ "figure": {
+ "expression": "expression",
+ "kind": "js",
+ },
+ }
+ ],
+ "params": {
+ "foo": {
+ "type": "string",
+ "value": "value",
+ }
+ },
+ "queries": [
+ {
+ "id": "id",
+ "sql": "sql",
+ }
+ ],
+ "title": "title",
+ "version": "version",
+ },
+ }
+ ],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert_matches_type(WorkflowSession, session, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_upload_dashboard_layout_overload_2(self, async_client: AsyncStructify) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
+ await async_client.sessions.with_raw_response.upload_dashboard_layout(
+ session_id="",
+ dashboard_specs=[
+ {
+ "file_name": "file_name",
+ "spec": {
+ "dataset": "dataset",
+ "description": "description",
+ "figures": [
+ {
+ "id": "id",
+ "figure": {
+ "expression": "expression",
+ "kind": "js",
+ },
+ }
+ ],
+ "params": {
+ "foo": {
+ "type": "string",
+ "value": "value",
+ }
+ },
+ "queries": [
+ {
+ "id": "id",
+ "sql": "sql",
+ }
+ ],
+ "title": "title",
+ "version": "version",
+ },
+ }
+ ],
+ )
+
@parametrize
async def test_method_upload_node_output_data(self, async_client: AsyncStructify) -> None:
session = await async_client.sessions.upload_node_output_data(
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- content=b"raw file contents",
+ content=b"Example data",
)
assert_matches_type(WorkflowSessionNode, session, path=["response"])
@@ -2055,7 +2466,13 @@ async def test_method_upload_node_output_data(self, async_client: AsyncStructify
async def test_method_upload_node_output_data_with_all_params(self, async_client: AsyncStructify) -> None:
session = await async_client.sessions.upload_node_output_data(
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- content=b"raw file contents",
+ content=b"Example data",
+ cache_final_rows=0,
+ cache_final_size_bytes=0,
+ cache_max_bytes=0,
+ cache_original_rows=0,
+ cache_original_size_bytes=0,
+ cache_truncated=True,
output_schema="output_schema",
)
assert_matches_type(WorkflowSessionNode, session, path=["response"])
@@ -2064,7 +2481,7 @@ async def test_method_upload_node_output_data_with_all_params(self, async_client
async def test_raw_response_upload_node_output_data(self, async_client: AsyncStructify) -> None:
response = await async_client.sessions.with_raw_response.upload_node_output_data(
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- content=b"raw file contents",
+ content=b"Example data",
)
assert response.is_closed is True
@@ -2076,7 +2493,7 @@ async def test_raw_response_upload_node_output_data(self, async_client: AsyncStr
async def test_streaming_response_upload_node_output_data(self, async_client: AsyncStructify) -> None:
async with async_client.sessions.with_streaming_response.upload_node_output_data(
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- content=b"raw file contents",
+ content=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -2091,7 +2508,7 @@ async def test_path_params_upload_node_output_data(self, async_client: AsyncStru
with pytest.raises(ValueError, match=r"Expected a non-empty value for `node_id` but received ''"):
await async_client.sessions.with_raw_response.upload_node_output_data(
node_id="",
- content=b"raw file contents",
+ content=b"Example data",
)
@parametrize
diff --git a/tests/api_resources/test_structure.py b/tests/api_resources/test_structure.py
index a87649bcc..1d33cc3e6 100644
--- a/tests/api_resources/test_structure.py
+++ b/tests/api_resources/test_structure.py
@@ -250,9 +250,9 @@ def test_method_pdf_with_all_params(self, client: Structify) -> None:
dataset="dataset",
path="path",
instructions="instructions",
- mode="Single",
model="model",
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ pages=[0],
)
assert_matches_type(StructurePdfResponse, structure, path=["response"])
@@ -586,9 +586,9 @@ async def test_method_pdf_with_all_params(self, async_client: AsyncStructify) ->
dataset="dataset",
path="path",
instructions="instructions",
- mode="Single",
model="model",
node_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ pages=[0],
)
assert_matches_type(StructurePdfResponse, structure, path=["response"])
diff --git a/tests/api_resources/test_teams.py b/tests/api_resources/test_teams.py
index af5d5dca3..38bc0ce81 100644
--- a/tests/api_resources/test_teams.py
+++ b/tests/api_resources/test_teams.py
@@ -83,9 +83,13 @@ def test_method_update(self, client: Structify) -> None:
def test_method_update_with_all_params(self, client: Structify) -> None:
team = client.teams.update(
team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ daytona_credentials={
+ "api_key": "api_key",
+ "api_url": "api_url",
+ },
description="description",
name="name",
- pipedream_project_id="pipedream_project_id",
+ sandbox_provider="modal",
slack_bot_token="slack_bot_token",
slack_team_icon="slack_team_icon",
slack_team_id="slack_team_id",
@@ -93,6 +97,10 @@ def test_method_update_with_all_params(self, client: Structify) -> None:
teams_app_id="teams_app_id",
teams_app_password="teams_app_password",
teams_tenant_id="teams_tenant_id",
+ workflow_bucket={
+ "bucket_url": "bucket_url",
+ "gcp_credentials_json": "gcp_credentials_json",
+ },
)
assert_matches_type(UpdateTeamResponse, team, path=["response"])
@@ -730,9 +738,13 @@ async def test_method_update(self, async_client: AsyncStructify) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncStructify) -> None:
team = await async_client.teams.update(
team_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ daytona_credentials={
+ "api_key": "api_key",
+ "api_url": "api_url",
+ },
description="description",
name="name",
- pipedream_project_id="pipedream_project_id",
+ sandbox_provider="modal",
slack_bot_token="slack_bot_token",
slack_team_icon="slack_team_icon",
slack_team_id="slack_team_id",
@@ -740,6 +752,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncStructify)
teams_app_id="teams_app_id",
teams_app_password="teams_app_password",
teams_tenant_id="teams_tenant_id",
+ workflow_bucket={
+ "bucket_url": "bucket_url",
+ "gcp_credentials_json": "gcp_credentials_json",
+ },
)
assert_matches_type(UpdateTeamResponse, team, path=["response"])
diff --git a/tests/api_resources/test_user.py b/tests/api_resources/test_user.py
index 17f025ce9..063cd0063 100644
--- a/tests/api_resources/test_user.py
+++ b/tests/api_resources/test_user.py
@@ -15,6 +15,8 @@
RefreshSessionResponse,
SurveySubmissionResponse,
UserTransactionsResponse,
+ GetOnboardingAnswersResponse,
+ SaveOnboardingAnswersResponse,
)
from structify.types.admin import User
@@ -45,10 +47,10 @@ def test_method_update_with_all_params(self, client: Structify) -> None:
"feature_flags": ["functional_test"],
"feature_overrides": {},
"full_name": "full_name",
- "is_developer": True,
"job_title": "job_title",
"last_selected_team_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
"linkedin_url": "linkedin_url",
+ "notify_for_interaction": True,
"onboarding_session_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
"permissions": ["labeler"],
"slack_user_id": "slack_user_id",
@@ -117,6 +119,31 @@ def test_streaming_response_enrich(self, client: Structify) -> None:
assert cast(Any, response.is_closed) is True
+ @parametrize
+ def test_method_get_onboarding_answers(self, client: Structify) -> None:
+ user = client.user.get_onboarding_answers()
+ assert_matches_type(GetOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ def test_raw_response_get_onboarding_answers(self, client: Structify) -> None:
+ response = client.user.with_raw_response.get_onboarding_answers()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ user = response.parse()
+ assert_matches_type(GetOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get_onboarding_answers(self, client: Structify) -> None:
+ with client.user.with_streaming_response.get_onboarding_answers() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ user = response.parse()
+ assert_matches_type(GetOnboardingAnswersResponse, user, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@parametrize
def test_method_info(self, client: Structify) -> None:
user = client.user.info()
@@ -176,6 +203,52 @@ def test_streaming_response_refresh(self, client: Structify) -> None:
assert cast(Any, response.is_closed) is True
+ @parametrize
+ def test_method_save_onboarding_answers(self, client: Structify) -> None:
+ user = client.user.save_onboarding_answers(
+ answers={},
+ )
+ assert_matches_type(SaveOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ def test_method_save_onboarding_answers_with_all_params(self, client: Structify) -> None:
+ user = client.user.save_onboarding_answers(
+ answers={
+ "company_name": "company_name",
+ "connected_connector_ids": ["string"],
+ "full_name": "full_name",
+ "primary_goal": "primary_goal",
+ "recommended_template_id": "recommended_template_id",
+ "role": "role",
+ "systems_to_connect": ["string"],
+ },
+ )
+ assert_matches_type(SaveOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ def test_raw_response_save_onboarding_answers(self, client: Structify) -> None:
+ response = client.user.with_raw_response.save_onboarding_answers(
+ answers={},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ user = response.parse()
+ assert_matches_type(SaveOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ def test_streaming_response_save_onboarding_answers(self, client: Structify) -> None:
+ with client.user.with_streaming_response.save_onboarding_answers(
+ answers={},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ user = response.parse()
+ assert_matches_type(SaveOnboardingAnswersResponse, user, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@parametrize
def test_method_survey_submit(self, client: Structify) -> None:
user = client.user.survey_submit(
@@ -291,10 +364,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncStructify)
"feature_flags": ["functional_test"],
"feature_overrides": {},
"full_name": "full_name",
- "is_developer": True,
"job_title": "job_title",
"last_selected_team_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
"linkedin_url": "linkedin_url",
+ "notify_for_interaction": True,
"onboarding_session_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
"permissions": ["labeler"],
"slack_user_id": "slack_user_id",
@@ -363,6 +436,31 @@ async def test_streaming_response_enrich(self, async_client: AsyncStructify) ->
assert cast(Any, response.is_closed) is True
+ @parametrize
+ async def test_method_get_onboarding_answers(self, async_client: AsyncStructify) -> None:
+ user = await async_client.user.get_onboarding_answers()
+ assert_matches_type(GetOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get_onboarding_answers(self, async_client: AsyncStructify) -> None:
+ response = await async_client.user.with_raw_response.get_onboarding_answers()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ user = await response.parse()
+ assert_matches_type(GetOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get_onboarding_answers(self, async_client: AsyncStructify) -> None:
+ async with async_client.user.with_streaming_response.get_onboarding_answers() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ user = await response.parse()
+ assert_matches_type(GetOnboardingAnswersResponse, user, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@parametrize
async def test_method_info(self, async_client: AsyncStructify) -> None:
user = await async_client.user.info()
@@ -422,6 +520,52 @@ async def test_streaming_response_refresh(self, async_client: AsyncStructify) ->
assert cast(Any, response.is_closed) is True
+ @parametrize
+ async def test_method_save_onboarding_answers(self, async_client: AsyncStructify) -> None:
+ user = await async_client.user.save_onboarding_answers(
+ answers={},
+ )
+ assert_matches_type(SaveOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ async def test_method_save_onboarding_answers_with_all_params(self, async_client: AsyncStructify) -> None:
+ user = await async_client.user.save_onboarding_answers(
+ answers={
+ "company_name": "company_name",
+ "connected_connector_ids": ["string"],
+ "full_name": "full_name",
+ "primary_goal": "primary_goal",
+ "recommended_template_id": "recommended_template_id",
+ "role": "role",
+ "systems_to_connect": ["string"],
+ },
+ )
+ assert_matches_type(SaveOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ async def test_raw_response_save_onboarding_answers(self, async_client: AsyncStructify) -> None:
+ response = await async_client.user.with_raw_response.save_onboarding_answers(
+ answers={},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ user = await response.parse()
+ assert_matches_type(SaveOnboardingAnswersResponse, user, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_save_onboarding_answers(self, async_client: AsyncStructify) -> None:
+ async with async_client.user.with_streaming_response.save_onboarding_answers(
+ answers={},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ user = await response.parse()
+ assert_matches_type(SaveOnboardingAnswersResponse, user, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
@parametrize
async def test_method_survey_submit(self, async_client: AsyncStructify) -> None:
user = await async_client.user.survey_submit(
diff --git a/tests/test_client.py b/tests/test_client.py
index 7adaaa6c4..378c73e3e 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -966,6 +966,14 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None:
# Test that the proxy environment variables are set correctly
monkeypatch.setenv("HTTPS_PROXY", "https://example.org")
+ # Delete in case our environment has any proxy env vars set
+ monkeypatch.delenv("HTTP_PROXY", raising=False)
+ monkeypatch.delenv("ALL_PROXY", raising=False)
+ monkeypatch.delenv("NO_PROXY", raising=False)
+ monkeypatch.delenv("http_proxy", raising=False)
+ monkeypatch.delenv("https_proxy", raising=False)
+ monkeypatch.delenv("all_proxy", raising=False)
+ monkeypatch.delenv("no_proxy", raising=False)
client = DefaultHttpxClient()
@@ -1891,6 +1899,14 @@ async def test_get_platform(self) -> None:
async def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None:
# Test that the proxy environment variables are set correctly
monkeypatch.setenv("HTTPS_PROXY", "https://example.org")
+ # Delete in case our environment has any proxy env vars set
+ monkeypatch.delenv("HTTP_PROXY", raising=False)
+ monkeypatch.delenv("ALL_PROXY", raising=False)
+ monkeypatch.delenv("NO_PROXY", raising=False)
+ monkeypatch.delenv("http_proxy", raising=False)
+ monkeypatch.delenv("https_proxy", raising=False)
+ monkeypatch.delenv("all_proxy", raising=False)
+ monkeypatch.delenv("no_proxy", raising=False)
client = DefaultAsyncHttpxClient()
diff --git a/tests/test_utils/test_path.py b/tests/test_utils/test_path.py
new file mode 100644
index 000000000..a181b7010
--- /dev/null
+++ b/tests/test_utils/test_path.py
@@ -0,0 +1,89 @@
+from __future__ import annotations
+
+from typing import Any
+
+import pytest
+
+from structify._utils._path import path_template
+
+
+@pytest.mark.parametrize(
+ "template, kwargs, expected",
+ [
+ ("/v1/{id}", dict(id="abc"), "/v1/abc"),
+ ("/v1/{a}/{b}", dict(a="x", b="y"), "/v1/x/y"),
+ ("/v1/{a}{b}/path/{c}?val={d}#{e}", dict(a="x", b="y", c="z", d="u", e="v"), "/v1/xy/path/z?val=u#v"),
+ ("/{w}/{w}", dict(w="echo"), "/echo/echo"),
+ ("/v1/static", {}, "/v1/static"),
+ ("", {}, ""),
+ ("/v1/?q={n}&count=10", dict(n=42), "/v1/?q=42&count=10"),
+ ("/v1/{v}", dict(v=None), "/v1/null"),
+ ("/v1/{v}", dict(v=True), "/v1/true"),
+ ("/v1/{v}", dict(v=False), "/v1/false"),
+ ("/v1/{v}", dict(v=".hidden"), "/v1/.hidden"), # dot prefix ok
+ ("/v1/{v}", dict(v="file.txt"), "/v1/file.txt"), # dot in middle ok
+ ("/v1/{v}", dict(v="..."), "/v1/..."), # triple dot ok
+ ("/v1/{a}{b}", dict(a=".", b="txt"), "/v1/.txt"), # dot var combining with adjacent to be ok
+ ("/items?q={v}#{f}", dict(v=".", f=".."), "/items?q=.#.."), # dots in query/fragment are fine
+ (
+ "/v1/{a}?query={b}",
+ dict(a="../../other/endpoint", b="a&bad=true"),
+ "/v1/..%2F..%2Fother%2Fendpoint?query=a%26bad%3Dtrue",
+ ),
+ ("/v1/{val}", dict(val="a/b/c"), "/v1/a%2Fb%2Fc"),
+ ("/v1/{val}", dict(val="a/b/c?query=value"), "/v1/a%2Fb%2Fc%3Fquery=value"),
+ ("/v1/{val}", dict(val="a/b/c?query=value&bad=true"), "/v1/a%2Fb%2Fc%3Fquery=value&bad=true"),
+ ("/v1/{val}", dict(val="%20"), "/v1/%2520"), # escapes escape sequences in input
+ # Query: slash and ? are safe, # is not
+ ("/items?q={v}", dict(v="a/b"), "/items?q=a/b"),
+ ("/items?q={v}", dict(v="a?b"), "/items?q=a?b"),
+ ("/items?q={v}", dict(v="a#b"), "/items?q=a%23b"),
+ ("/items?q={v}", dict(v="a b"), "/items?q=a%20b"),
+ # Fragment: slash and ? are safe
+ ("/docs#{v}", dict(v="a/b"), "/docs#a/b"),
+ ("/docs#{v}", dict(v="a?b"), "/docs#a?b"),
+ # Path: slash, ? and # are all encoded
+ ("/v1/{v}", dict(v="a/b"), "/v1/a%2Fb"),
+ ("/v1/{v}", dict(v="a?b"), "/v1/a%3Fb"),
+ ("/v1/{v}", dict(v="a#b"), "/v1/a%23b"),
+ # same var encoded differently by component
+ (
+ "/v1/{v}?q={v}#{v}",
+ dict(v="a/b?c#d"),
+ "/v1/a%2Fb%3Fc%23d?q=a/b?c%23d#a/b?c%23d",
+ ),
+ ("/v1/{val}", dict(val="x?admin=true"), "/v1/x%3Fadmin=true"), # query injection
+ ("/v1/{val}", dict(val="x#admin"), "/v1/x%23admin"), # fragment injection
+ ],
+)
+def test_interpolation(template: str, kwargs: dict[str, Any], expected: str) -> None:
+ assert path_template(template, **kwargs) == expected
+
+
+def test_missing_kwarg_raises_key_error() -> None:
+ with pytest.raises(KeyError, match="org_id"):
+ path_template("/v1/{org_id}")
+
+
+@pytest.mark.parametrize(
+ "template, kwargs",
+ [
+ ("{a}/path", dict(a=".")),
+ ("{a}/path", dict(a="..")),
+ ("/v1/{a}", dict(a=".")),
+ ("/v1/{a}", dict(a="..")),
+ ("/v1/{a}/path", dict(a=".")),
+ ("/v1/{a}/path", dict(a="..")),
+ ("/v1/{a}{b}", dict(a=".", b=".")), # adjacent vars → ".."
+ ("/v1/{a}.", dict(a=".")), # var + static → ".."
+ ("/v1/{a}{b}", dict(a="", b=".")), # empty + dot → "."
+ ("/v1/%2e/{x}", dict(x="ok")), # encoded dot in static text
+ ("/v1/%2e./{x}", dict(x="ok")), # mixed encoded ".." in static
+ ("/v1/.%2E/{x}", dict(x="ok")), # mixed encoded ".." in static
+ ("/v1/{v}?q=1", dict(v="..")),
+ ("/v1/{v}#frag", dict(v="..")),
+ ],
+)
+def test_dot_segment_rejected(template: str, kwargs: dict[str, Any]) -> None:
+ with pytest.raises(ValueError, match="dot-segment"):
+ path_template(template, **kwargs)