diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 124b9841..486a203f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.119.0" + ".": "0.120.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 46156227..b2f535c2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 189 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-5bb8d2bedef02f07498de3f252fa6da1393d2fb59f727b05828804cea9aded30.yml -openapi_spec_hash: d1f260252b3bb7ebc77fa7134db6c65d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-8aac2690599ec7343fab3957433e94ebf63ac1186c753e00dff85b32f4d6e88c.yml +openapi_spec_hash: 84da9d0725e41cb5661c6ed6661ce101 config_hash: 400b9afe0f7f7b7d96177d05950775f9 diff --git a/CHANGELOG.md b/CHANGELOG.md index b64673d1..0f73a07a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## 0.120.0 (2026-03-20) + +Full Changelog: [v0.119.0...v0.120.0](https://github.com/lithic-com/lithic-python/compare/v0.119.0...v0.120.0) + +### Features + +* **api:** add CARD_AGE and ACCOUNT_AGE attributes to auth_rules conditions ([1838bd0](https://github.com/lithic-com/lithic-python/commit/1838bd0fbb14543bc05140167eb787b26f3adad1)) +* **api:** add override_company_name parameter to external_payments create ([ebb9e7e](https://github.com/lithic-com/lithic-python/commit/ebb9e7e42397c158c13a8c79a20ae62a5bc5dff9)) +* **api:** add service location attributes to auth_rules, fields to merchant ([40b6ef4](https://github.com/lithic-com/lithic-python/commit/40b6ef452d154afd5262977b20ddbea8f2581d9c)) + + +### Bug Fixes + +* sanitize endpoint path params ([3bdb99d](https://github.com/lithic-com/lithic-python/commit/3bdb99d62ca73acbd65d4f2ca3dda9e9405c05e3)) + + +### Chores + +* **tests:** bump steady to v0.19.4 ([6e585b7](https://github.com/lithic-com/lithic-python/commit/6e585b742334baf5045bbc1d8be487674a4ec9af)) +* **tests:** bump steady to v0.19.5 ([327135e](https://github.com/lithic-com/lithic-python/commit/327135ec2c31132edcf1d3a3cbb4f4f7f6dbdb1a)) + + +### Refactors + +* **tests:** switch from prism to steady ([23a9671](https://github.com/lithic-com/lithic-python/commit/23a967122869204b8e063e86d2807417d1542b5b)) + ## 0.119.0 (2026-03-17) Full Changelog: [v0.118.0...v0.119.0](https://github.com/lithic-com/lithic-python/compare/v0.118.0...v0.119.0) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e758caa0..54b573f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -85,7 +85,7 @@ $ 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 $ ./scripts/mock diff --git a/pyproject.toml b/pyproject.toml index 28959094..1a227b5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lithic" -version = "0.119.0" +version = "0.120.0" description = "The official Python library for the lithic API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/scripts/mock b/scripts/mock index bcf3b392..ab814d38 100755 --- a/scripts/mock +++ b/scripts/mock @@ -19,34 +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 # Pre-install the package so the download doesn't eat into the startup timeout - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism --version + npm exec --package=@stdy/cli@0.19.5 -- steady --version - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & + npm exec --package=@stdy/cli@0.19.5 -- steady --host 127.0.0.1 -p 4010 --validator-form-array-format=comma --validator-query-array-format=comma --validator-form-object-format=brackets --validator-query-object-format=brackets "$URL" &> .stdy.log & - # Wait for server to come online (max 30s) + # Wait for server to come online via health endpoint (max 30s) echo -n "Waiting for server" attempts=0 - while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do + 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 Prism server to start" - cat .prism.log + 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.5 -- steady --host 127.0.0.1 -p 4010 --validator-form-array-format=comma --validator-query-array-format=comma --validator-form-object-format=brackets --validator-query-object-format=brackets "$URL" fi diff --git a/scripts/test b/scripts/test index dbeda2d2..d1c8e1a9 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.5 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-form-array-format=comma --validator-query-array-format=comma --validator-form-object-format=brackets --validator-query-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/lithic/_utils/__init__.py b/src/lithic/_utils/__init__.py index dc64e29a..10cb66d2 100644 --- a/src/lithic/_utils/__init__.py +++ b/src/lithic/_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/lithic/_utils/_path.py b/src/lithic/_utils/_path.py new file mode 100644 index 00000000..4d6e1e4c --- /dev/null +++ b/src/lithic/_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/lithic/_version.py b/src/lithic/_version.py index e18b73b4..63c609e4 100644 --- a/src/lithic/_version.py +++ b/src/lithic/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "lithic" -__version__ = "0.119.0" # x-release-please-version +__version__ = "0.120.0" # x-release-please-version diff --git a/src/lithic/resources/account_activity.py b/src/lithic/resources/account_activity.py index e9934587..3b9a3119 100644 --- a/src/lithic/resources/account_activity.py +++ b/src/lithic/resources/account_activity.py @@ -11,7 +11,7 @@ from .. import _legacy_response from ..types import account_activity_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -184,7 +184,7 @@ def retrieve_transaction( return cast( AccountActivityRetrieveTransactionResponse, self._get( - f"/v1/account_activity/{transaction_token}", + path_template("/v1/account_activity/{transaction_token}", transaction_token=transaction_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -356,7 +356,7 @@ async def retrieve_transaction( return cast( AccountActivityRetrieveTransactionResponse, await self._get( - f"/v1/account_activity/{transaction_token}", + path_template("/v1/account_activity/{transaction_token}", transaction_token=transaction_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/account_holders/account_holders.py b/src/lithic/resources/account_holders/account_holders.py index 11a6c508..12046d61 100644 --- a/src/lithic/resources/account_holders/account_holders.py +++ b/src/lithic/resources/account_holders/account_holders.py @@ -18,7 +18,7 @@ account_holder_simulate_enrollment_document_review_params, ) from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given -from ..._utils import is_given, required_args, maybe_transform, async_maybe_transform +from ..._utils import is_given, path_template, required_args, maybe_transform, async_maybe_transform from .entities import ( Entities, AsyncEntities, @@ -461,7 +461,7 @@ def retrieve( f"Expected a non-empty value for `account_holder_token` but received {account_holder_token!r}" ) return self._get( - f"/v1/account_holders/{account_holder_token}", + path_template("/v1/account_holders/{account_holder_token}", account_holder_token=account_holder_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -679,7 +679,7 @@ def update( return cast( AccountHolderUpdateResponse, self._patch( - f"/v1/account_holders/{account_holder_token}", + path_template("/v1/account_holders/{account_holder_token}", account_holder_token=account_holder_token), body=maybe_transform( { "beneficial_owner_individuals": beneficial_owner_individuals, @@ -843,7 +843,9 @@ def list_documents( f"Expected a non-empty value for `account_holder_token` but received {account_holder_token!r}" ) return self._get( - f"/v1/account_holders/{account_holder_token}/documents", + path_template( + "/v1/account_holders/{account_holder_token}/documents", account_holder_token=account_holder_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -894,7 +896,11 @@ def retrieve_document( if not document_token: raise ValueError(f"Expected a non-empty value for `document_token` but received {document_token!r}") return self._get( - f"/v1/account_holders/{account_holder_token}/documents/{document_token}", + path_template( + "/v1/account_holders/{account_holder_token}/documents/{document_token}", + account_holder_token=account_holder_token, + document_token=document_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1108,7 +1114,9 @@ def upload_document( f"Expected a non-empty value for `account_holder_token` but received {account_holder_token!r}" ) return self._post( - f"/v1/account_holders/{account_holder_token}/documents", + path_template( + "/v1/account_holders/{account_holder_token}/documents", account_holder_token=account_holder_token + ), body=maybe_transform( { "document_type": document_type, @@ -1539,7 +1547,7 @@ async def retrieve( f"Expected a non-empty value for `account_holder_token` but received {account_holder_token!r}" ) return await self._get( - f"/v1/account_holders/{account_holder_token}", + path_template("/v1/account_holders/{account_holder_token}", account_holder_token=account_holder_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1757,7 +1765,7 @@ async def update( return cast( AccountHolderUpdateResponse, await self._patch( - f"/v1/account_holders/{account_holder_token}", + path_template("/v1/account_holders/{account_holder_token}", account_holder_token=account_holder_token), body=await async_maybe_transform( { "beneficial_owner_individuals": beneficial_owner_individuals, @@ -1921,7 +1929,9 @@ async def list_documents( f"Expected a non-empty value for `account_holder_token` but received {account_holder_token!r}" ) return await self._get( - f"/v1/account_holders/{account_holder_token}/documents", + path_template( + "/v1/account_holders/{account_holder_token}/documents", account_holder_token=account_holder_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1972,7 +1982,11 @@ async def retrieve_document( if not document_token: raise ValueError(f"Expected a non-empty value for `document_token` but received {document_token!r}") return await self._get( - f"/v1/account_holders/{account_holder_token}/documents/{document_token}", + path_template( + "/v1/account_holders/{account_holder_token}/documents/{document_token}", + account_holder_token=account_holder_token, + document_token=document_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -2186,7 +2200,9 @@ async def upload_document( f"Expected a non-empty value for `account_holder_token` but received {account_holder_token!r}" ) return await self._post( - f"/v1/account_holders/{account_holder_token}/documents", + path_template( + "/v1/account_holders/{account_holder_token}/documents", account_holder_token=account_holder_token + ), body=await async_maybe_transform( { "document_type": document_type, diff --git a/src/lithic/resources/account_holders/entities.py b/src/lithic/resources/account_holders/entities.py index 2f72deb9..209780a4 100644 --- a/src/lithic/resources/account_holders/entities.py +++ b/src/lithic/resources/account_holders/entities.py @@ -8,7 +8,7 @@ from ... import _legacy_response from ..._types import Body, Query, Headers, NotGiven, 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -101,7 +101,9 @@ def create( f"Expected a non-empty value for `account_holder_token` but received {account_holder_token!r}" ) return self._post( - f"/v1/account_holders/{account_holder_token}/entities", + path_template( + "/v1/account_holders/{account_holder_token}/entities", account_holder_token=account_holder_token + ), body=maybe_transform( { "address": address, @@ -154,7 +156,11 @@ def delete( if not entity_token: raise ValueError(f"Expected a non-empty value for `entity_token` but received {entity_token!r}") return self._delete( - f"/v1/account_holders/{account_holder_token}/entities/{entity_token}", + path_template( + "/v1/account_holders/{account_holder_token}/entities/{entity_token}", + account_holder_token=account_holder_token, + entity_token=entity_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -243,7 +249,9 @@ async def create( f"Expected a non-empty value for `account_holder_token` but received {account_holder_token!r}" ) return await self._post( - f"/v1/account_holders/{account_holder_token}/entities", + path_template( + "/v1/account_holders/{account_holder_token}/entities", account_holder_token=account_holder_token + ), body=await async_maybe_transform( { "address": address, @@ -296,7 +304,11 @@ async def delete( if not entity_token: raise ValueError(f"Expected a non-empty value for `entity_token` but received {entity_token!r}") return await self._delete( - f"/v1/account_holders/{account_holder_token}/entities/{entity_token}", + path_template( + "/v1/account_holders/{account_holder_token}/entities/{entity_token}", + account_holder_token=account_holder_token, + entity_token=entity_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/accounts.py b/src/lithic/resources/accounts.py index 2fb57e59..703f3b47 100644 --- a/src/lithic/resources/accounts.py +++ b/src/lithic/resources/accounts.py @@ -11,7 +11,7 @@ from .. import _legacy_response from ..types import account_list_params, account_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -69,7 +69,7 @@ def retrieve( if not account_token: raise ValueError(f"Expected a non-empty value for `account_token` but received {account_token!r}") return self._get( - f"/v1/accounts/{account_token}", + path_template("/v1/accounts/{account_token}", account_token=account_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -174,7 +174,7 @@ def update( if not account_token: raise ValueError(f"Expected a non-empty value for `account_token` but received {account_token!r}") return self._patch( - f"/v1/accounts/{account_token}", + path_template("/v1/accounts/{account_token}", account_token=account_token), body=maybe_transform( { "comment": comment, @@ -287,7 +287,7 @@ def retrieve_spend_limits( if not account_token: raise ValueError(f"Expected a non-empty value for `account_token` but received {account_token!r}") return self._get( - f"/v1/accounts/{account_token}/spend_limits", + path_template("/v1/accounts/{account_token}/spend_limits", account_token=account_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -341,7 +341,7 @@ async def retrieve( if not account_token: raise ValueError(f"Expected a non-empty value for `account_token` but received {account_token!r}") return await self._get( - f"/v1/accounts/{account_token}", + path_template("/v1/accounts/{account_token}", account_token=account_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -446,7 +446,7 @@ async def update( if not account_token: raise ValueError(f"Expected a non-empty value for `account_token` but received {account_token!r}") return await self._patch( - f"/v1/accounts/{account_token}", + path_template("/v1/accounts/{account_token}", account_token=account_token), body=await async_maybe_transform( { "comment": comment, @@ -559,7 +559,7 @@ async def retrieve_spend_limits( if not account_token: raise ValueError(f"Expected a non-empty value for `account_token` but received {account_token!r}") return await self._get( - f"/v1/accounts/{account_token}/spend_limits", + path_template("/v1/accounts/{account_token}/spend_limits", account_token=account_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/auth_rules/v2/backtests.py b/src/lithic/resources/auth_rules/v2/backtests.py index 5cade849..29e565e7 100644 --- a/src/lithic/resources/auth_rules/v2/backtests.py +++ b/src/lithic/resources/auth_rules/v2/backtests.py @@ -9,7 +9,7 @@ from .... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -97,7 +97,7 @@ def create( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._post( - f"/v2/auth_rules/{auth_rule_token}/backtests", + path_template("/v2/auth_rules/{auth_rule_token}/backtests", auth_rule_token=auth_rule_token), body=maybe_transform( { "end": end, @@ -159,7 +159,11 @@ def retrieve( f"Expected a non-empty value for `auth_rule_backtest_token` but received {auth_rule_backtest_token!r}" ) return self._get( - f"/v2/auth_rules/{auth_rule_token}/backtests/{auth_rule_backtest_token}", + path_template( + "/v2/auth_rules/{auth_rule_token}/backtests/{auth_rule_backtest_token}", + auth_rule_token=auth_rule_token, + auth_rule_backtest_token=auth_rule_backtest_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -243,7 +247,7 @@ async def create( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._post( - f"/v2/auth_rules/{auth_rule_token}/backtests", + path_template("/v2/auth_rules/{auth_rule_token}/backtests", auth_rule_token=auth_rule_token), body=await async_maybe_transform( { "end": end, @@ -305,7 +309,11 @@ async def retrieve( f"Expected a non-empty value for `auth_rule_backtest_token` but received {auth_rule_backtest_token!r}" ) return await self._get( - f"/v2/auth_rules/{auth_rule_token}/backtests/{auth_rule_backtest_token}", + path_template( + "/v2/auth_rules/{auth_rule_token}/backtests/{auth_rule_backtest_token}", + auth_rule_token=auth_rule_token, + auth_rule_backtest_token=auth_rule_backtest_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/auth_rules/v2/v2.py b/src/lithic/resources/auth_rules/v2/v2.py index 3c8039b7..2a050870 100644 --- a/src/lithic/resources/auth_rules/v2/v2.py +++ b/src/lithic/resources/auth_rules/v2/v2.py @@ -10,7 +10,7 @@ from .... import _legacy_response from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, 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 .backtests import ( Backtests, AsyncBacktests, @@ -312,7 +312,7 @@ def retrieve( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._get( - f"/v2/auth_rules/{auth_rule_token}", + path_template("/v2/auth_rules/{auth_rule_token}", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -483,7 +483,7 @@ def update( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._patch( - f"/v2/auth_rules/{auth_rule_token}", + path_template("/v2/auth_rules/{auth_rule_token}", auth_rule_token=auth_rule_token), body=maybe_transform( { "account_tokens": account_tokens, @@ -610,7 +610,7 @@ def delete( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._delete( - f"/v2/auth_rules/{auth_rule_token}", + path_template("/v2/auth_rules/{auth_rule_token}", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -649,7 +649,7 @@ def draft( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._post( - f"/v2/auth_rules/{auth_rule_token}/draft", + path_template("/v2/auth_rules/{auth_rule_token}/draft", auth_rule_token=auth_rule_token), body=maybe_transform({"parameters": parameters}, v2_draft_params.V2DraftParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -766,7 +766,7 @@ def list_versions( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._get( - f"/v2/auth_rules/{auth_rule_token}/versions", + path_template("/v2/auth_rules/{auth_rule_token}/versions", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -800,7 +800,7 @@ def promote( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._post( - f"/v2/auth_rules/{auth_rule_token}/promote", + path_template("/v2/auth_rules/{auth_rule_token}/promote", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -843,7 +843,7 @@ def retrieve_features( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._get( - f"/v2/auth_rules/{auth_rule_token}/features", + path_template("/v2/auth_rules/{auth_rule_token}/features", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -904,7 +904,7 @@ def retrieve_report( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return self._get( - f"/v2/auth_rules/{auth_rule_token}/report", + path_template("/v2/auth_rules/{auth_rule_token}/report", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -1190,7 +1190,7 @@ async def retrieve( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._get( - f"/v2/auth_rules/{auth_rule_token}", + path_template("/v2/auth_rules/{auth_rule_token}", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1361,7 +1361,7 @@ async def update( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._patch( - f"/v2/auth_rules/{auth_rule_token}", + path_template("/v2/auth_rules/{auth_rule_token}", auth_rule_token=auth_rule_token), body=await async_maybe_transform( { "account_tokens": account_tokens, @@ -1488,7 +1488,7 @@ async def delete( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._delete( - f"/v2/auth_rules/{auth_rule_token}", + path_template("/v2/auth_rules/{auth_rule_token}", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1527,7 +1527,7 @@ async def draft( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._post( - f"/v2/auth_rules/{auth_rule_token}/draft", + path_template("/v2/auth_rules/{auth_rule_token}/draft", auth_rule_token=auth_rule_token), body=await async_maybe_transform({"parameters": parameters}, v2_draft_params.V2DraftParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -1644,7 +1644,7 @@ async def list_versions( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._get( - f"/v2/auth_rules/{auth_rule_token}/versions", + path_template("/v2/auth_rules/{auth_rule_token}/versions", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1678,7 +1678,7 @@ async def promote( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._post( - f"/v2/auth_rules/{auth_rule_token}/promote", + path_template("/v2/auth_rules/{auth_rule_token}/promote", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1721,7 +1721,7 @@ async def retrieve_features( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._get( - f"/v2/auth_rules/{auth_rule_token}/features", + path_template("/v2/auth_rules/{auth_rule_token}/features", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -1782,7 +1782,7 @@ async def retrieve_report( if not auth_rule_token: raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") return await self._get( - f"/v2/auth_rules/{auth_rule_token}/report", + path_template("/v2/auth_rules/{auth_rule_token}/report", auth_rule_token=auth_rule_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/lithic/resources/book_transfers.py b/src/lithic/resources/book_transfers.py index eeafcc0a..5addf008 100644 --- a/src/lithic/resources/book_transfers.py +++ b/src/lithic/resources/book_transfers.py @@ -16,7 +16,7 @@ book_transfer_reverse_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -203,7 +203,7 @@ def retrieve( f"Expected a non-empty value for `book_transfer_token` but received {book_transfer_token!r}" ) return self._get( - f"/v1/book_transfers/{book_transfer_token}", + path_template("/v1/book_transfers/{book_transfer_token}", book_transfer_token=book_transfer_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -338,7 +338,7 @@ def retry( f"Expected a non-empty value for `book_transfer_token` but received {book_transfer_token!r}" ) return self._post( - f"/v1/book_transfers/{book_transfer_token}/retry", + path_template("/v1/book_transfers/{book_transfer_token}/retry", book_transfer_token=book_transfer_token), body=maybe_transform({"retry_token": retry_token}, book_transfer_retry_params.BookTransferRetryParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -377,7 +377,7 @@ def reverse( f"Expected a non-empty value for `book_transfer_token` but received {book_transfer_token!r}" ) return self._post( - f"/v1/book_transfers/{book_transfer_token}/reverse", + path_template("/v1/book_transfers/{book_transfer_token}/reverse", book_transfer_token=book_transfer_token), body=maybe_transform({"memo": memo}, book_transfer_reverse_params.BookTransferReverseParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -562,7 +562,7 @@ async def retrieve( f"Expected a non-empty value for `book_transfer_token` but received {book_transfer_token!r}" ) return await self._get( - f"/v1/book_transfers/{book_transfer_token}", + path_template("/v1/book_transfers/{book_transfer_token}", book_transfer_token=book_transfer_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -697,7 +697,7 @@ async def retry( f"Expected a non-empty value for `book_transfer_token` but received {book_transfer_token!r}" ) return await self._post( - f"/v1/book_transfers/{book_transfer_token}/retry", + path_template("/v1/book_transfers/{book_transfer_token}/retry", book_transfer_token=book_transfer_token), body=await async_maybe_transform( {"retry_token": retry_token}, book_transfer_retry_params.BookTransferRetryParams ), @@ -738,7 +738,7 @@ async def reverse( f"Expected a non-empty value for `book_transfer_token` but received {book_transfer_token!r}" ) return await self._post( - f"/v1/book_transfers/{book_transfer_token}/reverse", + path_template("/v1/book_transfers/{book_transfer_token}/reverse", book_transfer_token=book_transfer_token), body=await async_maybe_transform({"memo": memo}, book_transfer_reverse_params.BookTransferReverseParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout diff --git a/src/lithic/resources/card_bulk_orders.py b/src/lithic/resources/card_bulk_orders.py index 7caaad9d..40c9d132 100644 --- a/src/lithic/resources/card_bulk_orders.py +++ b/src/lithic/resources/card_bulk_orders.py @@ -11,7 +11,7 @@ from .. import _legacy_response from ..types import card_bulk_order_list_params, card_bulk_order_create_params, card_bulk_order_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -122,7 +122,7 @@ def retrieve( if not bulk_order_token: raise ValueError(f"Expected a non-empty value for `bulk_order_token` but received {bulk_order_token!r}") return self._get( - f"/v1/card_bulk_orders/{bulk_order_token}", + path_template("/v1/card_bulk_orders/{bulk_order_token}", bulk_order_token=bulk_order_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -160,7 +160,7 @@ def update( if not bulk_order_token: raise ValueError(f"Expected a non-empty value for `bulk_order_token` but received {bulk_order_token!r}") return self._patch( - f"/v1/card_bulk_orders/{bulk_order_token}", + path_template("/v1/card_bulk_orders/{bulk_order_token}", bulk_order_token=bulk_order_token), body=maybe_transform({"status": status}, card_bulk_order_update_params.CardBulkOrderUpdateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -332,7 +332,7 @@ async def retrieve( if not bulk_order_token: raise ValueError(f"Expected a non-empty value for `bulk_order_token` but received {bulk_order_token!r}") return await self._get( - f"/v1/card_bulk_orders/{bulk_order_token}", + path_template("/v1/card_bulk_orders/{bulk_order_token}", bulk_order_token=bulk_order_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -370,7 +370,7 @@ async def update( if not bulk_order_token: raise ValueError(f"Expected a non-empty value for `bulk_order_token` but received {bulk_order_token!r}") return await self._patch( - f"/v1/card_bulk_orders/{bulk_order_token}", + path_template("/v1/card_bulk_orders/{bulk_order_token}", bulk_order_token=bulk_order_token), body=await async_maybe_transform( {"status": status}, card_bulk_order_update_params.CardBulkOrderUpdateParams ), diff --git a/src/lithic/resources/card_programs.py b/src/lithic/resources/card_programs.py index 8a9728d6..94bea5d2 100644 --- a/src/lithic/resources/card_programs.py +++ b/src/lithic/resources/card_programs.py @@ -7,7 +7,7 @@ from .. import _legacy_response from ..types import card_program_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -64,7 +64,7 @@ def retrieve( if not card_program_token: raise ValueError(f"Expected a non-empty value for `card_program_token` but received {card_program_token!r}") return self._get( - f"/v1/card_programs/{card_program_token}", + path_template("/v1/card_programs/{card_program_token}", card_program_token=card_program_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -171,7 +171,7 @@ async def retrieve( if not card_program_token: raise ValueError(f"Expected a non-empty value for `card_program_token` but received {card_program_token!r}") return await self._get( - f"/v1/card_programs/{card_program_token}", + path_template("/v1/card_programs/{card_program_token}", card_program_token=card_program_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/cards/balances.py b/src/lithic/resources/cards/balances.py index 44784aed..ca5b1699 100644 --- a/src/lithic/resources/cards/balances.py +++ b/src/lithic/resources/cards/balances.py @@ -9,7 +9,7 @@ from ... import _legacy_response from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform +from ..._utils import path_template, maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -75,7 +75,7 @@ def list( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._get_api_list( - f"/v1/cards/{card_token}/balances", + path_template("/v1/cards/{card_token}/balances", card_token=card_token), page=SyncSinglePage[FinancialAccountBalance], options=make_request_options( extra_headers=extra_headers, @@ -148,7 +148,7 @@ def list( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._get_api_list( - f"/v1/cards/{card_token}/balances", + path_template("/v1/cards/{card_token}/balances", card_token=card_token), page=AsyncSinglePage[FinancialAccountBalance], options=make_request_options( extra_headers=extra_headers, diff --git a/src/lithic/resources/cards/cards.py b/src/lithic/resources/cards/cards.py index 67842145..e627f240 100644 --- a/src/lithic/resources/cards/cards.py +++ b/src/lithic/resources/cards/cards.py @@ -29,7 +29,7 @@ card_convert_physical_params, ) from ..._types import NOT_GIVEN, Body, Omit, Query, Headers, NotGiven, Base64FileInput, 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 .balances import ( Balances, AsyncBalances, @@ -351,7 +351,7 @@ def retrieve( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._get( - f"/v1/cards/{card_token}", + path_template("/v1/cards/{card_token}", card_token=card_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -490,7 +490,7 @@ def update( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._patch( - f"/v1/cards/{card_token}", + path_template("/v1/cards/{card_token}", card_token=card_token), body=maybe_transform( { "comment": comment, @@ -654,7 +654,7 @@ def convert_physical( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._post( - f"/v1/cards/{card_token}/convert_physical", + path_template("/v1/cards/{card_token}/convert_physical", card_token=card_token), body=maybe_transform( { "shipping_address": shipping_address, @@ -914,7 +914,7 @@ def provision( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._post( - f"/v1/cards/{card_token}/provision", + path_template("/v1/cards/{card_token}/provision", card_token=card_token), body=maybe_transform( { "certificate": certificate, @@ -994,7 +994,7 @@ def reissue( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._post( - f"/v1/cards/{card_token}/reissue", + path_template("/v1/cards/{card_token}/reissue", card_token=card_token), body=maybe_transform( { "carrier": carrier, @@ -1084,7 +1084,7 @@ def renew( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._post( - f"/v1/cards/{card_token}/renew", + path_template("/v1/cards/{card_token}/renew", card_token=card_token), body=maybe_transform( { "shipping_address": shipping_address, @@ -1131,7 +1131,7 @@ def retrieve_spend_limits( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._get( - f"/v1/cards/{card_token}/spend_limits", + path_template("/v1/cards/{card_token}/spend_limits", card_token=card_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1225,7 +1225,7 @@ def web_provision( return cast( CardWebProvisionResponse, self._post( - f"/v1/cards/{card_token}/web_provision", + path_template("/v1/cards/{card_token}/web_provision", card_token=card_token), body=maybe_transform( { "client_device_id": client_device_id, @@ -1533,7 +1533,7 @@ async def retrieve( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return await self._get( - f"/v1/cards/{card_token}", + path_template("/v1/cards/{card_token}", card_token=card_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1672,7 +1672,7 @@ async def update( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return await self._patch( - f"/v1/cards/{card_token}", + path_template("/v1/cards/{card_token}", card_token=card_token), body=await async_maybe_transform( { "comment": comment, @@ -1836,7 +1836,7 @@ async def convert_physical( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return await self._post( - f"/v1/cards/{card_token}/convert_physical", + path_template("/v1/cards/{card_token}/convert_physical", card_token=card_token), body=await async_maybe_transform( { "shipping_address": shipping_address, @@ -2096,7 +2096,7 @@ async def provision( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return await self._post( - f"/v1/cards/{card_token}/provision", + path_template("/v1/cards/{card_token}/provision", card_token=card_token), body=await async_maybe_transform( { "certificate": certificate, @@ -2176,7 +2176,7 @@ async def reissue( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return await self._post( - f"/v1/cards/{card_token}/reissue", + path_template("/v1/cards/{card_token}/reissue", card_token=card_token), body=await async_maybe_transform( { "carrier": carrier, @@ -2266,7 +2266,7 @@ async def renew( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return await self._post( - f"/v1/cards/{card_token}/renew", + path_template("/v1/cards/{card_token}/renew", card_token=card_token), body=await async_maybe_transform( { "shipping_address": shipping_address, @@ -2313,7 +2313,7 @@ async def retrieve_spend_limits( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return await self._get( - f"/v1/cards/{card_token}/spend_limits", + path_template("/v1/cards/{card_token}/spend_limits", card_token=card_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -2407,7 +2407,7 @@ async def web_provision( return cast( CardWebProvisionResponse, await self._post( - f"/v1/cards/{card_token}/web_provision", + path_template("/v1/cards/{card_token}/web_provision", card_token=card_token), body=await async_maybe_transform( { "client_device_id": client_device_id, diff --git a/src/lithic/resources/cards/financial_transactions.py b/src/lithic/resources/cards/financial_transactions.py index bc97969b..a349baf6 100644 --- a/src/lithic/resources/cards/financial_transactions.py +++ b/src/lithic/resources/cards/financial_transactions.py @@ -10,7 +10,7 @@ from ... import _legacy_response from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform +from ..._utils import path_template, maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -73,7 +73,11 @@ def retrieve( f"Expected a non-empty value for `financial_transaction_token` but received {financial_transaction_token!r}" ) return self._get( - f"/v1/cards/{card_token}/financial_transactions/{financial_transaction_token}", + path_template( + "/v1/cards/{card_token}/financial_transactions/{financial_transaction_token}", + card_token=card_token, + financial_transaction_token=financial_transaction_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -131,7 +135,7 @@ def list( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._get_api_list( - f"/v1/cards/{card_token}/financial_transactions", + path_template("/v1/cards/{card_token}/financial_transactions", card_token=card_token), page=SyncSinglePage[FinancialTransaction], options=make_request_options( extra_headers=extra_headers, @@ -206,7 +210,11 @@ async def retrieve( f"Expected a non-empty value for `financial_transaction_token` but received {financial_transaction_token!r}" ) return await self._get( - f"/v1/cards/{card_token}/financial_transactions/{financial_transaction_token}", + path_template( + "/v1/cards/{card_token}/financial_transactions/{financial_transaction_token}", + card_token=card_token, + financial_transaction_token=financial_transaction_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -264,7 +272,7 @@ def list( if not card_token: raise ValueError(f"Expected a non-empty value for `card_token` but received {card_token!r}") return self._get_api_list( - f"/v1/cards/{card_token}/financial_transactions", + path_template("/v1/cards/{card_token}/financial_transactions", card_token=card_token), page=AsyncSinglePage[FinancialTransaction], options=make_request_options( extra_headers=extra_headers, diff --git a/src/lithic/resources/credit_products/extended_credit.py b/src/lithic/resources/credit_products/extended_credit.py index 7b006763..09c766d1 100644 --- a/src/lithic/resources/credit_products/extended_credit.py +++ b/src/lithic/resources/credit_products/extended_credit.py @@ -6,6 +6,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -63,7 +64,9 @@ def retrieve( f"Expected a non-empty value for `credit_product_token` but received {credit_product_token!r}" ) return self._get( - f"/v1/credit_products/{credit_product_token}/extended_credit", + path_template( + "/v1/credit_products/{credit_product_token}/extended_credit", credit_product_token=credit_product_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -119,7 +122,9 @@ async def retrieve( f"Expected a non-empty value for `credit_product_token` but received {credit_product_token!r}" ) return await self._get( - f"/v1/credit_products/{credit_product_token}/extended_credit", + path_template( + "/v1/credit_products/{credit_product_token}/extended_credit", credit_product_token=credit_product_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/credit_products/prime_rates.py b/src/lithic/resources/credit_products/prime_rates.py index 8c256481..a2802b97 100644 --- a/src/lithic/resources/credit_products/prime_rates.py +++ b/src/lithic/resources/credit_products/prime_rates.py @@ -9,7 +9,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -76,7 +76,9 @@ def create( f"Expected a non-empty value for `credit_product_token` but received {credit_product_token!r}" ) return self._post( - f"/v1/credit_products/{credit_product_token}/prime_rates", + path_template( + "/v1/credit_products/{credit_product_token}/prime_rates", credit_product_token=credit_product_token + ), body=maybe_transform( { "effective_date": effective_date, @@ -126,7 +128,9 @@ def retrieve( f"Expected a non-empty value for `credit_product_token` but received {credit_product_token!r}" ) return self._get( - f"/v1/credit_products/{credit_product_token}/prime_rates", + path_template( + "/v1/credit_products/{credit_product_token}/prime_rates", credit_product_token=credit_product_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -200,7 +204,9 @@ async def create( f"Expected a non-empty value for `credit_product_token` but received {credit_product_token!r}" ) return await self._post( - f"/v1/credit_products/{credit_product_token}/prime_rates", + path_template( + "/v1/credit_products/{credit_product_token}/prime_rates", credit_product_token=credit_product_token + ), body=await async_maybe_transform( { "effective_date": effective_date, @@ -250,7 +256,9 @@ async def retrieve( f"Expected a non-empty value for `credit_product_token` but received {credit_product_token!r}" ) return await self._get( - f"/v1/credit_products/{credit_product_token}/prime_rates", + path_template( + "/v1/credit_products/{credit_product_token}/prime_rates", credit_product_token=credit_product_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/lithic/resources/digital_card_art.py b/src/lithic/resources/digital_card_art.py index e42ac01b..f2d4ac2b 100644 --- a/src/lithic/resources/digital_card_art.py +++ b/src/lithic/resources/digital_card_art.py @@ -7,7 +7,7 @@ from .. import _legacy_response from ..types import digital_card_art_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -66,7 +66,9 @@ def retrieve( f"Expected a non-empty value for `digital_card_art_token` but received {digital_card_art_token!r}" ) return self._get( - f"/v1/digital_card_art/{digital_card_art_token}", + path_template( + "/v1/digital_card_art/{digital_card_art_token}", digital_card_art_token=digital_card_art_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -175,7 +177,9 @@ async def retrieve( f"Expected a non-empty value for `digital_card_art_token` but received {digital_card_art_token!r}" ) return await self._get( - f"/v1/digital_card_art/{digital_card_art_token}", + path_template( + "/v1/digital_card_art/{digital_card_art_token}", digital_card_art_token=digital_card_art_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/disputes.py b/src/lithic/resources/disputes.py index 6369b647..38946e06 100644 --- a/src/lithic/resources/disputes.py +++ b/src/lithic/resources/disputes.py @@ -17,7 +17,7 @@ dispute_initiate_evidence_upload_params, ) from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, FileTypes, 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -145,7 +145,7 @@ def retrieve( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return self._get( - f"/v1/disputes/{dispute_token}", + path_template("/v1/disputes/{dispute_token}", dispute_token=dispute_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -207,7 +207,7 @@ def update( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return self._patch( - f"/v1/disputes/{dispute_token}", + path_template("/v1/disputes/{dispute_token}", dispute_token=dispute_token), body=maybe_transform( { "amount": amount, @@ -331,7 +331,7 @@ def delete( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return self._delete( - f"/v1/disputes/{dispute_token}", + path_template("/v1/disputes/{dispute_token}", dispute_token=dispute_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -369,7 +369,11 @@ def delete_evidence( if not evidence_token: raise ValueError(f"Expected a non-empty value for `evidence_token` but received {evidence_token!r}") return self._delete( - f"/v1/disputes/{dispute_token}/evidences/{evidence_token}", + path_template( + "/v1/disputes/{dispute_token}/evidences/{evidence_token}", + dispute_token=dispute_token, + evidence_token=evidence_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -410,7 +414,7 @@ def initiate_evidence_upload( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return self._post( - f"/v1/disputes/{dispute_token}/evidences", + path_template("/v1/disputes/{dispute_token}/evidences", dispute_token=dispute_token), body=maybe_transform( {"filename": filename}, dispute_initiate_evidence_upload_params.DisputeInitiateEvidenceUploadParams ), @@ -465,7 +469,7 @@ def list_evidences( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return self._get_api_list( - f"/v1/disputes/{dispute_token}/evidences", + path_template("/v1/disputes/{dispute_token}/evidences", dispute_token=dispute_token), page=SyncCursorPage[DisputeEvidence], options=make_request_options( extra_headers=extra_headers, @@ -515,7 +519,11 @@ def retrieve_evidence( if not evidence_token: raise ValueError(f"Expected a non-empty value for `evidence_token` but received {evidence_token!r}") return self._get( - f"/v1/disputes/{dispute_token}/evidences/{evidence_token}", + path_template( + "/v1/disputes/{dispute_token}/evidences/{evidence_token}", + dispute_token=dispute_token, + evidence_token=evidence_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -661,7 +669,7 @@ async def retrieve( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return await self._get( - f"/v1/disputes/{dispute_token}", + path_template("/v1/disputes/{dispute_token}", dispute_token=dispute_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -723,7 +731,7 @@ async def update( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return await self._patch( - f"/v1/disputes/{dispute_token}", + path_template("/v1/disputes/{dispute_token}", dispute_token=dispute_token), body=await async_maybe_transform( { "amount": amount, @@ -847,7 +855,7 @@ async def delete( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return await self._delete( - f"/v1/disputes/{dispute_token}", + path_template("/v1/disputes/{dispute_token}", dispute_token=dispute_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -885,7 +893,11 @@ async def delete_evidence( if not evidence_token: raise ValueError(f"Expected a non-empty value for `evidence_token` but received {evidence_token!r}") return await self._delete( - f"/v1/disputes/{dispute_token}/evidences/{evidence_token}", + path_template( + "/v1/disputes/{dispute_token}/evidences/{evidence_token}", + dispute_token=dispute_token, + evidence_token=evidence_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -926,7 +938,7 @@ async def initiate_evidence_upload( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return await self._post( - f"/v1/disputes/{dispute_token}/evidences", + path_template("/v1/disputes/{dispute_token}/evidences", dispute_token=dispute_token), body=await async_maybe_transform( {"filename": filename}, dispute_initiate_evidence_upload_params.DisputeInitiateEvidenceUploadParams ), @@ -981,7 +993,7 @@ def list_evidences( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return self._get_api_list( - f"/v1/disputes/{dispute_token}/evidences", + path_template("/v1/disputes/{dispute_token}/evidences", dispute_token=dispute_token), page=AsyncCursorPage[DisputeEvidence], options=make_request_options( extra_headers=extra_headers, @@ -1031,7 +1043,11 @@ async def retrieve_evidence( if not evidence_token: raise ValueError(f"Expected a non-empty value for `evidence_token` but received {evidence_token!r}") return await self._get( - f"/v1/disputes/{dispute_token}/evidences/{evidence_token}", + path_template( + "/v1/disputes/{dispute_token}/evidences/{evidence_token}", + dispute_token=dispute_token, + evidence_token=evidence_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/disputes_v2.py b/src/lithic/resources/disputes_v2.py index f6433efa..e15667e8 100644 --- a/src/lithic/resources/disputes_v2.py +++ b/src/lithic/resources/disputes_v2.py @@ -10,7 +10,7 @@ from .. import _legacy_response from ..types import disputes_v2_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -67,7 +67,7 @@ def retrieve( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return self._get( - f"/v2/disputes/{dispute_token}", + path_template("/v2/disputes/{dispute_token}", dispute_token=dispute_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -195,7 +195,7 @@ async def retrieve( if not dispute_token: raise ValueError(f"Expected a non-empty value for `dispute_token` but received {dispute_token!r}") return await self._get( - f"/v2/disputes/{dispute_token}", + path_template("/v2/disputes/{dispute_token}", dispute_token=dispute_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/events/event_subscriptions.py b/src/lithic/resources/events/event_subscriptions.py index de49709b..f68f0cd8 100644 --- a/src/lithic/resources/events/event_subscriptions.py +++ b/src/lithic/resources/events/event_subscriptions.py @@ -6,6 +6,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -65,7 +66,11 @@ def resend( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._post( - f"/v1/events/{event_token}/event_subscriptions/{event_subscription_token}/resend", + path_template( + "/v1/events/{event_token}/event_subscriptions/{event_subscription_token}/resend", + event_token=event_token, + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -124,7 +129,11 @@ async def resend( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._post( - f"/v1/events/{event_token}/event_subscriptions/{event_subscription_token}/resend", + path_template( + "/v1/events/{event_token}/event_subscriptions/{event_subscription_token}/resend", + event_token=event_token, + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/events/events.py b/src/lithic/resources/events/events.py index 6583c851..984d63f4 100644 --- a/src/lithic/resources/events/events.py +++ b/src/lithic/resources/events/events.py @@ -11,7 +11,7 @@ from ... import _legacy_response from ...types import event_list_params, event_list_attempts_params from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given -from ..._utils import maybe_transform +from ..._utils import path_template, maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -93,7 +93,7 @@ def retrieve( if not event_token: raise ValueError(f"Expected a non-empty value for `event_token` but received {event_token!r}") return self._get( - f"/v1/events/{event_token}", + path_template("/v1/events/{event_token}", event_token=event_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -274,7 +274,7 @@ def list_attempts( if not event_token: raise ValueError(f"Expected a non-empty value for `event_token` but received {event_token!r}") return self._get_api_list( - f"/v1/events/{event_token}/attempts", + path_template("/v1/events/{event_token}/attempts", event_token=event_token), page=SyncCursorPage[MessageAttempt], options=make_request_options( extra_headers=extra_headers, @@ -367,7 +367,7 @@ async def retrieve( if not event_token: raise ValueError(f"Expected a non-empty value for `event_token` but received {event_token!r}") return await self._get( - f"/v1/events/{event_token}", + path_template("/v1/events/{event_token}", event_token=event_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -548,7 +548,7 @@ def list_attempts( if not event_token: raise ValueError(f"Expected a non-empty value for `event_token` but received {event_token!r}") return self._get_api_list( - f"/v1/events/{event_token}/attempts", + path_template("/v1/events/{event_token}/attempts", event_token=event_token), page=AsyncCursorPage[MessageAttempt], options=make_request_options( extra_headers=extra_headers, diff --git a/src/lithic/resources/events/subscriptions.py b/src/lithic/resources/events/subscriptions.py index 5e3f385f..96ad2287 100644 --- a/src/lithic/resources/events/subscriptions.py +++ b/src/lithic/resources/events/subscriptions.py @@ -10,7 +10,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -188,7 +188,9 @@ def retrieve( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._get( - f"/v1/event_subscriptions/{event_subscription_token}", + path_template( + "/v1/event_subscriptions/{event_subscription_token}", event_subscription_token=event_subscription_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -292,7 +294,9 @@ def update( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._patch( - f"/v1/event_subscriptions/{event_subscription_token}", + path_template( + "/v1/event_subscriptions/{event_subscription_token}", event_subscription_token=event_subscription_token + ), body=maybe_transform( { "url": url, @@ -389,7 +393,9 @@ def delete( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._delete( - f"/v1/event_subscriptions/{event_subscription_token}", + path_template( + "/v1/event_subscriptions/{event_subscription_token}", event_subscription_token=event_subscription_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -444,7 +450,10 @@ def list_attempts( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._get_api_list( - f"/v1/event_subscriptions/{event_subscription_token}/attempts", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/attempts", + event_subscription_token=event_subscription_token, + ), page=SyncCursorPage[MessageAttempt], options=make_request_options( extra_headers=extra_headers, @@ -502,7 +511,10 @@ def recover( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._post( - f"/v1/event_subscriptions/{event_subscription_token}/recover", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/recover", + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -560,7 +572,10 @@ def replay_missing( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._post( - f"/v1/event_subscriptions/{event_subscription_token}/replay_missing", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/replay_missing", + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -605,7 +620,10 @@ def retrieve_secret( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._get( - f"/v1/event_subscriptions/{event_subscription_token}/secret", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/secret", + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -642,7 +660,10 @@ def rotate_secret( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._post( - f"/v1/event_subscriptions/{event_subscription_token}/secret/rotate", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/secret/rotate", + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -734,7 +755,10 @@ def send_simulated_example( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._post( - f"/v1/simulate/event_subscriptions/{event_subscription_token}/send_example", + path_template( + "/v1/simulate/event_subscriptions/{event_subscription_token}/send_example", + event_subscription_token=event_subscription_token, + ), body=maybe_transform( {"event_type": event_type}, subscription_send_simulated_example_params.SubscriptionSendSimulatedExampleParams, @@ -902,7 +926,9 @@ async def retrieve( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._get( - f"/v1/event_subscriptions/{event_subscription_token}", + path_template( + "/v1/event_subscriptions/{event_subscription_token}", event_subscription_token=event_subscription_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1006,7 +1032,9 @@ async def update( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._patch( - f"/v1/event_subscriptions/{event_subscription_token}", + path_template( + "/v1/event_subscriptions/{event_subscription_token}", event_subscription_token=event_subscription_token + ), body=await async_maybe_transform( { "url": url, @@ -1103,7 +1131,9 @@ async def delete( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._delete( - f"/v1/event_subscriptions/{event_subscription_token}", + path_template( + "/v1/event_subscriptions/{event_subscription_token}", event_subscription_token=event_subscription_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1158,7 +1188,10 @@ def list_attempts( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return self._get_api_list( - f"/v1/event_subscriptions/{event_subscription_token}/attempts", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/attempts", + event_subscription_token=event_subscription_token, + ), page=AsyncCursorPage[MessageAttempt], options=make_request_options( extra_headers=extra_headers, @@ -1216,7 +1249,10 @@ async def recover( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._post( - f"/v1/event_subscriptions/{event_subscription_token}/recover", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/recover", + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -1274,7 +1310,10 @@ async def replay_missing( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._post( - f"/v1/event_subscriptions/{event_subscription_token}/replay_missing", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/replay_missing", + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -1319,7 +1358,10 @@ async def retrieve_secret( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._get( - f"/v1/event_subscriptions/{event_subscription_token}/secret", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/secret", + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1356,7 +1398,10 @@ async def rotate_secret( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._post( - f"/v1/event_subscriptions/{event_subscription_token}/secret/rotate", + path_template( + "/v1/event_subscriptions/{event_subscription_token}/secret/rotate", + event_subscription_token=event_subscription_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1448,7 +1493,10 @@ async def send_simulated_example( f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}" ) return await self._post( - f"/v1/simulate/event_subscriptions/{event_subscription_token}/send_example", + path_template( + "/v1/simulate/event_subscriptions/{event_subscription_token}/send_example", + event_subscription_token=event_subscription_token, + ), body=await async_maybe_transform( {"event_type": event_type}, subscription_send_simulated_example_params.SubscriptionSendSimulatedExampleParams, diff --git a/src/lithic/resources/external_bank_accounts/external_bank_accounts.py b/src/lithic/resources/external_bank_accounts/external_bank_accounts.py index 0a3ee175..f386c48d 100644 --- a/src/lithic/resources/external_bank_accounts/external_bank_accounts.py +++ b/src/lithic/resources/external_bank_accounts/external_bank_accounts.py @@ -19,7 +19,7 @@ external_bank_account_retry_micro_deposits_params, ) from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -404,7 +404,10 @@ def retrieve( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return self._get( - f"/v1/external_bank_accounts/{external_bank_account_token}", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}", + external_bank_account_token=external_bank_account_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -465,7 +468,10 @@ def update( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return self._patch( - f"/v1/external_bank_accounts/{external_bank_account_token}", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}", + external_bank_account_token=external_bank_account_token, + ), body=maybe_transform( { "address": address, @@ -581,7 +587,10 @@ def retry_micro_deposits( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return self._post( - f"/v1/external_bank_accounts/{external_bank_account_token}/retry_micro_deposits", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}/retry_micro_deposits", + external_bank_account_token=external_bank_account_token, + ), body=maybe_transform( {"financial_account_token": financial_account_token}, external_bank_account_retry_micro_deposits_params.ExternalBankAccountRetryMicroDepositsParams, @@ -621,7 +630,10 @@ def retry_prenote( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return self._post( - f"/v1/external_bank_accounts/{external_bank_account_token}/retry_prenote", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}/retry_prenote", + external_bank_account_token=external_bank_account_token, + ), body=maybe_transform( {"financial_account_token": financial_account_token}, external_bank_account_retry_prenote_params.ExternalBankAccountRetryPrenoteParams, @@ -660,7 +672,10 @@ def unpause( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return self._post( - f"/v1/external_bank_accounts/{external_bank_account_token}/unpause", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}/unpause", + external_bank_account_token=external_bank_account_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1026,7 +1041,10 @@ async def retrieve( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return await self._get( - f"/v1/external_bank_accounts/{external_bank_account_token}", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}", + external_bank_account_token=external_bank_account_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -1087,7 +1105,10 @@ async def update( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return await self._patch( - f"/v1/external_bank_accounts/{external_bank_account_token}", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}", + external_bank_account_token=external_bank_account_token, + ), body=await async_maybe_transform( { "address": address, @@ -1203,7 +1224,10 @@ async def retry_micro_deposits( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return await self._post( - f"/v1/external_bank_accounts/{external_bank_account_token}/retry_micro_deposits", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}/retry_micro_deposits", + external_bank_account_token=external_bank_account_token, + ), body=await async_maybe_transform( {"financial_account_token": financial_account_token}, external_bank_account_retry_micro_deposits_params.ExternalBankAccountRetryMicroDepositsParams, @@ -1243,7 +1267,10 @@ async def retry_prenote( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return await self._post( - f"/v1/external_bank_accounts/{external_bank_account_token}/retry_prenote", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}/retry_prenote", + external_bank_account_token=external_bank_account_token, + ), body=await async_maybe_transform( {"financial_account_token": financial_account_token}, external_bank_account_retry_prenote_params.ExternalBankAccountRetryPrenoteParams, @@ -1282,7 +1309,10 @@ async def unpause( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return await self._post( - f"/v1/external_bank_accounts/{external_bank_account_token}/unpause", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}/unpause", + external_bank_account_token=external_bank_account_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/external_bank_accounts/micro_deposits.py b/src/lithic/resources/external_bank_accounts/micro_deposits.py index ac74374b..44bcda79 100644 --- a/src/lithic/resources/external_bank_accounts/micro_deposits.py +++ b/src/lithic/resources/external_bank_accounts/micro_deposits.py @@ -8,7 +8,7 @@ from ... import _legacy_response from ..._types import Body, Query, Headers, NotGiven, 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -68,7 +68,10 @@ def create( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return self._post( - f"/v1/external_bank_accounts/{external_bank_account_token}/micro_deposits", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}/micro_deposits", + external_bank_account_token=external_bank_account_token, + ), body=maybe_transform( {"micro_deposits": micro_deposits}, micro_deposit_create_params.MicroDepositCreateParams ), @@ -128,7 +131,10 @@ async def create( f"Expected a non-empty value for `external_bank_account_token` but received {external_bank_account_token!r}" ) return await self._post( - f"/v1/external_bank_accounts/{external_bank_account_token}/micro_deposits", + path_template( + "/v1/external_bank_accounts/{external_bank_account_token}/micro_deposits", + external_bank_account_token=external_bank_account_token, + ), body=await async_maybe_transform( {"micro_deposits": micro_deposits}, micro_deposit_create_params.MicroDepositCreateParams ), diff --git a/src/lithic/resources/external_payments.py b/src/lithic/resources/external_payments.py index fd4cf371..2ad951b2 100644 --- a/src/lithic/resources/external_payments.py +++ b/src/lithic/resources/external_payments.py @@ -18,7 +18,7 @@ external_payment_reverse_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -135,7 +135,9 @@ def retrieve( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return self._get( - f"/v1/external_payments/{external_payment_token}", + path_template( + "/v1/external_payments/{external_payment_token}", external_payment_token=external_payment_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -258,7 +260,9 @@ def cancel( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return self._post( - f"/v1/external_payments/{external_payment_token}/cancel", + path_template( + "/v1/external_payments/{external_payment_token}/cancel", external_payment_token=external_payment_token + ), body=maybe_transform( { "effective_date": effective_date, @@ -302,7 +306,9 @@ def release( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return self._post( - f"/v1/external_payments/{external_payment_token}/release", + path_template( + "/v1/external_payments/{external_payment_token}/release", external_payment_token=external_payment_token + ), body=maybe_transform( { "effective_date": effective_date, @@ -346,7 +352,9 @@ def reverse( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return self._post( - f"/v1/external_payments/{external_payment_token}/reverse", + path_template( + "/v1/external_payments/{external_payment_token}/reverse", external_payment_token=external_payment_token + ), body=maybe_transform( { "effective_date": effective_date, @@ -391,7 +399,9 @@ def settle( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return self._post( - f"/v1/external_payments/{external_payment_token}/settle", + path_template( + "/v1/external_payments/{external_payment_token}/settle", external_payment_token=external_payment_token + ), body=maybe_transform( { "effective_date": effective_date, @@ -513,7 +523,9 @@ async def retrieve( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return await self._get( - f"/v1/external_payments/{external_payment_token}", + path_template( + "/v1/external_payments/{external_payment_token}", external_payment_token=external_payment_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -636,7 +648,9 @@ async def cancel( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return await self._post( - f"/v1/external_payments/{external_payment_token}/cancel", + path_template( + "/v1/external_payments/{external_payment_token}/cancel", external_payment_token=external_payment_token + ), body=await async_maybe_transform( { "effective_date": effective_date, @@ -680,7 +694,9 @@ async def release( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return await self._post( - f"/v1/external_payments/{external_payment_token}/release", + path_template( + "/v1/external_payments/{external_payment_token}/release", external_payment_token=external_payment_token + ), body=await async_maybe_transform( { "effective_date": effective_date, @@ -724,7 +740,9 @@ async def reverse( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return await self._post( - f"/v1/external_payments/{external_payment_token}/reverse", + path_template( + "/v1/external_payments/{external_payment_token}/reverse", external_payment_token=external_payment_token + ), body=await async_maybe_transform( { "effective_date": effective_date, @@ -769,7 +787,9 @@ async def settle( f"Expected a non-empty value for `external_payment_token` but received {external_payment_token!r}" ) return await self._post( - f"/v1/external_payments/{external_payment_token}/settle", + path_template( + "/v1/external_payments/{external_payment_token}/settle", external_payment_token=external_payment_token + ), body=await async_maybe_transform( { "effective_date": effective_date, diff --git a/src/lithic/resources/financial_accounts/balances.py b/src/lithic/resources/financial_accounts/balances.py index d280a862..fd039a45 100644 --- a/src/lithic/resources/financial_accounts/balances.py +++ b/src/lithic/resources/financial_accounts/balances.py @@ -9,7 +9,7 @@ from ... import _legacy_response from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform +from ..._utils import path_template, maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -77,7 +77,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/balances", + path_template( + "/v1/financial_accounts/{financial_account_token}/balances", + financial_account_token=financial_account_token, + ), page=SyncSinglePage[FinancialAccountBalance], options=make_request_options( extra_headers=extra_headers, @@ -152,7 +155,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/balances", + path_template( + "/v1/financial_accounts/{financial_account_token}/balances", + financial_account_token=financial_account_token, + ), page=AsyncSinglePage[FinancialAccountBalance], options=make_request_options( extra_headers=extra_headers, diff --git a/src/lithic/resources/financial_accounts/credit_configuration.py b/src/lithic/resources/financial_accounts/credit_configuration.py index 0ab13dbe..76c60412 100644 --- a/src/lithic/resources/financial_accounts/credit_configuration.py +++ b/src/lithic/resources/financial_accounts/credit_configuration.py @@ -6,7 +6,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -65,7 +65,10 @@ def retrieve( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get( - f"/v1/financial_accounts/{financial_account_token}/credit_configuration", + path_template( + "/v1/financial_accounts/{financial_account_token}/credit_configuration", + financial_account_token=financial_account_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -109,7 +112,10 @@ def update( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._patch( - f"/v1/financial_accounts/{financial_account_token}/credit_configuration", + path_template( + "/v1/financial_accounts/{financial_account_token}/credit_configuration", + financial_account_token=financial_account_token, + ), body=maybe_transform( { "auto_collection_configuration": auto_collection_configuration, @@ -175,7 +181,10 @@ async def retrieve( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._get( - f"/v1/financial_accounts/{financial_account_token}/credit_configuration", + path_template( + "/v1/financial_accounts/{financial_account_token}/credit_configuration", + financial_account_token=financial_account_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -219,7 +228,10 @@ async def update( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._patch( - f"/v1/financial_accounts/{financial_account_token}/credit_configuration", + path_template( + "/v1/financial_accounts/{financial_account_token}/credit_configuration", + financial_account_token=financial_account_token, + ), body=await async_maybe_transform( { "auto_collection_configuration": auto_collection_configuration, diff --git a/src/lithic/resources/financial_accounts/financial_accounts.py b/src/lithic/resources/financial_accounts/financial_accounts.py index 3c42d154..339ecca6 100644 --- a/src/lithic/resources/financial_accounts/financial_accounts.py +++ b/src/lithic/resources/financial_accounts/financial_accounts.py @@ -16,7 +16,7 @@ financial_account_register_account_number_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 .balances import ( Balances, AsyncBalances, @@ -202,7 +202,9 @@ def retrieve( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get( - f"/v1/financial_accounts/{financial_account_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}", financial_account_token=financial_account_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -238,7 +240,9 @@ def update( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._patch( - f"/v1/financial_accounts/{financial_account_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}", financial_account_token=financial_account_token + ), body=maybe_transform({"nickname": nickname}, financial_account_update_params.FinancialAccountUpdateParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -327,7 +331,10 @@ def register_account_number( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._post( - f"/v1/financial_accounts/{financial_account_token}/register_account_number", + path_template( + "/v1/financial_accounts/{financial_account_token}/register_account_number", + financial_account_token=financial_account_token, + ), body=maybe_transform( {"account_number": account_number}, financial_account_register_account_number_params.FinancialAccountRegisterAccountNumberParams, @@ -383,7 +390,10 @@ def update_status( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._post( - f"/v1/financial_accounts/{financial_account_token}/update_status", + path_template( + "/v1/financial_accounts/{financial_account_token}/update_status", + financial_account_token=financial_account_token, + ), body=maybe_transform( { "status": status, @@ -518,7 +528,9 @@ async def retrieve( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._get( - f"/v1/financial_accounts/{financial_account_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}", financial_account_token=financial_account_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -554,7 +566,9 @@ async def update( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._patch( - f"/v1/financial_accounts/{financial_account_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}", financial_account_token=financial_account_token + ), body=await async_maybe_transform( {"nickname": nickname}, financial_account_update_params.FinancialAccountUpdateParams ), @@ -645,7 +659,10 @@ async def register_account_number( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._post( - f"/v1/financial_accounts/{financial_account_token}/register_account_number", + path_template( + "/v1/financial_accounts/{financial_account_token}/register_account_number", + financial_account_token=financial_account_token, + ), body=await async_maybe_transform( {"account_number": account_number}, financial_account_register_account_number_params.FinancialAccountRegisterAccountNumberParams, @@ -701,7 +718,10 @@ async def update_status( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._post( - f"/v1/financial_accounts/{financial_account_token}/update_status", + path_template( + "/v1/financial_accounts/{financial_account_token}/update_status", + financial_account_token=financial_account_token, + ), body=await async_maybe_transform( { "status": status, diff --git a/src/lithic/resources/financial_accounts/financial_transactions.py b/src/lithic/resources/financial_accounts/financial_transactions.py index 3df4d47c..b8629de4 100644 --- a/src/lithic/resources/financial_accounts/financial_transactions.py +++ b/src/lithic/resources/financial_accounts/financial_transactions.py @@ -10,7 +10,7 @@ from ... import _legacy_response from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform +from ..._utils import path_template, maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -75,7 +75,11 @@ def retrieve( f"Expected a non-empty value for `financial_transaction_token` but received {financial_transaction_token!r}" ) return self._get( - f"/v1/financial_accounts/{financial_account_token}/financial_transactions/{financial_transaction_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}/financial_transactions/{financial_transaction_token}", + financial_account_token=financial_account_token, + financial_transaction_token=financial_transaction_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -135,7 +139,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/financial_transactions", + path_template( + "/v1/financial_accounts/{financial_account_token}/financial_transactions", + financial_account_token=financial_account_token, + ), page=SyncSinglePage[FinancialTransaction], options=make_request_options( extra_headers=extra_headers, @@ -212,7 +219,11 @@ async def retrieve( f"Expected a non-empty value for `financial_transaction_token` but received {financial_transaction_token!r}" ) return await self._get( - f"/v1/financial_accounts/{financial_account_token}/financial_transactions/{financial_transaction_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}/financial_transactions/{financial_transaction_token}", + financial_account_token=financial_account_token, + financial_transaction_token=financial_transaction_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -272,7 +283,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/financial_transactions", + path_template( + "/v1/financial_accounts/{financial_account_token}/financial_transactions", + financial_account_token=financial_account_token, + ), page=AsyncSinglePage[FinancialTransaction], options=make_request_options( extra_headers=extra_headers, diff --git a/src/lithic/resources/financial_accounts/interest_tier_schedule.py b/src/lithic/resources/financial_accounts/interest_tier_schedule.py index 6dae7a88..571597bb 100644 --- a/src/lithic/resources/financial_accounts/interest_tier_schedule.py +++ b/src/lithic/resources/financial_accounts/interest_tier_schedule.py @@ -9,7 +9,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -89,7 +89,10 @@ def create( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._post( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule", + financial_account_token=financial_account_token, + ), body=maybe_transform( { "credit_product_token": credit_product_token, @@ -137,7 +140,11 @@ def retrieve( if not effective_date: raise ValueError(f"Expected a non-empty value for `effective_date` but received {effective_date!r}") return self._get( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + financial_account_token=financial_account_token, + effective_date=effective_date, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -185,7 +192,11 @@ def update( if not effective_date: raise ValueError(f"Expected a non-empty value for `effective_date` but received {effective_date!r}") return self._put( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + financial_account_token=financial_account_token, + effective_date=effective_date, + ), body=maybe_transform( { "penalty_rates": penalty_rates, @@ -246,7 +257,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule", + financial_account_token=financial_account_token, + ), page=SyncSinglePage[InterestTierSchedule], options=make_request_options( extra_headers=extra_headers, @@ -311,7 +325,11 @@ def delete( if not effective_date: raise ValueError(f"Expected a non-empty value for `effective_date` but received {effective_date!r}") return self._delete( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + financial_account_token=financial_account_token, + effective_date=effective_date, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -383,7 +401,10 @@ async def create( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._post( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule", + financial_account_token=financial_account_token, + ), body=await async_maybe_transform( { "credit_product_token": credit_product_token, @@ -431,7 +452,11 @@ async def retrieve( if not effective_date: raise ValueError(f"Expected a non-empty value for `effective_date` but received {effective_date!r}") return await self._get( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + financial_account_token=financial_account_token, + effective_date=effective_date, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -479,7 +504,11 @@ async def update( if not effective_date: raise ValueError(f"Expected a non-empty value for `effective_date` but received {effective_date!r}") return await self._put( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + financial_account_token=financial_account_token, + effective_date=effective_date, + ), body=await async_maybe_transform( { "penalty_rates": penalty_rates, @@ -540,7 +569,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule", + financial_account_token=financial_account_token, + ), page=AsyncSinglePage[InterestTierSchedule], options=make_request_options( extra_headers=extra_headers, @@ -605,7 +637,11 @@ async def delete( if not effective_date: raise ValueError(f"Expected a non-empty value for `effective_date` but received {effective_date!r}") return await self._delete( - f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + path_template( + "/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", + financial_account_token=financial_account_token, + effective_date=effective_date, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/financial_accounts/loan_tape_configuration.py b/src/lithic/resources/financial_accounts/loan_tape_configuration.py index b07b5006..71989e71 100644 --- a/src/lithic/resources/financial_accounts/loan_tape_configuration.py +++ b/src/lithic/resources/financial_accounts/loan_tape_configuration.py @@ -6,6 +6,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -65,7 +66,10 @@ def retrieve( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get( - f"/v1/financial_accounts/{financial_account_token}/loan_tape_configuration", + path_template( + "/v1/financial_accounts/{financial_account_token}/loan_tape_configuration", + financial_account_token=financial_account_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -123,7 +127,10 @@ async def retrieve( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._get( - f"/v1/financial_accounts/{financial_account_token}/loan_tape_configuration", + path_template( + "/v1/financial_accounts/{financial_account_token}/loan_tape_configuration", + financial_account_token=financial_account_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/financial_accounts/loan_tapes.py b/src/lithic/resources/financial_accounts/loan_tapes.py index 96d40fe3..b53faa25 100644 --- a/src/lithic/resources/financial_accounts/loan_tapes.py +++ b/src/lithic/resources/financial_accounts/loan_tapes.py @@ -9,7 +9,7 @@ from ... import _legacy_response from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform +from ..._utils import path_template, maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -76,7 +76,11 @@ def retrieve( if not loan_tape_token: raise ValueError(f"Expected a non-empty value for `loan_tape_token` but received {loan_tape_token!r}") return self._get( - f"/v1/financial_accounts/{financial_account_token}/loan_tapes/{loan_tape_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}/loan_tapes/{loan_tape_token}", + financial_account_token=financial_account_token, + loan_tape_token=loan_tape_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -132,7 +136,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/loan_tapes", + path_template( + "/v1/financial_accounts/{financial_account_token}/loan_tapes", + financial_account_token=financial_account_token, + ), page=SyncCursorPage[LoanTape], options=make_request_options( extra_headers=extra_headers, @@ -209,7 +216,11 @@ async def retrieve( if not loan_tape_token: raise ValueError(f"Expected a non-empty value for `loan_tape_token` but received {loan_tape_token!r}") return await self._get( - f"/v1/financial_accounts/{financial_account_token}/loan_tapes/{loan_tape_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}/loan_tapes/{loan_tape_token}", + financial_account_token=financial_account_token, + loan_tape_token=loan_tape_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -265,7 +276,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/loan_tapes", + path_template( + "/v1/financial_accounts/{financial_account_token}/loan_tapes", + financial_account_token=financial_account_token, + ), page=AsyncCursorPage[LoanTape], options=make_request_options( extra_headers=extra_headers, diff --git a/src/lithic/resources/financial_accounts/statements/line_items.py b/src/lithic/resources/financial_accounts/statements/line_items.py index 64cc1d97..1a9b62b9 100644 --- a/src/lithic/resources/financial_accounts/statements/line_items.py +++ b/src/lithic/resources/financial_accounts/statements/line_items.py @@ -6,7 +6,7 @@ from .... import _legacy_response from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform +from ...._utils import path_template, maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -84,7 +84,11 @@ def list( if not statement_token: raise ValueError(f"Expected a non-empty value for `statement_token` but received {statement_token!r}") return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/statements/{statement_token}/line_items", + path_template( + "/v1/financial_accounts/{financial_account_token}/statements/{statement_token}/line_items", + financial_account_token=financial_account_token, + statement_token=statement_token, + ), page=SyncCursorPage[Data], options=make_request_options( extra_headers=extra_headers, @@ -170,7 +174,11 @@ def list( if not statement_token: raise ValueError(f"Expected a non-empty value for `statement_token` but received {statement_token!r}") return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/statements/{statement_token}/line_items", + path_template( + "/v1/financial_accounts/{financial_account_token}/statements/{statement_token}/line_items", + financial_account_token=financial_account_token, + statement_token=statement_token, + ), page=AsyncCursorPage[Data], options=make_request_options( extra_headers=extra_headers, diff --git a/src/lithic/resources/financial_accounts/statements/statements.py b/src/lithic/resources/financial_accounts/statements/statements.py index 08afc6ea..1767acb7 100644 --- a/src/lithic/resources/financial_accounts/statements/statements.py +++ b/src/lithic/resources/financial_accounts/statements/statements.py @@ -9,7 +9,7 @@ from .... import _legacy_response from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform +from ...._utils import path_template, maybe_transform from ...._compat import cached_property from .line_items import ( LineItems, @@ -88,7 +88,11 @@ def retrieve( if not statement_token: raise ValueError(f"Expected a non-empty value for `statement_token` but received {statement_token!r}") return self._get( - f"/v1/financial_accounts/{financial_account_token}/statements/{statement_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}/statements/{statement_token}", + financial_account_token=financial_account_token, + statement_token=statement_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -147,7 +151,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/statements", + path_template( + "/v1/financial_accounts/{financial_account_token}/statements", + financial_account_token=financial_account_token, + ), page=SyncCursorPage[Statement], options=make_request_options( extra_headers=extra_headers, @@ -229,7 +236,11 @@ async def retrieve( if not statement_token: raise ValueError(f"Expected a non-empty value for `statement_token` but received {statement_token!r}") return await self._get( - f"/v1/financial_accounts/{financial_account_token}/statements/{statement_token}", + path_template( + "/v1/financial_accounts/{financial_account_token}/statements/{statement_token}", + financial_account_token=financial_account_token, + statement_token=statement_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -288,7 +299,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/statements", + path_template( + "/v1/financial_accounts/{financial_account_token}/statements", + financial_account_token=financial_account_token, + ), page=AsyncCursorPage[Statement], options=make_request_options( extra_headers=extra_headers, diff --git a/src/lithic/resources/fraud/transactions.py b/src/lithic/resources/fraud/transactions.py index 1f3e6e2d..398cb7a3 100644 --- a/src/lithic/resources/fraud/transactions.py +++ b/src/lithic/resources/fraud/transactions.py @@ -8,7 +8,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -67,7 +67,7 @@ def retrieve( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return self._get( - f"/v1/fraud/transactions/{transaction_token}", + path_template("/v1/fraud/transactions/{transaction_token}", transaction_token=transaction_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -144,7 +144,7 @@ def report( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return self._post( - f"/v1/fraud/transactions/{transaction_token}", + path_template("/v1/fraud/transactions/{transaction_token}", transaction_token=transaction_token), body=maybe_transform( { "fraud_status": fraud_status, @@ -207,7 +207,7 @@ async def retrieve( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return await self._get( - f"/v1/fraud/transactions/{transaction_token}", + path_template("/v1/fraud/transactions/{transaction_token}", transaction_token=transaction_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -284,7 +284,7 @@ async def report( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return await self._post( - f"/v1/fraud/transactions/{transaction_token}", + path_template("/v1/fraud/transactions/{transaction_token}", transaction_token=transaction_token), body=await async_maybe_transform( { "fraud_status": fraud_status, diff --git a/src/lithic/resources/funding_events.py b/src/lithic/resources/funding_events.py index 44599b96..f8fdc141 100644 --- a/src/lithic/resources/funding_events.py +++ b/src/lithic/resources/funding_events.py @@ -7,7 +7,7 @@ from .. import _legacy_response from ..types import funding_event_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -67,7 +67,7 @@ def retrieve( f"Expected a non-empty value for `funding_event_token` but received {funding_event_token!r}" ) return self._get( - f"/v1/funding_events/{funding_event_token}", + path_template("/v1/funding_events/{funding_event_token}", funding_event_token=funding_event_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -155,7 +155,7 @@ def retrieve_details( f"Expected a non-empty value for `funding_event_token` but received {funding_event_token!r}" ) return self._get( - f"/v1/funding_events/{funding_event_token}/details", + path_template("/v1/funding_events/{funding_event_token}/details", funding_event_token=funding_event_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -211,7 +211,7 @@ async def retrieve( f"Expected a non-empty value for `funding_event_token` but received {funding_event_token!r}" ) return await self._get( - f"/v1/funding_events/{funding_event_token}", + path_template("/v1/funding_events/{funding_event_token}", funding_event_token=funding_event_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -299,7 +299,7 @@ async def retrieve_details( f"Expected a non-empty value for `funding_event_token` but received {funding_event_token!r}" ) return await self._get( - f"/v1/funding_events/{funding_event_token}/details", + path_template("/v1/funding_events/{funding_event_token}/details", funding_event_token=funding_event_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/holds.py b/src/lithic/resources/holds.py index 45d6c4ae..a52932d2 100644 --- a/src/lithic/resources/holds.py +++ b/src/lithic/resources/holds.py @@ -11,7 +11,7 @@ from .. import _legacy_response from ..types import hold_list_params, hold_void_params, hold_create_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -88,7 +88,10 @@ def create( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._post( - f"/v1/financial_accounts/{financial_account_token}/holds", + path_template( + "/v1/financial_accounts/{financial_account_token}/holds", + financial_account_token=financial_account_token, + ), body=maybe_transform( { "amount": amount, @@ -131,7 +134,7 @@ def retrieve( if not hold_token: raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}") return self._get( - f"/v1/holds/{hold_token}", + path_template("/v1/holds/{hold_token}", hold_token=hold_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -188,7 +191,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/holds", + path_template( + "/v1/financial_accounts/{financial_account_token}/holds", + financial_account_token=financial_account_token, + ), page=SyncCursorPage[Hold], options=make_request_options( extra_headers=extra_headers, @@ -241,7 +247,7 @@ def void( if not hold_token: raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}") return self._post( - f"/v1/holds/{hold_token}/void", + path_template("/v1/holds/{hold_token}/void", hold_token=hold_token), body=maybe_transform({"memo": memo}, hold_void_params.HoldVoidParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -316,7 +322,10 @@ async def create( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return await self._post( - f"/v1/financial_accounts/{financial_account_token}/holds", + path_template( + "/v1/financial_accounts/{financial_account_token}/holds", + financial_account_token=financial_account_token, + ), body=await async_maybe_transform( { "amount": amount, @@ -359,7 +368,7 @@ async def retrieve( if not hold_token: raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}") return await self._get( - f"/v1/holds/{hold_token}", + path_template("/v1/holds/{hold_token}", hold_token=hold_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -416,7 +425,10 @@ def list( f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" ) return self._get_api_list( - f"/v1/financial_accounts/{financial_account_token}/holds", + path_template( + "/v1/financial_accounts/{financial_account_token}/holds", + financial_account_token=financial_account_token, + ), page=AsyncCursorPage[Hold], options=make_request_options( extra_headers=extra_headers, @@ -469,7 +481,7 @@ async def void( if not hold_token: raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}") return await self._post( - f"/v1/holds/{hold_token}/void", + path_template("/v1/holds/{hold_token}/void", hold_token=hold_token), body=await async_maybe_transform({"memo": memo}, hold_void_params.HoldVoidParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout diff --git a/src/lithic/resources/management_operations.py b/src/lithic/resources/management_operations.py index ac148f05..c5f7ee5f 100644 --- a/src/lithic/resources/management_operations.py +++ b/src/lithic/resources/management_operations.py @@ -15,7 +15,7 @@ management_operation_reverse_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -168,7 +168,10 @@ def retrieve( f"Expected a non-empty value for `management_operation_token` but received {management_operation_token!r}" ) return self._get( - f"/v1/management_operations/{management_operation_token}", + path_template( + "/v1/management_operations/{management_operation_token}", + management_operation_token=management_operation_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -291,7 +294,10 @@ def reverse( f"Expected a non-empty value for `management_operation_token` but received {management_operation_token!r}" ) return self._post( - f"/v1/management_operations/{management_operation_token}/reverse", + path_template( + "/v1/management_operations/{management_operation_token}/reverse", + management_operation_token=management_operation_token, + ), body=maybe_transform( { "effective_date": effective_date, @@ -448,7 +454,10 @@ async def retrieve( f"Expected a non-empty value for `management_operation_token` but received {management_operation_token!r}" ) return await self._get( - f"/v1/management_operations/{management_operation_token}", + path_template( + "/v1/management_operations/{management_operation_token}", + management_operation_token=management_operation_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -571,7 +580,10 @@ async def reverse( f"Expected a non-empty value for `management_operation_token` but received {management_operation_token!r}" ) return await self._post( - f"/v1/management_operations/{management_operation_token}/reverse", + path_template( + "/v1/management_operations/{management_operation_token}/reverse", + management_operation_token=management_operation_token, + ), body=await async_maybe_transform( { "effective_date": effective_date, diff --git a/src/lithic/resources/network_programs.py b/src/lithic/resources/network_programs.py index 2b0fb8aa..5a8d9e14 100644 --- a/src/lithic/resources/network_programs.py +++ b/src/lithic/resources/network_programs.py @@ -10,7 +10,7 @@ from .. import _legacy_response from ..types import network_program_list_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import path_template, maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -69,7 +69,7 @@ def retrieve( f"Expected a non-empty value for `network_program_token` but received {network_program_token!r}" ) return self._get( - f"/v1/network_programs/{network_program_token}", + path_template("/v1/network_programs/{network_program_token}", network_program_token=network_program_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -179,7 +179,7 @@ async def retrieve( f"Expected a non-empty value for `network_program_token` but received {network_program_token!r}" ) return await self._get( - f"/v1/network_programs/{network_program_token}", + path_template("/v1/network_programs/{network_program_token}", network_program_token=network_program_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/payments.py b/src/lithic/resources/payments.py index afca033b..c6275973 100644 --- a/src/lithic/resources/payments.py +++ b/src/lithic/resources/payments.py @@ -19,7 +19,7 @@ payment_simulate_release_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -142,7 +142,7 @@ def retrieve( if not payment_token: raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return self._get( - f"/v1/payments/{payment_token}", + path_template("/v1/payments/{payment_token}", payment_token=payment_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -250,7 +250,7 @@ def retry( if not payment_token: raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return self._post( - f"/v1/payments/{payment_token}/retry", + path_template("/v1/payments/{payment_token}/retry", payment_token=payment_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -317,7 +317,7 @@ def return_( if not payment_token: raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return self._post( - f"/v1/payments/{payment_token}/return", + path_template("/v1/payments/{payment_token}/return", payment_token=payment_token), body=maybe_transform( { "financial_account_token": financial_account_token, @@ -389,7 +389,7 @@ def simulate_action( if not payment_token: raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return self._post( - f"/v1/simulate/payments/{payment_token}/action", + path_template("/v1/simulate/payments/{payment_token}/action", payment_token=payment_token), body=maybe_transform( { "event_type": event_type, @@ -647,7 +647,7 @@ async def retrieve( if not payment_token: raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return await self._get( - f"/v1/payments/{payment_token}", + path_template("/v1/payments/{payment_token}", payment_token=payment_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -755,7 +755,7 @@ async def retry( if not payment_token: raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return await self._post( - f"/v1/payments/{payment_token}/retry", + path_template("/v1/payments/{payment_token}/retry", payment_token=payment_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -822,7 +822,7 @@ async def return_( if not payment_token: raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return await self._post( - f"/v1/payments/{payment_token}/return", + path_template("/v1/payments/{payment_token}/return", payment_token=payment_token), body=await async_maybe_transform( { "financial_account_token": financial_account_token, @@ -894,7 +894,7 @@ async def simulate_action( if not payment_token: raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return await self._post( - f"/v1/simulate/payments/{payment_token}/action", + path_template("/v1/simulate/payments/{payment_token}/action", payment_token=payment_token), body=await async_maybe_transform( { "event_type": event_type, diff --git a/src/lithic/resources/reports/settlement/network_totals.py b/src/lithic/resources/reports/settlement/network_totals.py index 4d4f9172..46781eb9 100644 --- a/src/lithic/resources/reports/settlement/network_totals.py +++ b/src/lithic/resources/reports/settlement/network_totals.py @@ -10,7 +10,7 @@ from .... import _legacy_response from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform +from ...._utils import path_template, maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -69,7 +69,7 @@ def retrieve( if not token: raise ValueError(f"Expected a non-empty value for `token` but received {token!r}") return self._get( - f"/v1/reports/settlement/network_totals/{token}", + path_template("/v1/reports/settlement/network_totals/{token}", token=token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -213,7 +213,7 @@ async def retrieve( if not token: raise ValueError(f"Expected a non-empty value for `token` but received {token!r}") return await self._get( - f"/v1/reports/settlement/network_totals/{token}", + path_template("/v1/reports/settlement/network_totals/{token}", token=token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/reports/settlement/settlement.py b/src/lithic/resources/reports/settlement/settlement.py index 81a34b04..709b9224 100644 --- a/src/lithic/resources/reports/settlement/settlement.py +++ b/src/lithic/resources/reports/settlement/settlement.py @@ -9,7 +9,7 @@ from .... import _legacy_response from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ...._utils import maybe_transform +from ...._utils import path_template, maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -91,7 +91,7 @@ def list_details( if not report_date: raise ValueError(f"Expected a non-empty value for `report_date` but received {report_date!r}") return self._get_api_list( - f"/v1/reports/settlement/details/{report_date}", + path_template("/v1/reports/settlement/details/{report_date}", report_date=report_date), page=SyncCursorPage[SettlementDetail], options=make_request_options( extra_headers=extra_headers, @@ -137,7 +137,7 @@ def summary( if not report_date: raise ValueError(f"Expected a non-empty value for `report_date` but received {report_date!r}") return self._get( - f"/v1/reports/settlement/summary/{report_date}", + path_template("/v1/reports/settlement/summary/{report_date}", report_date=report_date), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -206,7 +206,7 @@ def list_details( if not report_date: raise ValueError(f"Expected a non-empty value for `report_date` but received {report_date!r}") return self._get_api_list( - f"/v1/reports/settlement/details/{report_date}", + path_template("/v1/reports/settlement/details/{report_date}", report_date=report_date), page=AsyncCursorPage[SettlementDetail], options=make_request_options( extra_headers=extra_headers, @@ -252,7 +252,7 @@ async def summary( if not report_date: raise ValueError(f"Expected a non-empty value for `report_date` but received {report_date!r}") return await self._get( - f"/v1/reports/settlement/summary/{report_date}", + path_template("/v1/reports/settlement/summary/{report_date}", report_date=report_date), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/three_ds/authentication.py b/src/lithic/resources/three_ds/authentication.py index f2a6c75c..a6d37209 100644 --- a/src/lithic/resources/three_ds/authentication.py +++ b/src/lithic/resources/three_ds/authentication.py @@ -8,7 +8,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -68,7 +68,10 @@ def retrieve( f"Expected a non-empty value for `three_ds_authentication_token` but received {three_ds_authentication_token!r}" ) return self._get( - f"/v1/three_ds_authentication/{three_ds_authentication_token}", + path_template( + "/v1/three_ds_authentication/{three_ds_authentication_token}", + three_ds_authentication_token=three_ds_authentication_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -229,7 +232,10 @@ async def retrieve( f"Expected a non-empty value for `three_ds_authentication_token` but received {three_ds_authentication_token!r}" ) return await self._get( - f"/v1/three_ds_authentication/{three_ds_authentication_token}", + path_template( + "/v1/three_ds_authentication/{three_ds_authentication_token}", + three_ds_authentication_token=three_ds_authentication_token, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/tokenizations.py b/src/lithic/resources/tokenizations.py index 4307e20f..34c28a48 100644 --- a/src/lithic/resources/tokenizations.py +++ b/src/lithic/resources/tokenizations.py @@ -16,7 +16,7 @@ tokenization_update_digital_card_art_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -73,7 +73,7 @@ def retrieve( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return self._get( - f"/v1/tokenizations/{tokenization_token}", + path_template("/v1/tokenizations/{tokenization_token}", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -188,7 +188,7 @@ def activate( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return self._post( - f"/v1/tokenizations/{tokenization_token}/activate", + path_template("/v1/tokenizations/{tokenization_token}/activate", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -230,7 +230,7 @@ def deactivate( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return self._post( - f"/v1/tokenizations/{tokenization_token}/deactivate", + path_template("/v1/tokenizations/{tokenization_token}/deactivate", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -271,7 +271,7 @@ def pause( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return self._post( - f"/v1/tokenizations/{tokenization_token}/pause", + path_template("/v1/tokenizations/{tokenization_token}/pause", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -318,7 +318,9 @@ def resend_activation_code( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return self._post( - f"/v1/tokenizations/{tokenization_token}/resend_activation_code", + path_template( + "/v1/tokenizations/{tokenization_token}/resend_activation_code", tokenization_token=tokenization_token + ), body=maybe_transform( {"activation_method_type": activation_method_type}, tokenization_resend_activation_code_params.TokenizationResendActivationCodeParams, @@ -433,7 +435,7 @@ def unpause( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return self._post( - f"/v1/tokenizations/{tokenization_token}/unpause", + path_template("/v1/tokenizations/{tokenization_token}/unpause", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -479,7 +481,9 @@ def update_digital_card_art( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return self._post( - f"/v1/tokenizations/{tokenization_token}/update_digital_card_art", + path_template( + "/v1/tokenizations/{tokenization_token}/update_digital_card_art", tokenization_token=tokenization_token + ), body=maybe_transform( {"digital_card_art_token": digital_card_art_token}, tokenization_update_digital_card_art_params.TokenizationUpdateDigitalCardArtParams, @@ -537,7 +541,7 @@ async def retrieve( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return await self._get( - f"/v1/tokenizations/{tokenization_token}", + path_template("/v1/tokenizations/{tokenization_token}", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -652,7 +656,7 @@ async def activate( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return await self._post( - f"/v1/tokenizations/{tokenization_token}/activate", + path_template("/v1/tokenizations/{tokenization_token}/activate", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -694,7 +698,7 @@ async def deactivate( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return await self._post( - f"/v1/tokenizations/{tokenization_token}/deactivate", + path_template("/v1/tokenizations/{tokenization_token}/deactivate", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -735,7 +739,7 @@ async def pause( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return await self._post( - f"/v1/tokenizations/{tokenization_token}/pause", + path_template("/v1/tokenizations/{tokenization_token}/pause", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -782,7 +786,9 @@ async def resend_activation_code( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return await self._post( - f"/v1/tokenizations/{tokenization_token}/resend_activation_code", + path_template( + "/v1/tokenizations/{tokenization_token}/resend_activation_code", tokenization_token=tokenization_token + ), body=await async_maybe_transform( {"activation_method_type": activation_method_type}, tokenization_resend_activation_code_params.TokenizationResendActivationCodeParams, @@ -897,7 +903,7 @@ async def unpause( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return await self._post( - f"/v1/tokenizations/{tokenization_token}/unpause", + path_template("/v1/tokenizations/{tokenization_token}/unpause", tokenization_token=tokenization_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -943,7 +949,9 @@ async def update_digital_card_art( if not tokenization_token: raise ValueError(f"Expected a non-empty value for `tokenization_token` but received {tokenization_token!r}") return await self._post( - f"/v1/tokenizations/{tokenization_token}/update_digital_card_art", + path_template( + "/v1/tokenizations/{tokenization_token}/update_digital_card_art", tokenization_token=tokenization_token + ), body=await async_maybe_transform( {"digital_card_art_token": digital_card_art_token}, tokenization_update_digital_card_art_params.TokenizationUpdateDigitalCardArtParams, diff --git a/src/lithic/resources/transactions/enhanced_commercial_data.py b/src/lithic/resources/transactions/enhanced_commercial_data.py index 10325b5d..9848f5db 100644 --- a/src/lithic/resources/transactions/enhanced_commercial_data.py +++ b/src/lithic/resources/transactions/enhanced_commercial_data.py @@ -6,6 +6,7 @@ from ... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -63,7 +64,9 @@ def retrieve( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return self._get( - f"/v1/transactions/{transaction_token}/enhanced_commercial_data", + path_template( + "/v1/transactions/{transaction_token}/enhanced_commercial_data", transaction_token=transaction_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -119,7 +122,9 @@ async def retrieve( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return await self._get( - f"/v1/transactions/{transaction_token}/enhanced_commercial_data", + path_template( + "/v1/transactions/{transaction_token}/enhanced_commercial_data", transaction_token=transaction_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/transactions/events/enhanced_commercial_data.py b/src/lithic/resources/transactions/events/enhanced_commercial_data.py index 5d48cdb8..7cbdee74 100644 --- a/src/lithic/resources/transactions/events/enhanced_commercial_data.py +++ b/src/lithic/resources/transactions/events/enhanced_commercial_data.py @@ -6,6 +6,7 @@ from .... import _legacy_response 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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -63,7 +64,7 @@ def retrieve( if not event_token: raise ValueError(f"Expected a non-empty value for `event_token` but received {event_token!r}") return self._get( - f"/v1/transactions/events/{event_token}/enhanced_commercial_data", + path_template("/v1/transactions/events/{event_token}/enhanced_commercial_data", event_token=event_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -119,7 +120,7 @@ async def retrieve( if not event_token: raise ValueError(f"Expected a non-empty value for `event_token` but received {event_token!r}") return await self._get( - f"/v1/transactions/events/{event_token}/enhanced_commercial_data", + path_template("/v1/transactions/events/{event_token}/enhanced_commercial_data", event_token=event_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/resources/transactions/transactions.py b/src/lithic/resources/transactions/transactions.py index 9a7c7af7..b1129484 100644 --- a/src/lithic/resources/transactions/transactions.py +++ b/src/lithic/resources/transactions/transactions.py @@ -22,7 +22,7 @@ transaction_simulate_credit_authorization_advice_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 to_streamed_response_wrapper, async_to_streamed_response_wrapper @@ -115,7 +115,7 @@ def retrieve( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return self._get( - f"/v1/transactions/{transaction_token}", + path_template("/v1/transactions/{transaction_token}", transaction_token=transaction_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -230,7 +230,9 @@ def expire_authorization( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return self._post( - f"/v1/transactions/{transaction_token}/expire_authorization", + path_template( + "/v1/transactions/{transaction_token}/expire_authorization", transaction_token=transaction_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -816,7 +818,7 @@ async def retrieve( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return await self._get( - f"/v1/transactions/{transaction_token}", + path_template("/v1/transactions/{transaction_token}", transaction_token=transaction_token), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -931,7 +933,9 @@ async def expire_authorization( if not transaction_token: raise ValueError(f"Expected a non-empty value for `transaction_token` but received {transaction_token!r}") return await self._post( - f"/v1/transactions/{transaction_token}/expire_authorization", + path_template( + "/v1/transactions/{transaction_token}/expire_authorization", transaction_token=transaction_token + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/types/auth_rules/conditional_authorization_action_parameters.py b/src/lithic/types/auth_rules/conditional_authorization_action_parameters.py index a322a14a..6606f238 100644 --- a/src/lithic/types/auth_rules/conditional_authorization_action_parameters.py +++ b/src/lithic/types/auth_rules/conditional_authorization_action_parameters.py @@ -31,6 +31,10 @@ class Condition(BaseModel): "WALLET_TYPE", "TRANSACTION_INITIATOR", "ADDRESS_MATCH", + "SERVICE_LOCATION_STATE", + "SERVICE_LOCATION_POSTAL_CODE", + "CARD_AGE", + "ACCOUNT_AGE", ] """The attribute to target. @@ -86,6 +90,17 @@ class Condition(BaseModel): - `ADDRESS_MATCH`: Lithic's evaluation result comparing transaction's address data with the cardholder KYC data if it exists. Valid values are `MATCH`, `MATCH_ADDRESS_ONLY`, `MATCH_ZIP_ONLY`,`MISMATCH`,`NOT_PRESENT`. + - `SERVICE_LOCATION_STATE`: The state/province code (ISO 3166-2) where the + cardholder received the service, e.g. "NY". When a service location is present + in the network data, the service location state is used. Otherwise, falls back + to the card acceptor state. + - `SERVICE_LOCATION_POSTAL_CODE`: The postal code where the cardholder received + the service, e.g. "10001". When a service location is present in the network + data, the service location postal code is used. Otherwise, falls back to the + card acceptor postal code. + - `CARD_AGE`: The age of the card in seconds at the time of the authorization. + - `ACCOUNT_AGE`: The age of the account holder's account in seconds at the time + of the authorization. """ operation: ConditionalOperation diff --git a/src/lithic/types/auth_rules/conditional_authorization_action_parameters_param.py b/src/lithic/types/auth_rules/conditional_authorization_action_parameters_param.py index 04eee746..a04adbc4 100644 --- a/src/lithic/types/auth_rules/conditional_authorization_action_parameters_param.py +++ b/src/lithic/types/auth_rules/conditional_authorization_action_parameters_param.py @@ -34,6 +34,10 @@ class Condition(TypedDict, total=False): "WALLET_TYPE", "TRANSACTION_INITIATOR", "ADDRESS_MATCH", + "SERVICE_LOCATION_STATE", + "SERVICE_LOCATION_POSTAL_CODE", + "CARD_AGE", + "ACCOUNT_AGE", ] ] """The attribute to target. @@ -90,6 +94,17 @@ class Condition(TypedDict, total=False): - `ADDRESS_MATCH`: Lithic's evaluation result comparing transaction's address data with the cardholder KYC data if it exists. Valid values are `MATCH`, `MATCH_ADDRESS_ONLY`, `MATCH_ZIP_ONLY`,`MISMATCH`,`NOT_PRESENT`. + - `SERVICE_LOCATION_STATE`: The state/province code (ISO 3166-2) where the + cardholder received the service, e.g. "NY". When a service location is present + in the network data, the service location state is used. Otherwise, falls back + to the card acceptor state. + - `SERVICE_LOCATION_POSTAL_CODE`: The postal code where the cardholder received + the service, e.g. "10001". When a service location is present in the network + data, the service location postal code is used. Otherwise, falls back to the + card acceptor postal code. + - `CARD_AGE`: The age of the card in seconds at the time of the authorization. + - `ACCOUNT_AGE`: The age of the account holder's account in seconds at the time + of the authorization. """ operation: Required[ConditionalOperation] diff --git a/src/lithic/types/card_authorization_approval_request_webhook_event.py b/src/lithic/types/card_authorization_approval_request_webhook_event.py index 29d1d285..e1341b40 100644 --- a/src/lithic/types/card_authorization_approval_request_webhook_event.py +++ b/src/lithic/types/card_authorization_approval_request_webhook_event.py @@ -4,10 +4,10 @@ from datetime import datetime from typing_extensions import Literal +from .shared import merchant from .._models import BaseModel from .token_info import TokenInfo from .shared.currency import Currency -from .shared.merchant import Merchant from .cardholder_authentication import CardholderAuthentication __all__ = [ @@ -19,6 +19,8 @@ "AmountsSettlement", "Avs", "Card", + "Merchant", + "ServiceLocation", "FleetInfo", "LatestChallenge", "NetworkSpecificData", @@ -141,6 +143,40 @@ class Card(BaseModel): type: Optional[Literal["SINGLE_USE", "MERCHANT_LOCKED", "UNLOCKED", "PHYSICAL", "DIGITAL_WALLET", "VIRTUAL"]] = None +class Merchant(merchant.Merchant): + """Merchant information including full location details.""" + + phone_number: Optional[str] = None + """Phone number of card acceptor.""" + + postal_code: Optional[str] = None + """Postal code of card acceptor.""" + + street_address: Optional[str] = None + """Street address of card acceptor.""" + + +class ServiceLocation(BaseModel): + """ + Where the cardholder received the service, when different from the card acceptor location. This is populated from network data elements such as Mastercard DE-122 SE1 SF9-14 and Visa F34 DS02. + """ + + city: Optional[str] = None + """City of service location.""" + + country: Optional[str] = None + """Country code of service location, ISO 3166-1 alpha-3.""" + + postal_code: Optional[str] = None + """Postal code of service location.""" + + state: Optional[str] = None + """State/province code of service location, ISO 3166-2.""" + + street_address: Optional[str] = None + """Street address of service location.""" + + class FleetInfo(BaseModel): """ Optional Object containing information if the Card is a part of a Fleet managed program @@ -412,6 +448,7 @@ class CardAuthorizationApprovalRequestWebhookEvent(BaseModel): event_type: Literal["card_authorization.approval_request"] merchant: Merchant + """Merchant information including full location details.""" merchant_amount: int """Deprecated, use `amounts`. @@ -426,6 +463,13 @@ class CardAuthorizationApprovalRequestWebhookEvent(BaseModel): merchant_currency: str """3-character alphabetic ISO 4217 code for the local currency of the transaction.""" + service_location: Optional[ServiceLocation] = None + """ + Where the cardholder received the service, when different from the card acceptor + location. This is populated from network data elements such as Mastercard DE-122 + SE1 SF9-14 and Visa F34 DS02. + """ + settled_amount: int """Deprecated, use `amounts`. diff --git a/src/lithic/types/payment.py b/src/lithic/types/payment.py index 28463417..d9788781 100644 --- a/src/lithic/types/payment.py +++ b/src/lithic/types/payment.py @@ -157,6 +157,12 @@ class MethodAttributesACHMethodAttributes(BaseModel): company_id: Optional[str] = None """Company ID for the ACH transaction""" + override_company_name: Optional[str] = None + """Value to override the configured company name with. + + Can only be used if allowed to override + """ + receipt_routing_number: Optional[str] = None """Receipt routing number""" diff --git a/src/lithic/types/transaction.py b/src/lithic/types/transaction.py index 6424a3c2..a12e94df 100644 --- a/src/lithic/types/transaction.py +++ b/src/lithic/types/transaction.py @@ -4,10 +4,10 @@ from datetime import datetime from typing_extensions import Literal +from .shared import merchant from .._models import BaseModel from .token_info import TokenInfo from .shared.currency import Currency -from .shared.merchant import Merchant from .cardholder_authentication import CardholderAuthentication __all__ = [ @@ -18,9 +18,11 @@ "AmountsMerchant", "AmountsSettlement", "Avs", + "Merchant", "Pos", "PosEntryMode", "PosTerminal", + "ServiceLocation", "Event", "EventAmounts", "EventAmountsCardholder", @@ -98,6 +100,19 @@ class Avs(BaseModel): """Cardholder ZIP code""" +class Merchant(merchant.Merchant): + """Merchant information including full location details.""" + + phone_number: Optional[str] = None + """Phone number of card acceptor.""" + + postal_code: Optional[str] = None + """Postal code of card acceptor.""" + + street_address: Optional[str] = None + """Street address of card acceptor.""" + + class PosEntryMode(BaseModel): card: Literal["NOT_PRESENT", "PREAUTHORIZED", "PRESENT", "UNKNOWN"] """Card presence indicator""" @@ -206,6 +221,27 @@ class Pos(BaseModel): terminal: PosTerminal +class ServiceLocation(BaseModel): + """ + Where the cardholder received the service, when different from the card acceptor location. This is populated from network data elements such as Mastercard DE-122 SE1 SF9-14 and Visa F34 DS02. + """ + + city: Optional[str] = None + """City of service location.""" + + country: Optional[str] = None + """Country code of service location, ISO 3166-1 alpha-3.""" + + postal_code: Optional[str] = None + """Postal code of service location.""" + + state: Optional[str] = None + """State/province code of service location, ISO 3166-2.""" + + street_address: Optional[str] = None + """Street address of service location.""" + + class EventAmountsCardholder(BaseModel): amount: int """Amount of the event in the cardholder billing currency.""" @@ -667,6 +703,7 @@ class Transaction(BaseModel): financial_account_token: Optional[str] = None merchant: Merchant + """Merchant information including full location details.""" merchant_amount: Optional[int] = None """Analogous to the 'amount', but in the merchant currency.""" @@ -723,6 +760,13 @@ class Transaction(BaseModel): "USER_TRANSACTION_LIMIT", ] + service_location: Optional[ServiceLocation] = None + """ + Where the cardholder received the service, when different from the card acceptor + location. This is populated from network data elements such as Mastercard DE-122 + SE1 SF9-14 and Visa F34 DS02. + """ + settled_amount: int """The settled amount of the transaction in the settlement currency.""" diff --git a/tests/test_utils/test_path.py b/tests/test_utils/test_path.py new file mode 100644 index 00000000..72f4fe0a --- /dev/null +++ b/tests/test_utils/test_path.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +from typing import Any + +import pytest + +from lithic._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)