diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7518d9c..92182d3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,7 +19,7 @@ jobs:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/keycard-api-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
@@ -35,7 +35,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:
diff --git a/.gitignore b/.gitignore
index 95ceb18..3824f4c 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 6b7b74c..da59f99 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.3.0"
+ ".": "0.4.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index c2d3476..d146ce9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 107
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/keycard%2Fkeycard-api-e0b7b296f7b0cac79675a790974f3ad90eb46833027467ee97c3ed21675628b8.yml
-openapi_spec_hash: 5e60faefb18dd2fca721f14252ab907a
-config_hash: dbb3c94874836d520e64fc8ffda4f0d3
+configured_endpoints: 106
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/keycard%2Fkeycard-api-932699a5ea16b4d5c8f2e2f12dfe48e56d0eaefa58ea18799147582bfa8d093b.yml
+openapi_spec_hash: 7a1bede6d87265f841a08b65cd3f87e1
+config_hash: 8fdc6a9c1185417459f79052b1222ff0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 70e6ee0..5728239 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,35 @@
# Changelog
+## 0.4.0 (2026-04-10)
+
+Full Changelog: [v0.3.0...v0.4.0](https://github.com/keycardai/keycard-python/compare/v0.3.0...v0.4.0)
+
+### Features
+
+* add email search to list organization identities endpoint ([f9b2707](https://github.com/keycardai/keycard-python/commit/f9b2707b0649678407423d2f5b3007a6d7bcc2e6))
+* add openapi-yaml command ([b37854a](https://github.com/keycardai/keycard-python/commit/b37854a0910db1c34df7509b706c34306a160ebf))
+* add owner_type and enforce protection for platform-owned versions (ACC-29) ([bfac76d](https://github.com/keycardai/keycard-python/commit/bfac76da47db6264d00d9df73c387a8e5e175840))
+* add PRM discovery to MCP gateway endpoint ([fbc502d](https://github.com/keycardai/keycard-python/commit/fbc502dc075d7a0f6890317fc59203ca51d644a7))
+* improved identities pagination ([d4c4d1b](https://github.com/keycardai/keycard-python/commit/d4c4d1ba4d76d709e6067d36f1848d293d227a81))
+* **internal:** implement indices array format for query and form serialization ([617099d](https://github.com/keycardai/keycard-python/commit/617099df6ed00538530a5f4ed285130dd5ac13c7))
+* normalize and validate user input (ACC-107) ([7bb7c97](https://github.com/keycardai/keycard-python/commit/7bb7c970e37b50353c54b4afc6307608c5bcdd94))
+* provide more context for policy schema ([46bea8a](https://github.com/keycardai/keycard-python/commit/46bea8a4493318b0b37904119e057cb7b4e50550))
+* shadow testing (ACC-14) ([f8f9ac8](https://github.com/keycardai/keycard-python/commit/f8f9ac8089531b5613cb9147dd736de348de2d33))
+* Support for user identifier and provider user identifier claim ([ac47cc2](https://github.com/keycardai/keycard-python/commit/ac47cc20c48168e226a78d5402d7f8e745881bb8))
+
+
+### Bug Fixes
+
+* **client:** preserve hardcoded query params when merging with user params ([3a94db2](https://github.com/keycardai/keycard-python/commit/3a94db26d731d5d0a34957d0aec691b0346eb275))
+* ensure file data are only sent as 1 parameter ([bcc62f9](https://github.com/keycardai/keycard-python/commit/bcc62f9c4cd18748dc5a26eb4d84fee22573a237))
+* sanitize endpoint path params ([6993e56](https://github.com/keycardai/keycard-python/commit/6993e56d5e9a79713471a0b2b33920c1e2da77d9))
+
+
+### Chores
+
+* **ci:** skip lint on metadata-only changes ([bc52e3f](https://github.com/keycardai/keycard-python/commit/bc52e3f59616d0754b7f0bc30374fac7f357f63b))
+* **internal:** update gitignore ([24f9a15](https://github.com/keycardai/keycard-python/commit/24f9a15a6031769c2a5912a3eda480fb82fc17b1))
+
## 0.3.0 (2026-03-16)
Full Changelog: [v0.2.0...v0.3.0](https://github.com/keycardai/keycard-python/compare/v0.2.0...v0.3.0)
diff --git a/README.md b/README.md
index fabc50f..cf222f1 100644
--- a/README.md
+++ b/README.md
@@ -9,15 +9,6 @@ and offers both synchronous and asynchronous clients powered by [httpx](https://
It is generated with [Stainless](https://www.stainless.com/).
-## MCP Server
-
-Use the Keycard API MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
-
-[](https://cursor.com/en-US/install-mcp?name=%40keycardai%2Fapi-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBrZXljYXJkYWkvYXBpLW1jcCJdLCJlbnYiOnsiS0VZQ0FSRF9BUElfQVBJX0tFWSI6Ik15IEFQSSBLZXkiLCJLRVlDQVJEX0FQSV9DTElFTlRfSUQiOiJNeSBDbGllbnQgSUQiLCJLRVlDQVJEX0FQSV9DTElFTlRfU0VDUkVUIjoiTXkgQ2xpZW50IFNlY3JldCJ9fQ)
-[](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22%40keycardai%2Fapi-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40keycardai%2Fapi-mcp%22%5D%2C%22env%22%3A%7B%22KEYCARD_API_API_KEY%22%3A%22My%20API%20Key%22%2C%22KEYCARD_API_CLIENT_ID%22%3A%22My%20Client%20ID%22%2C%22KEYCARD_API_CLIENT_SECRET%22%3A%22My%20Client%20Secret%22%7D%7D)
-
-> Note: You may need to set environment variables in your MCP client.
-
## Documentation
The REST API documentation can be found on [docs.keycard.ai](https://docs.keycard.ai). The full API of this library can be found in [api.md](api.md).
diff --git a/api.md b/api.md
index 2fe229e..de50220 100644
--- a/api.md
+++ b/api.md
@@ -8,7 +8,6 @@ from keycardai_api.types import (
PageInfoPagination,
Zone,
ZoneListResponse,
- ZoneListSessionResourceAccessResponse,
)
```
@@ -19,7 +18,6 @@ Methods:
- client.zones.update(zone_id, \*\*params) -> Zone
- client.zones.list(\*\*params) -> ZoneListResponse
- client.zones.delete(zone_id) -> None
-- client.zones.list_session_resource_access(zone_id, \*\*params) -> ZoneListSessionResourceAccessResponse
## Applications
diff --git a/pyproject.toml b/pyproject.toml
index 77ffed2..5b59e67 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "keycardai_api"
-version = "0.3.0"
+version = "0.4.0"
description = "The official Python library for the keycard-api API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/keycardai_api/_base_client.py b/src/keycardai_api/_base_client.py
index 8696779..37a66b0 100644
--- a/src/keycardai_api/_base_client.py
+++ b/src/keycardai_api/_base_client.py
@@ -558,6 +558,10 @@ def _build_request(
files = cast(HttpxRequestFiles, ForceMultipartDict())
prepared_url = self._prepare_url(options.url)
+ # preserve hard-coded query params from the url
+ if params and prepared_url.query:
+ params = {**dict(prepared_url.params.items()), **params}
+ prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0])
if "_" in prepared_url.host:
# work around https://github.com/encode/httpx/discussions/2880
kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")}
diff --git a/src/keycardai_api/_qs.py b/src/keycardai_api/_qs.py
index ada6fd3..de8c99b 100644
--- a/src/keycardai_api/_qs.py
+++ b/src/keycardai_api/_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/keycardai_api/_utils/__init__.py b/src/keycardai_api/_utils/__init__.py
index dc64e29..10cb66d 100644
--- a/src/keycardai_api/_utils/__init__.py
+++ b/src/keycardai_api/_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/keycardai_api/_utils/_path.py b/src/keycardai_api/_utils/_path.py
new file mode 100644
index 0000000..4d6e1e4
--- /dev/null
+++ b/src/keycardai_api/_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/keycardai_api/_utils/_utils.py b/src/keycardai_api/_utils/_utils.py
index eec7f4a..63b8cd6 100644
--- a/src/keycardai_api/_utils/_utils.py
+++ b/src/keycardai_api/_utils/_utils.py
@@ -86,8 +86,9 @@ def _extract_items(
index += 1
if is_dict(obj):
try:
- # We are at the last entry in the path so we must remove the field
- if (len(path)) == index:
+ # Remove the field if there are no more dict keys in the path,
+ # only "" traversal markers or end.
+ if all(p == "" for p in path[index:]):
item = obj.pop(key)
else:
item = obj[key]
diff --git a/src/keycardai_api/_version.py b/src/keycardai_api/_version.py
index 239bc4c..6bfff43 100644
--- a/src/keycardai_api/_version.py
+++ b/src/keycardai_api/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "keycardai_api"
-__version__ = "0.3.0" # x-release-please-version
+__version__ = "0.4.0" # x-release-please-version
diff --git a/src/keycardai_api/resources/invitations.py b/src/keycardai_api/resources/invitations.py
index 57f8339..923bb58 100644
--- a/src/keycardai_api/resources/invitations.py
+++ b/src/keycardai_api/resources/invitations.py
@@ -5,7 +5,7 @@
import httpx
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import strip_not_given
+from .._utils import path_template, strip_not_given
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -69,7 +69,7 @@ def retrieve(
raise ValueError(f"Expected a non-empty value for `token` but received {token!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/invitations/{token}",
+ path_template("/invitations/{token}", token=token),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -108,7 +108,7 @@ def accept(
raise ValueError(f"Expected a non-empty value for `token` but received {token!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._post(
- f"/invitations/{token}/accept",
+ path_template("/invitations/{token}/accept", token=token),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -164,7 +164,7 @@ async def retrieve(
raise ValueError(f"Expected a non-empty value for `token` but received {token!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/invitations/{token}",
+ path_template("/invitations/{token}", token=token),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -203,7 +203,7 @@ async def accept(
raise ValueError(f"Expected a non-empty value for `token` but received {token!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._post(
- f"/invitations/{token}/accept",
+ path_template("/invitations/{token}/accept", token=token),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/keycardai_api/resources/organizations/invitations.py b/src/keycardai_api/resources/organizations/invitations.py
index 8a71cc2..ab0ccce 100644
--- a/src/keycardai_api/resources/organizations/invitations.py
+++ b/src/keycardai_api/resources/organizations/invitations.py
@@ -8,7 +8,7 @@
import httpx
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ..._utils import maybe_transform, strip_not_given, async_maybe_transform
+from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -82,7 +82,7 @@ def create(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._post(
- f"/organizations/{organization_id}/invitations",
+ path_template("/organizations/{organization_id}/invitations", organization_id=organization_id),
body=maybe_transform(
{
"email": email,
@@ -102,7 +102,7 @@ def list(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -122,8 +122,11 @@ def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of invitations to return
@@ -139,7 +142,7 @@ def list(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/invitations",
+ path_template("/organizations/{organization_id}/invitations", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -194,7 +197,11 @@ def delete(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._delete(
- f"/organizations/{organization_id}/invitations/{invitation_id}",
+ path_template(
+ "/organizations/{organization_id}/invitations/{invitation_id}",
+ organization_id=organization_id,
+ invitation_id=invitation_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -258,7 +265,7 @@ async def create(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._post(
- f"/organizations/{organization_id}/invitations",
+ path_template("/organizations/{organization_id}/invitations", organization_id=organization_id),
body=await async_maybe_transform(
{
"email": email,
@@ -278,7 +285,7 @@ async def list(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -298,8 +305,11 @@ async def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of invitations to return
@@ -315,7 +325,7 @@ async def list(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/invitations",
+ path_template("/organizations/{organization_id}/invitations", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -370,7 +380,11 @@ async def delete(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._delete(
- f"/organizations/{organization_id}/invitations/{invitation_id}",
+ path_template(
+ "/organizations/{organization_id}/invitations/{invitation_id}",
+ organization_id=organization_id,
+ invitation_id=invitation_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/keycardai_api/resources/organizations/organizations.py b/src/keycardai_api/resources/organizations/organizations.py
index 4678241..49df542 100644
--- a/src/keycardai_api/resources/organizations/organizations.py
+++ b/src/keycardai_api/resources/organizations/organizations.py
@@ -25,7 +25,7 @@
organization_list_identities_params,
)
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, strip_not_given, async_maybe_transform
+from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -145,7 +145,7 @@ def retrieve(
self,
organization_id: str,
*,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -160,8 +160,11 @@ def retrieve(
Args:
organization_id: Organization ID or label identifier
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -175,7 +178,7 @@ def retrieve(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}",
+ path_template("/organizations/{organization_id}", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -219,7 +222,7 @@ def update(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._patch(
- f"/organizations/{organization_id}",
+ path_template("/organizations/{organization_id}", organization_id=organization_id),
body=maybe_transform({"name": name}, organization_update_params.OrganizationUpdateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -232,7 +235,7 @@ def list(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -250,8 +253,11 @@ def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of organizations to return
@@ -314,7 +320,7 @@ def exchange_token(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._post(
- f"/organizations/{organization_id}/token",
+ path_template("/organizations/{organization_id}/token", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -327,8 +333,9 @@ def list_identities(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
+ query_email: str | Omit = omit,
role: OrganizationRole | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -348,11 +355,16 @@ def list_identities(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of identities to return
+ query_email: Search identities by email substring (case-insensitive)
+
role: Filter identities by role
extra_headers: Send extra headers
@@ -367,7 +379,7 @@ def list_identities(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/identities",
+ path_template("/organizations/{organization_id}/identities", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -379,6 +391,7 @@ def list_identities(
"before": before,
"expand": expand,
"limit": limit,
+ "query_email": query_email,
"role": role,
},
organization_list_identities_params.OrganizationListIdentitiesParams,
@@ -391,7 +404,7 @@ def list_roles(
self,
organization_id: str,
*,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
scope: RoleScope | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -416,8 +429,11 @@ def list_roles(
Args:
organization_id: Organization ID or label identifier
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
scope: Filter roles by scope (organization or zone level)
@@ -433,7 +449,7 @@ def list_roles(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/roles",
+ path_template("/organizations/{organization_id}/roles", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -525,7 +541,7 @@ async def retrieve(
self,
organization_id: str,
*,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -540,8 +556,11 @@ async def retrieve(
Args:
organization_id: Organization ID or label identifier
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -555,7 +574,7 @@ async def retrieve(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}",
+ path_template("/organizations/{organization_id}", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -601,7 +620,7 @@ async def update(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._patch(
- f"/organizations/{organization_id}",
+ path_template("/organizations/{organization_id}", organization_id=organization_id),
body=await async_maybe_transform({"name": name}, organization_update_params.OrganizationUpdateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -614,7 +633,7 @@ async def list(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -632,8 +651,11 @@ async def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of organizations to return
@@ -696,7 +718,7 @@ async def exchange_token(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._post(
- f"/organizations/{organization_id}/token",
+ path_template("/organizations/{organization_id}/token", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -709,8 +731,9 @@ async def list_identities(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
+ query_email: str | Omit = omit,
role: OrganizationRole | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -730,11 +753,16 @@ async def list_identities(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of identities to return
+ query_email: Search identities by email substring (case-insensitive)
+
role: Filter identities by role
extra_headers: Send extra headers
@@ -749,7 +777,7 @@ async def list_identities(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/identities",
+ path_template("/organizations/{organization_id}/identities", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -761,6 +789,7 @@ async def list_identities(
"before": before,
"expand": expand,
"limit": limit,
+ "query_email": query_email,
"role": role,
},
organization_list_identities_params.OrganizationListIdentitiesParams,
@@ -773,7 +802,7 @@ async def list_roles(
self,
organization_id: str,
*,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
scope: RoleScope | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -798,8 +827,11 @@ async def list_roles(
Args:
organization_id: Organization ID or label identifier
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
scope: Filter roles by scope (organization or zone level)
@@ -815,7 +847,7 @@ async def list_roles(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/roles",
+ path_template("/organizations/{organization_id}/roles", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/keycardai_api/resources/organizations/service_accounts/credentials.py b/src/keycardai_api/resources/organizations/service_accounts/credentials.py
index 5b5e4fe..e74e94a 100644
--- a/src/keycardai_api/resources/organizations/service_accounts/credentials.py
+++ b/src/keycardai_api/resources/organizations/service_accounts/credentials.py
@@ -8,7 +8,7 @@
import httpx
from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ...._utils import maybe_transform, strip_not_given, async_maybe_transform
+from ...._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform
from ...._compat import cached_property
from ...._resource import SyncAPIResource, AsyncAPIResource
from ...._response import (
@@ -92,7 +92,11 @@ def create(
raise ValueError(f"Expected a non-empty value for `service_account_id` but received {service_account_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._post(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
body=maybe_transform(
{
"name": name,
@@ -112,7 +116,7 @@ def retrieve(
*,
organization_id: str,
service_account_id: str,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -131,8 +135,11 @@ def retrieve(
credential_id: Identifier for API resources. A 26-char nanoid (URL/DNS safe).
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -150,7 +157,12 @@ def retrieve(
raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ credential_id=credential_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -207,7 +219,12 @@ def update(
raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._patch(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ credential_id=credential_id,
+ ),
body=maybe_transform(
{
"description": description,
@@ -228,7 +245,7 @@ def list(
organization_id: str,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -250,8 +267,11 @@ def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of credentials to return
@@ -269,7 +289,11 @@ def list(
raise ValueError(f"Expected a non-empty value for `service_account_id` but received {service_account_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -329,7 +353,12 @@ def delete(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._delete(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ credential_id=credential_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -398,7 +427,11 @@ async def create(
raise ValueError(f"Expected a non-empty value for `service_account_id` but received {service_account_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._post(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
body=await async_maybe_transform(
{
"name": name,
@@ -418,7 +451,7 @@ async def retrieve(
*,
organization_id: str,
service_account_id: str,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -437,8 +470,11 @@ async def retrieve(
credential_id: Identifier for API resources. A 26-char nanoid (URL/DNS safe).
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -456,7 +492,12 @@ async def retrieve(
raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ credential_id=credential_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -515,7 +556,12 @@ async def update(
raise ValueError(f"Expected a non-empty value for `credential_id` but received {credential_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._patch(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ credential_id=credential_id,
+ ),
body=await async_maybe_transform(
{
"description": description,
@@ -536,7 +582,7 @@ async def list(
organization_id: str,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -558,8 +604,11 @@ async def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of credentials to return
@@ -577,7 +626,11 @@ async def list(
raise ValueError(f"Expected a non-empty value for `service_account_id` but received {service_account_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -637,7 +690,12 @@ async def delete(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._delete(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ credential_id=credential_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/keycardai_api/resources/organizations/service_accounts/service_accounts.py b/src/keycardai_api/resources/organizations/service_accounts/service_accounts.py
index 5817d28..68715b3 100644
--- a/src/keycardai_api/resources/organizations/service_accounts/service_accounts.py
+++ b/src/keycardai_api/resources/organizations/service_accounts/service_accounts.py
@@ -8,7 +8,7 @@
import httpx
from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ...._utils import maybe_transform, strip_not_given, async_maybe_transform
+from ...._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform
from ...._compat import cached_property
from .credentials import (
CredentialsResource,
@@ -98,7 +98,7 @@ def create(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._post(
- f"/organizations/{organization_id}/service-accounts",
+ path_template("/organizations/{organization_id}/service-accounts", organization_id=organization_id),
body=maybe_transform(
{
"name": name,
@@ -117,7 +117,7 @@ def retrieve(
service_account_id: str,
*,
organization_id: str,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -134,8 +134,11 @@ def retrieve(
service_account_id: Identifier for API resources. A 26-char nanoid (URL/DNS safe).
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -151,7 +154,11 @@ def retrieve(
raise ValueError(f"Expected a non-empty value for `service_account_id` but received {service_account_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -203,7 +210,11 @@ def update(
raise ValueError(f"Expected a non-empty value for `service_account_id` but received {service_account_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._patch(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
body=maybe_transform(
{
"description": description,
@@ -223,7 +234,7 @@ def list(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -243,8 +254,11 @@ def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of service accounts to return
@@ -260,7 +274,7 @@ def list(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/service-accounts",
+ path_template("/organizations/{organization_id}/service-accounts", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -315,7 +329,11 @@ def delete(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._delete(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -383,7 +401,7 @@ async def create(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._post(
- f"/organizations/{organization_id}/service-accounts",
+ path_template("/organizations/{organization_id}/service-accounts", organization_id=organization_id),
body=await async_maybe_transform(
{
"name": name,
@@ -402,7 +420,7 @@ async def retrieve(
service_account_id: str,
*,
organization_id: str,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -419,8 +437,11 @@ async def retrieve(
service_account_id: Identifier for API resources. A 26-char nanoid (URL/DNS safe).
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -436,7 +457,11 @@ async def retrieve(
raise ValueError(f"Expected a non-empty value for `service_account_id` but received {service_account_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -490,7 +515,11 @@ async def update(
raise ValueError(f"Expected a non-empty value for `service_account_id` but received {service_account_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._patch(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
body=await async_maybe_transform(
{
"description": description,
@@ -510,7 +539,7 @@ async def list(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
x_client_request_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -530,8 +559,11 @@ async def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of service accounts to return
@@ -547,7 +579,7 @@ async def list(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/service-accounts",
+ path_template("/organizations/{organization_id}/service-accounts", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -602,7 +634,11 @@ async def delete(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._delete(
- f"/organizations/{organization_id}/service-accounts/{service_account_id}",
+ path_template(
+ "/organizations/{organization_id}/service-accounts/{service_account_id}",
+ organization_id=organization_id,
+ service_account_id=service_account_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/keycardai_api/resources/organizations/sso_connection.py b/src/keycardai_api/resources/organizations/sso_connection.py
index 7c4ddac..4a8a44f 100644
--- a/src/keycardai_api/resources/organizations/sso_connection.py
+++ b/src/keycardai_api/resources/organizations/sso_connection.py
@@ -8,7 +8,7 @@
import httpx
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ..._utils import maybe_transform, strip_not_given, async_maybe_transform
+from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -53,7 +53,7 @@ def retrieve(
self,
organization_id: str,
*,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -68,8 +68,11 @@ def retrieve(
Args:
organization_id: Organization ID or label identifier
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -83,7 +86,7 @@ def retrieve(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/sso-connection",
+ path_template("/organizations/{organization_id}/sso-connection", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -136,7 +139,7 @@ def update(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._patch(
- f"/organizations/{organization_id}/sso-connection",
+ path_template("/organizations/{organization_id}/sso-connection", organization_id=organization_id),
body=maybe_transform(
{
"client_id": client_id,
@@ -183,7 +186,7 @@ def disable(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._delete(
- f"/organizations/{organization_id}/sso-connection",
+ path_template("/organizations/{organization_id}/sso-connection", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -232,7 +235,7 @@ def enable(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._post(
- f"/organizations/{organization_id}/sso-connection",
+ path_template("/organizations/{organization_id}/sso-connection", organization_id=organization_id),
body=maybe_transform(
{
"client_id": client_id,
@@ -273,7 +276,7 @@ async def retrieve(
self,
organization_id: str,
*,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -288,8 +291,11 @@ async def retrieve(
Args:
organization_id: Organization ID or label identifier
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -303,7 +309,7 @@ async def retrieve(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/sso-connection",
+ path_template("/organizations/{organization_id}/sso-connection", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -358,7 +364,7 @@ async def update(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._patch(
- f"/organizations/{organization_id}/sso-connection",
+ path_template("/organizations/{organization_id}/sso-connection", organization_id=organization_id),
body=await async_maybe_transform(
{
"client_id": client_id,
@@ -405,7 +411,7 @@ async def disable(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._delete(
- f"/organizations/{organization_id}/sso-connection",
+ path_template("/organizations/{organization_id}/sso-connection", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -454,7 +460,7 @@ async def enable(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._post(
- f"/organizations/{organization_id}/sso-connection",
+ path_template("/organizations/{organization_id}/sso-connection", organization_id=organization_id),
body=await async_maybe_transform(
{
"client_id": client_id,
diff --git a/src/keycardai_api/resources/organizations/users.py b/src/keycardai_api/resources/organizations/users.py
index 29e0b12..9ef4fa1 100644
--- a/src/keycardai_api/resources/organizations/users.py
+++ b/src/keycardai_api/resources/organizations/users.py
@@ -8,7 +8,7 @@
import httpx
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ..._utils import maybe_transform, strip_not_given, async_maybe_transform
+from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -58,7 +58,7 @@ def retrieve(
user_id: str,
*,
organization_id: str,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -75,8 +75,11 @@ def retrieve(
user_id: Identifier for API resources. A 26-char nanoid (URL/DNS safe).
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -92,7 +95,9 @@ def retrieve(
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/users/{user_id}",
+ path_template(
+ "/organizations/{organization_id}/users/{user_id}", organization_id=organization_id, user_id=user_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -144,7 +149,9 @@ def update(
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._patch(
- f"/organizations/{organization_id}/users/{user_id}",
+ path_template(
+ "/organizations/{organization_id}/users/{user_id}", organization_id=organization_id, user_id=user_id
+ ),
body=maybe_transform(
{
"role": role,
@@ -164,7 +171,7 @@ def list(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
role: OrganizationRole | Omit = omit,
x_client_request_id: str | Omit = omit,
@@ -185,8 +192,11 @@ def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of users to return
@@ -204,7 +214,7 @@ def list(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._get(
- f"/organizations/{organization_id}/users",
+ path_template("/organizations/{organization_id}/users", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -260,7 +270,9 @@ def delete(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return self._delete(
- f"/organizations/{organization_id}/users/{user_id}",
+ path_template(
+ "/organizations/{organization_id}/users/{user_id}", organization_id=organization_id, user_id=user_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -293,7 +305,7 @@ async def retrieve(
user_id: str,
*,
organization_id: str,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
x_client_request_id: 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.
@@ -310,8 +322,11 @@ async def retrieve(
user_id: Identifier for API resources. A 26-char nanoid (URL/DNS safe).
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
extra_headers: Send extra headers
@@ -327,7 +342,9 @@ async def retrieve(
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/users/{user_id}",
+ path_template(
+ "/organizations/{organization_id}/users/{user_id}", organization_id=organization_id, user_id=user_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -379,7 +396,9 @@ async def update(
raise ValueError(f"Expected a non-empty value for `user_id` but received {user_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._patch(
- f"/organizations/{organization_id}/users/{user_id}",
+ path_template(
+ "/organizations/{organization_id}/users/{user_id}", organization_id=organization_id, user_id=user_id
+ ),
body=await async_maybe_transform(
{
"role": role,
@@ -399,7 +418,7 @@ async def list(
*,
after: str | Omit = omit,
before: str | Omit = omit,
- expand: List[Literal["permissions"]] | Omit = omit,
+ expand: List[Literal["permissions", "total_count"]] | Omit = omit,
limit: int | Omit = omit,
role: OrganizationRole | Omit = omit,
x_client_request_id: str | Omit = omit,
@@ -420,8 +439,11 @@ async def list(
before: Cursor for backward pagination
- expand: Fields to expand in the response. Currently supports "permissions" to include
- the permissions field with the caller's permissions for the resource.
+ expand: Fields to expand in the response. Supports "permissions" to include the
+ permissions field with the caller's permissions for the resource. For list
+ organization identities only, "total_count" populates pagination.total_count
+ with the number of identities matching the same filters as the list (excluding
+ cursor and limit). Other operations ignore expand values they do not use.
limit: Maximum number of users to return
@@ -439,7 +461,7 @@ async def list(
raise ValueError(f"Expected a non-empty value for `organization_id` but received {organization_id!r}")
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._get(
- f"/organizations/{organization_id}/users",
+ path_template("/organizations/{organization_id}/users", organization_id=organization_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -495,7 +517,9 @@ async def delete(
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
extra_headers = {**strip_not_given({"X-Client-Request-ID": x_client_request_id}), **(extra_headers or {})}
return await self._delete(
- f"/organizations/{organization_id}/users/{user_id}",
+ path_template(
+ "/organizations/{organization_id}/users/{user_id}", organization_id=organization_id, user_id=user_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/keycardai_api/resources/zones/application_credentials.py b/src/keycardai_api/resources/zones/application_credentials.py
index 1d2abf7..14e9b18 100644
--- a/src/keycardai_api/resources/zones/application_credentials.py
+++ b/src/keycardai_api/resources/zones/application_credentials.py
@@ -8,7 +8,7 @@
import httpx
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ..._utils import required_args, maybe_transform, async_maybe_transform
+from ..._utils import path_template, required_args, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -253,7 +253,7 @@ def create(
return cast(
ApplicationCredentialCreateResponse,
self._post(
- f"/zones/{zone_id}/application-credentials",
+ path_template("/zones/{zone_id}/application-credentials", zone_id=zone_id),
body=maybe_transform(
{
"application_id": application_id,
@@ -305,7 +305,7 @@ def retrieve(
return cast(
Credential,
self._get(
- f"/zones/{zone_id}/application-credentials/{id}",
+ path_template("/zones/{zone_id}/application-credentials/{id}", zone_id=zone_id, id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -491,7 +491,7 @@ def update(
return cast(
Credential,
self._patch(
- f"/zones/{zone_id}/application-credentials/{id}",
+ path_template("/zones/{zone_id}/application-credentials/{id}", zone_id=zone_id, id=id),
body=maybe_transform(
{
"subject": subject,
@@ -546,7 +546,7 @@ def list(
if not zone_id:
raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
return self._get(
- f"/zones/{zone_id}/application-credentials",
+ path_template("/zones/{zone_id}/application-credentials", zone_id=zone_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -598,7 +598,7 @@ def delete(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/zones/{zone_id}/application-credentials/{id}",
+ path_template("/zones/{zone_id}/application-credentials/{id}", zone_id=zone_id, id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -829,7 +829,7 @@ async def create(
return cast(
ApplicationCredentialCreateResponse,
await self._post(
- f"/zones/{zone_id}/application-credentials",
+ path_template("/zones/{zone_id}/application-credentials", zone_id=zone_id),
body=await async_maybe_transform(
{
"application_id": application_id,
@@ -881,7 +881,7 @@ async def retrieve(
return cast(
Credential,
await self._get(
- f"/zones/{zone_id}/application-credentials/{id}",
+ path_template("/zones/{zone_id}/application-credentials/{id}", zone_id=zone_id, id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1067,7 +1067,7 @@ async def update(
return cast(
Credential,
await self._patch(
- f"/zones/{zone_id}/application-credentials/{id}",
+ path_template("/zones/{zone_id}/application-credentials/{id}", zone_id=zone_id, id=id),
body=await async_maybe_transform(
{
"subject": subject,
@@ -1122,7 +1122,7 @@ async def list(
if not zone_id:
raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
return await self._get(
- f"/zones/{zone_id}/application-credentials",
+ path_template("/zones/{zone_id}/application-credentials", zone_id=zone_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1174,7 +1174,7 @@ async def delete(
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"/zones/{zone_id}/application-credentials/{id}",
+ path_template("/zones/{zone_id}/application-credentials/{id}", zone_id=zone_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/keycardai_api/resources/zones/applications/applications.py b/src/keycardai_api/resources/zones/applications/applications.py
index b03bbfa..98cce49 100644
--- a/src/keycardai_api/resources/zones/applications/applications.py
+++ b/src/keycardai_api/resources/zones/applications/applications.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 (
@@ -74,6 +74,7 @@ def create(
*,
identifier: str,
name: str,
+ consent: Literal["implicit", "required"] | Omit = omit,
dependencies: Iterable[application_create_params.Dependency] | Omit = omit,
description: Optional[str] | Omit = omit,
metadata: MetadataParam | Omit = omit,
@@ -90,13 +91,18 @@ def create(
Resources
Args:
- identifier: User specified identifier, unique within the zone
+ identifier: User specified identifier, unique within the zone. Must not contain HTML tags
+ (e.g. `