diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 6d78745..091cfb1 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.9.0"
+ ".": "0.10.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 8601088..7e70f72 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 22
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/fragment-foundries-inc-dash%2Ffragment-0b499e34e128eee284c8b3d28d431f0521e747a9d573571b57b59c2dca2aac6e.yml
-openapi_spec_hash: c50d64859d14067d66dc02c0da86184c
-config_hash: 452389671401acf58c5429a09ae573db
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/fragment-foundries-inc-dash%2Ffragment-8472a9bd15eaa5b8aa9c12513d02b06ae385d06dd48e94a23f121678981de98a.yml
+openapi_spec_hash: 4c42faa5ab6443bab546568adc330b7a
+config_hash: 8e4b2d3ac55a0b2cdecfba99a1925e6f
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ef5cf99..383e52e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,28 @@
# Changelog
+## 0.10.0 (2026-04-13)
+
+Full Changelog: [v0.9.0...v0.10.0](https://github.com/fragment-dev/fragment-py/compare/v0.9.0...v0.10.0)
+
+### Features
+
+* **api:** update SDK from prod (511af1bcd4001be60c589fed1d05a5814e416679) ([e2ce984](https://github.com/fragment-dev/fragment-py/commit/e2ce984d3cadaf39400d35ae5d35d464027dca54))
+* **api:** update SDK from prod (523b1fdd6cc6b5732ccdad5095c21f69fe1f7489) ([ea85617](https://github.com/fragment-dev/fragment-py/commit/ea85617c004e54e4a27abf4c8a5e585d17256d7c))
+* **api:** update SDK from prod (5cede0854eb141955854b7a9d3eb0e07a9588e3c) ([67481e4](https://github.com/fragment-dev/fragment-py/commit/67481e45971c9e704986c425b42b4a9938b45746))
+* **api:** update SDK from prod (729db28098a20ebc22e879a2cd1c6ad860f9ce4c) ([1d1b5d0](https://github.com/fragment-dev/fragment-py/commit/1d1b5d0b74975f2505475ca8167176680eff0655))
+* **api:** update SDK from prod (8051461980fb65468797d0b82dfa42dee9014004) ([25512da](https://github.com/fragment-dev/fragment-py/commit/25512da8089db4f3be50174a77373390fa29c52c))
+* **api:** update SDK from prod (a5eb093078fe5947a299bccafd30a0c7f2e90790) ([fc27b30](https://github.com/fragment-dev/fragment-py/commit/fc27b304c5dae27cb485853ad80c55b3c1392df0))
+* **api:** update SDK from prod (b3080493fb6bb118abdd03644b9ef6f59d417a3c) ([cd9337f](https://github.com/fragment-dev/fragment-py/commit/cd9337fbe43c0c5e6ed9ec1ef4c6db5bbf270403))
+* **api:** update SDK from prod (b8f6f1940acd3d10fc17aaeb59cd75281f3c6436) ([dca29fc](https://github.com/fragment-dev/fragment-py/commit/dca29fcd235fe6c110efcdf9042fe012d06ce17e))
+* **api:** update SDK from prod (d8f41b559592a1a8c68c0c40fdb773aa6e53795e) ([9bd565e](https://github.com/fragment-dev/fragment-py/commit/9bd565e3cee12d961291d7b4641195045097f7c9))
+* **api:** update SDK from prod (e1ebb9e4d62034855202a8ff99690880c072d953) ([4de3417](https://github.com/fragment-dev/fragment-py/commit/4de3417d2e14d337dc6bbd9f809c4bc6f624015b))
+
+
+### Bug Fixes
+
+* **client:** preserve hardcoded query params when merging with user params ([dd8e3f1](https://github.com/fragment-dev/fragment-py/commit/dd8e3f1966650b7cb4043f377c4fcf9b30e188ba))
+* ensure file data are only sent as 1 parameter ([b244d50](https://github.com/fragment-dev/fragment-py/commit/b244d5004f5f7fb0ba13745581e47e4bb84a67e4))
+
## 0.9.0 (2026-03-27)
Full Changelog: [v0.8.0...v0.9.0](https://github.com/fragment-dev/fragment-py/compare/v0.8.0...v0.9.0)
diff --git a/api.md b/api.md
index f444e32..a140d9b 100644
--- a/api.md
+++ b/api.md
@@ -81,8 +81,8 @@ from fragment.types import (
Transaction,
TransactionCreateResponse,
TransactionRetrieveResponse,
+ TransactionUpdateResponse,
TransactionListResponse,
- TransactionCreateAllocationsResponse,
TransactionListHistoryResponse,
TransactionSearchResponse,
TransactionSearchAllocationsResponse,
@@ -93,8 +93,8 @@ Methods:
- client.transactions.create(\*\*params) -> TransactionCreateResponse
- client.transactions.retrieve(transaction_ref) -> TransactionRetrieveResponse
+- client.transactions.update(transaction_ref, \*\*params) -> TransactionUpdateResponse
- client.transactions.list(\*\*params) -> TransactionListResponse
-- client.transactions.create_allocations(transaction_ref, \*\*params) -> TransactionCreateAllocationsResponse
- client.transactions.list_history(transaction_ref) -> TransactionListHistoryResponse
- client.transactions.search(\*\*params) -> TransactionSearchResponse
- client.transactions.search_allocations(\*\*params) -> TransactionSearchAllocationsResponse
diff --git a/pyproject.toml b/pyproject.toml
index 06b2946..67a8a18 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "fragment-py"
-version = "0.9.0"
+version = "0.10.0"
description = "The official Python library for the fragment API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/fragment/_base_client.py b/src/fragment/_base_client.py
index 57ac0fb..a78c425 100644
--- a/src/fragment/_base_client.py
+++ b/src/fragment/_base_client.py
@@ -540,6 +540,10 @@ def _build_request(
files = cast(HttpxRequestFiles, ForceMultipartDict())
prepared_url = self._prepare_url(options.url)
+ # preserve hard-coded query params from the url
+ if params and prepared_url.query:
+ params = {**dict(prepared_url.params.items()), **params}
+ prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0])
if "_" in prepared_url.host:
# work around https://github.com/encode/httpx/discussions/2880
kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")}
diff --git a/src/fragment/_client.py b/src/fragment/_client.py
index d91fcb0..a8932e4 100644
--- a/src/fragment/_client.py
+++ b/src/fragment/_client.py
@@ -113,6 +113,7 @@ def __init__(
@cached_property
def external_accounts(self) -> ExternalAccountsResource:
+ """External account management operations"""
from .resources.external_accounts import ExternalAccountsResource
return ExternalAccountsResource(self)
@@ -147,6 +148,7 @@ def transactions(self) -> TransactionsResource:
@cached_property
def users(self) -> UsersResource:
+ """User management operations"""
from .resources.users import UsersResource
return UsersResource(self)
@@ -342,6 +344,7 @@ def __init__(
@cached_property
def external_accounts(self) -> AsyncExternalAccountsResource:
+ """External account management operations"""
from .resources.external_accounts import AsyncExternalAccountsResource
return AsyncExternalAccountsResource(self)
@@ -376,6 +379,7 @@ def transactions(self) -> AsyncTransactionsResource:
@cached_property
def users(self) -> AsyncUsersResource:
+ """User management operations"""
from .resources.users import AsyncUsersResource
return AsyncUsersResource(self)
@@ -518,6 +522,7 @@ def __init__(self, client: Fragment) -> None:
@cached_property
def external_accounts(self) -> external_accounts.ExternalAccountsResourceWithRawResponse:
+ """External account management operations"""
from .resources.external_accounts import ExternalAccountsResourceWithRawResponse
return ExternalAccountsResourceWithRawResponse(self._client.external_accounts)
@@ -552,6 +557,7 @@ def transactions(self) -> transactions.TransactionsResourceWithRawResponse:
@cached_property
def users(self) -> users.UsersResourceWithRawResponse:
+ """User management operations"""
from .resources.users import UsersResourceWithRawResponse
return UsersResourceWithRawResponse(self._client.users)
@@ -565,6 +571,7 @@ def __init__(self, client: AsyncFragment) -> None:
@cached_property
def external_accounts(self) -> external_accounts.AsyncExternalAccountsResourceWithRawResponse:
+ """External account management operations"""
from .resources.external_accounts import AsyncExternalAccountsResourceWithRawResponse
return AsyncExternalAccountsResourceWithRawResponse(self._client.external_accounts)
@@ -599,6 +606,7 @@ def transactions(self) -> transactions.AsyncTransactionsResourceWithRawResponse:
@cached_property
def users(self) -> users.AsyncUsersResourceWithRawResponse:
+ """User management operations"""
from .resources.users import AsyncUsersResourceWithRawResponse
return AsyncUsersResourceWithRawResponse(self._client.users)
@@ -612,6 +620,7 @@ def __init__(self, client: Fragment) -> None:
@cached_property
def external_accounts(self) -> external_accounts.ExternalAccountsResourceWithStreamingResponse:
+ """External account management operations"""
from .resources.external_accounts import ExternalAccountsResourceWithStreamingResponse
return ExternalAccountsResourceWithStreamingResponse(self._client.external_accounts)
@@ -646,6 +655,7 @@ def transactions(self) -> transactions.TransactionsResourceWithStreamingResponse
@cached_property
def users(self) -> users.UsersResourceWithStreamingResponse:
+ """User management operations"""
from .resources.users import UsersResourceWithStreamingResponse
return UsersResourceWithStreamingResponse(self._client.users)
@@ -659,6 +669,7 @@ def __init__(self, client: AsyncFragment) -> None:
@cached_property
def external_accounts(self) -> external_accounts.AsyncExternalAccountsResourceWithStreamingResponse:
+ """External account management operations"""
from .resources.external_accounts import AsyncExternalAccountsResourceWithStreamingResponse
return AsyncExternalAccountsResourceWithStreamingResponse(self._client.external_accounts)
@@ -693,6 +704,7 @@ def transactions(self) -> transactions.AsyncTransactionsResourceWithStreamingRes
@cached_property
def users(self) -> users.AsyncUsersResourceWithStreamingResponse:
+ """User management operations"""
from .resources.users import AsyncUsersResourceWithStreamingResponse
return AsyncUsersResourceWithStreamingResponse(self._client.users)
diff --git a/src/fragment/_utils/_utils.py b/src/fragment/_utils/_utils.py
index eec7f4a..63b8cd6 100644
--- a/src/fragment/_utils/_utils.py
+++ b/src/fragment/_utils/_utils.py
@@ -86,8 +86,9 @@ def _extract_items(
index += 1
if is_dict(obj):
try:
- # We are at the last entry in the path so we must remove the field
- if (len(path)) == index:
+ # Remove the field if there are no more dict keys in the path,
+ # only "" traversal markers or end.
+ if all(p == "" for p in path[index:]):
item = obj.pop(key)
else:
item = obj[key]
diff --git a/src/fragment/_version.py b/src/fragment/_version.py
index f6d2ffa..bba4162 100644
--- a/src/fragment/_version.py
+++ b/src/fragment/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "fragment"
-__version__ = "0.9.0" # x-release-please-version
+__version__ = "0.10.0" # x-release-please-version
diff --git a/src/fragment/resources/external_accounts.py b/src/fragment/resources/external_accounts.py
index 724c0af..0ff4275 100644
--- a/src/fragment/resources/external_accounts.py
+++ b/src/fragment/resources/external_accounts.py
@@ -23,6 +23,8 @@
class ExternalAccountsResource(SyncAPIResource):
+ """External account management operations"""
+
@cached_property
def with_raw_response(self) -> ExternalAccountsResourceWithRawResponse:
"""
@@ -55,12 +57,12 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ExternalAccountCreateResponse:
"""
- Creates a new external account
+ Creates an external account.
Args:
- external_id: External ID for the account (user-provided, unique, mutable)
+ external_id: User-provided unique ID.
- name: Human-readable name for the external account (mutable)
+ name: Name of the account.
extra_headers: Send extra headers
@@ -95,7 +97,7 @@ def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ExternalAccountListResponse:
- """Lists all external accounts for the workspace"""
+ """Lists all external accounts."""
return self._get(
"/external-accounts",
options=make_request_options(
@@ -106,6 +108,8 @@ def list(
class AsyncExternalAccountsResource(AsyncAPIResource):
+ """External account management operations"""
+
@cached_property
def with_raw_response(self) -> AsyncExternalAccountsResourceWithRawResponse:
"""
@@ -138,12 +142,12 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ExternalAccountCreateResponse:
"""
- Creates a new external account
+ Creates an external account.
Args:
- external_id: External ID for the account (user-provided, unique, mutable)
+ external_id: User-provided unique ID.
- name: Human-readable name for the external account (mutable)
+ name: Name of the account.
extra_headers: Send extra headers
@@ -178,7 +182,7 @@ async def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ExternalAccountListResponse:
- """Lists all external accounts for the workspace"""
+ """Lists all external accounts."""
return await self._get(
"/external-accounts",
options=make_request_options(
diff --git a/src/fragment/resources/invoices.py b/src/fragment/resources/invoices.py
index 48b0387..4f6ea27 100644
--- a/src/fragment/resources/invoices.py
+++ b/src/fragment/resources/invoices.py
@@ -63,17 +63,15 @@ def create(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceCreateResponse:
- """Creates a new invoice
+ """
+ Creates an invoice.
Args:
- invoice_id: Unique identifier for the invoice.
-
- Make this the canonical ID from your system
- for the transaction.
+ invoice_id: Unique ID for the invoice.
- line_items: List of line items to create with the invoice
+ line_items: Line items to create with the invoice.
- tags: Optional metadata tags for this invoice
+ tags: Tags for the invoice.
extra_headers: Send extra headers
@@ -111,10 +109,10 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceRetrieveResponse:
"""
- Gets an invoice by ID with balance details
+ Retrieves an invoice.
Args:
- id: Invoice ID
+ id: Unique identifier for the invoice.
extra_headers: Send extra headers
@@ -149,13 +147,16 @@ def update(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceUpdateResponse:
"""
- Updates an invoice
+ Updates an invoice.
Args:
- id: Invoice ID
+ id: Unique identifier for the invoice.
+
+ current_invoice_version: Current version of the invoice. Must match the stored version.
+
+ line_items: Line item updates.
- current_invoice_version: The current version of the invoice. Must match the stored version for the update
- to succeed (optimistic concurrency).
+ tags: Tag updates.
extra_headers: Send extra headers
@@ -193,7 +194,7 @@ def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceListResponse:
- """Lists all invoices for the workspace"""
+ """Lists all invoices."""
return self._get(
"/invoices",
options=make_request_options(
@@ -214,10 +215,10 @@ def list_history(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceListHistoryResponse:
"""
- Gets the version history of an invoice
+ Retrieves the version history of an invoice.
Args:
- id: Invoice ID
+ id: Unique identifier for the invoice.
extra_headers: Send extra headers
@@ -241,7 +242,7 @@ def search(
self,
*,
filter: invoice_search_params.Filter,
- page_info: invoice_search_params.PageInfo,
+ page_info: invoice_search_params.PageInfo | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -250,12 +251,12 @@ def search(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceSearchResponse:
"""
- Searches invoices
+ Searches invoices.
Args:
- filter: Filter criteria for the search
+ filter: Filter criteria for the search.
- page_info: Pagination parameters
+ page_info: Pagination parameters.
extra_headers: Send extra headers
@@ -316,17 +317,15 @@ async def create(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceCreateResponse:
- """Creates a new invoice
+ """
+ Creates an invoice.
Args:
- invoice_id: Unique identifier for the invoice.
-
- Make this the canonical ID from your system
- for the transaction.
+ invoice_id: Unique ID for the invoice.
- line_items: List of line items to create with the invoice
+ line_items: Line items to create with the invoice.
- tags: Optional metadata tags for this invoice
+ tags: Tags for the invoice.
extra_headers: Send extra headers
@@ -364,10 +363,10 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceRetrieveResponse:
"""
- Gets an invoice by ID with balance details
+ Retrieves an invoice.
Args:
- id: Invoice ID
+ id: Unique identifier for the invoice.
extra_headers: Send extra headers
@@ -402,13 +401,16 @@ async def update(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceUpdateResponse:
"""
- Updates an invoice
+ Updates an invoice.
Args:
- id: Invoice ID
+ id: Unique identifier for the invoice.
+
+ current_invoice_version: Current version of the invoice. Must match the stored version.
+
+ line_items: Line item updates.
- current_invoice_version: The current version of the invoice. Must match the stored version for the update
- to succeed (optimistic concurrency).
+ tags: Tag updates.
extra_headers: Send extra headers
@@ -446,7 +448,7 @@ async def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceListResponse:
- """Lists all invoices for the workspace"""
+ """Lists all invoices."""
return await self._get(
"/invoices",
options=make_request_options(
@@ -467,10 +469,10 @@ async def list_history(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceListHistoryResponse:
"""
- Gets the version history of an invoice
+ Retrieves the version history of an invoice.
Args:
- id: Invoice ID
+ id: Unique identifier for the invoice.
extra_headers: Send extra headers
@@ -494,7 +496,7 @@ async def search(
self,
*,
filter: invoice_search_params.Filter,
- page_info: invoice_search_params.PageInfo,
+ page_info: invoice_search_params.PageInfo | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -503,12 +505,12 @@ async def search(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InvoiceSearchResponse:
"""
- Searches invoices
+ Searches invoices.
Args:
- filter: Filter criteria for the search
+ filter: Filter criteria for the search.
- page_info: Pagination parameters
+ page_info: Pagination parameters.
extra_headers: Send extra headers
diff --git a/src/fragment/resources/products.py b/src/fragment/resources/products.py
index 665b13f..00147d5 100644
--- a/src/fragment/resources/products.py
+++ b/src/fragment/resources/products.py
@@ -62,18 +62,18 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ProductCreateResponse:
"""
- Creates a new product
+ Creates a product.
Args:
- code: Product code (unique identifier)
+ code: Unique product code.
- description: Description of the product
+ description: Product description.
- paid_by_roles: Roles that can pay for this product. Reference roles by id or name. At least one
- of paid_by_roles or paid_to_roles must be provided.
+ paid_by_roles: Roles that can pay for the product. Reference roles by `id` or `name`. At least
+ one of `paid_by_roles` or `paid_to_roles` must be provided.
- paid_to_roles: Roles that receive payment for this product. Reference roles by id or name. At
- least one of paid_by_roles or paid_to_roles must be provided.
+ paid_to_roles: Roles that can receive payment for the product. Reference roles by `id` or
+ `name`. At least one of `paid_by_roles` or `paid_to_roles` must be provided.
extra_headers: Send extra headers
@@ -111,11 +111,12 @@ def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ProductRetrieveResponse:
- """
- Gets a product by code
+ """Retrieves a product by code.
Args:
- code: Product code
+ code: Product code.
+
+ Must not include #, /, or :.
extra_headers: Send extra headers
@@ -145,7 +146,7 @@ def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ProductListResponse:
- """Lists all products for the workspace"""
+ """Lists all products."""
return self._get(
"/products",
options=make_request_options(
@@ -192,18 +193,18 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ProductCreateResponse:
"""
- Creates a new product
+ Creates a product.
Args:
- code: Product code (unique identifier)
+ code: Unique product code.
- description: Description of the product
+ description: Product description.
- paid_by_roles: Roles that can pay for this product. Reference roles by id or name. At least one
- of paid_by_roles or paid_to_roles must be provided.
+ paid_by_roles: Roles that can pay for the product. Reference roles by `id` or `name`. At least
+ one of `paid_by_roles` or `paid_to_roles` must be provided.
- paid_to_roles: Roles that receive payment for this product. Reference roles by id or name. At
- least one of paid_by_roles or paid_to_roles must be provided.
+ paid_to_roles: Roles that can receive payment for the product. Reference roles by `id` or
+ `name`. At least one of `paid_by_roles` or `paid_to_roles` must be provided.
extra_headers: Send extra headers
@@ -241,11 +242,12 @@ async def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ProductRetrieveResponse:
- """
- Gets a product by code
+ """Retrieves a product by code.
Args:
- code: Product code
+ code: Product code.
+
+ Must not include #, /, or :.
extra_headers: Send extra headers
@@ -275,7 +277,7 @@ async def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ProductListResponse:
- """Lists all products for the workspace"""
+ """Lists all products."""
return await self._get(
"/products",
options=make_request_options(
diff --git a/src/fragment/resources/roles.py b/src/fragment/resources/roles.py
index 8fb673d..ee4729e 100644
--- a/src/fragment/resources/roles.py
+++ b/src/fragment/resources/roles.py
@@ -56,10 +56,10 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> RoleCreateResponse:
"""
- Creates a new role
+ Creates a role.
Args:
- role: Name of the role
+ role: Name of the role.
extra_headers: Send extra headers
@@ -88,7 +88,7 @@ def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> RoleListResponse:
- """Lists all roles for the workspace"""
+ """Lists all roles."""
return self._get(
"/roles",
options=make_request_options(
@@ -132,10 +132,10 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> RoleCreateResponse:
"""
- Creates a new role
+ Creates a role.
Args:
- role: Name of the role
+ role: Name of the role.
extra_headers: Send extra headers
@@ -164,7 +164,7 @@ async def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> RoleListResponse:
- """Lists all roles for the workspace"""
+ """Lists all roles."""
return await self._get(
"/roles",
options=make_request_options(
diff --git a/src/fragment/resources/transactions.py b/src/fragment/resources/transactions.py
index 673bbe9..b8b30a4 100644
--- a/src/fragment/resources/transactions.py
+++ b/src/fragment/resources/transactions.py
@@ -12,7 +12,7 @@
transaction_list_params,
transaction_create_params,
transaction_search_params,
- transaction_create_allocations_params,
+ transaction_update_params,
transaction_search_allocations_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
@@ -29,9 +29,9 @@
from ..types.transaction_list_response import TransactionListResponse
from ..types.transaction_create_response import TransactionCreateResponse
from ..types.transaction_search_response import TransactionSearchResponse
+from ..types.transaction_update_response import TransactionUpdateResponse
from ..types.transaction_retrieve_response import TransactionRetrieveResponse
from ..types.transaction_list_history_response import TransactionListHistoryResponse
-from ..types.transaction_create_allocations_response import TransactionCreateAllocationsResponse
from ..types.transaction_search_allocations_response import TransactionSearchAllocationsResponse
__all__ = ["TransactionsResource", "AsyncTransactionsResource"]
@@ -256,24 +256,26 @@ def create(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionCreateResponse:
- """
- Syncs a transaction, optionally with allocations
+ """Creates a transaction.
Args:
- account: Account reference. Provide id, external_id, or both.
+ account: External account for the transaction.
+
+ Identify it by `id`, `external_id`, or
+ both.
- allocations: Allocation entries for this transaction. Empty indicates unreconciled funds.
+ allocations: Allocations for the transaction. An empty array indicates unreconciled funds.
- amount: Amount in smallest currency unit as stringified bigint (can be positive or
- negative).
+ amount: Transaction amount, as a string in the smallest currency unit, such as cents for
+ USD. Can be positive or negative.
- currency: Currency code (ISO 4217 or crypto)
+ currency: ISO 4217 or crypto currency code.
- external_id: External transaction ID used for idempotent sync.
+ external_id: User-provided unique ID.
- posted: Posted timestamp in ISO 8601 format.
+ posted: Timestamp when the transaction was posted. Uses ISO 8601 format.
- tags: Optional metadata tags for this transaction
+ tags: Tags for the transaction.
extra_headers: Send extra headers
@@ -315,11 +317,10 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionRetrieveResponse:
"""
- Gets a transaction by ID or external ID
+ Retrieves a transaction by ID or external ID.
Args:
- transaction_ref: Transaction reference. Accepts either an encoded Fragment ID (txn_xxx) or an
- external ID.
+ transaction_ref: Transaction `id` or `external_id`.
extra_headers: Send extra headers
@@ -339,28 +340,31 @@ def retrieve(
cast_to=TransactionRetrieveResponse,
)
- def list(
+ def update(
self,
+ transaction_ref: str,
*,
- account: str | Omit = omit,
- reconciliation_status: Literal["reconciled", "unreconciled"] | Omit = omit,
+ current_transaction_version: int,
+ allocations: transaction_update_params.Allocations | Omit = omit,
+ tags: transaction_update_params.Tags | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> TransactionListResponse:
- """Lists all transactions for the workspace
+ ) -> TransactionUpdateResponse:
+ """
+ Updates a transaction.
Args:
- account: Filter by account.
+ transaction_ref: Transaction `id` or `external_id`.
+
+ current_transaction_version: Current version of the transaction. Must match the stored version.
- Encoded account ID (ext_account_xxx) or external_id. If the
- account does not exist, returns an empty list.
+ allocations: Allocation updates.
- reconciliation_status: Filter by reconciliation state. reconciled = unallocated_amount === 0;
- unreconciled = unallocated_amount !== 0. Omit for all transactions.
+ tags: Tag updates.
extra_headers: Send extra headers
@@ -370,47 +374,46 @@ def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/transactions",
+ if not transaction_ref:
+ raise ValueError(f"Expected a non-empty value for `transaction_ref` but received {transaction_ref!r}")
+ return self._patch(
+ path_template("/transactions/{transaction_ref}", transaction_ref=transaction_ref),
+ body=maybe_transform(
+ {
+ "current_transaction_version": current_transaction_version,
+ "allocations": allocations,
+ "tags": tags,
+ },
+ transaction_update_params.TransactionUpdateParams,
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "account": account,
- "reconciliation_status": reconciliation_status,
- },
- transaction_list_params.TransactionListParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TransactionListResponse,
+ cast_to=TransactionUpdateResponse,
)
- def create_allocations(
+ def list(
self,
- transaction_ref: str,
*,
- allocation_updates: Iterable[transaction_create_allocations_params.AllocationUpdate],
- version: int,
+ account: str | Omit = omit,
+ reconciliation_status: Literal["reconciled", "unreconciled"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> TransactionCreateAllocationsResponse:
+ ) -> TransactionListResponse:
"""
- Updates allocations on an existing transaction
+ Lists all transactions.
Args:
- transaction_ref: Transaction reference. Accepts either an encoded Fragment ID (txn_xxx) or an
- external ID.
+ account: Filter by account `id` or `external_id`. If the account does not exist, returns
+ an empty list.
- allocation_updates: Allocation operations to apply
-
- version: Current transaction version for optimistic concurrency control
+ reconciliation_status: Filter by reconciliation status. `reconciled` returns transactions where
+ unallocated_amount is 0. `unreconciled` returns transactions where
+ unallocated_amount is not 0. Omit for all transactions.
extra_headers: Send extra headers
@@ -420,21 +423,22 @@ def create_allocations(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not transaction_ref:
- raise ValueError(f"Expected a non-empty value for `transaction_ref` but received {transaction_ref!r}")
- return self._post(
- path_template("/transactions/{transaction_ref}/allocations", transaction_ref=transaction_ref),
- body=maybe_transform(
- {
- "allocation_updates": allocation_updates,
- "version": version,
- },
- transaction_create_allocations_params.TransactionCreateAllocationsParams,
- ),
+ return self._get(
+ "/transactions",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "account": account,
+ "reconciliation_status": reconciliation_status,
+ },
+ transaction_list_params.TransactionListParams,
+ ),
),
- cast_to=TransactionCreateAllocationsResponse,
+ cast_to=TransactionListResponse,
)
def list_history(
@@ -449,11 +453,10 @@ def list_history(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionListHistoryResponse:
"""
- Gets the version history of a transaction
+ Retrieves the version history of a transaction.
Args:
- transaction_ref: Transaction reference. Accepts either an encoded Fragment ID (txn_xxx) or an
- external ID.
+ transaction_ref: Transaction `id` or `external_id`.
extra_headers: Send extra headers
@@ -477,6 +480,7 @@ def search(
self,
*,
filter: transaction_search_params.Filter,
+ page_info: transaction_search_params.PageInfo | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -485,10 +489,12 @@ def search(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionSearchResponse:
"""
- Searches transactions by filter criteria
+ Searches transactions.
Args:
- filter: Filter criteria for searching transactions.
+ filter: Filter for searching transactions.
+
+ page_info: Pagination parameters.
extra_headers: Send extra headers
@@ -500,7 +506,13 @@ def search(
"""
return self._post(
"/transactions/search",
- body=maybe_transform({"filter": filter}, transaction_search_params.TransactionSearchParams),
+ body=maybe_transform(
+ {
+ "filter": filter,
+ "page_info": page_info,
+ },
+ transaction_search_params.TransactionSearchParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -519,10 +531,10 @@ def search_allocations(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionSearchAllocationsResponse:
"""
- Searches transaction allocations by filter criteria
+ Searches transaction allocations.
Args:
- filter: Filter criteria for searching transaction allocations.
+ filter: Filter for searching transaction allocations.
extra_headers: Send extra headers
@@ -763,24 +775,26 @@ async def create(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionCreateResponse:
- """
- Syncs a transaction, optionally with allocations
+ """Creates a transaction.
Args:
- account: Account reference. Provide id, external_id, or both.
+ account: External account for the transaction.
+
+ Identify it by `id`, `external_id`, or
+ both.
- allocations: Allocation entries for this transaction. Empty indicates unreconciled funds.
+ allocations: Allocations for the transaction. An empty array indicates unreconciled funds.
- amount: Amount in smallest currency unit as stringified bigint (can be positive or
- negative).
+ amount: Transaction amount, as a string in the smallest currency unit, such as cents for
+ USD. Can be positive or negative.
- currency: Currency code (ISO 4217 or crypto)
+ currency: ISO 4217 or crypto currency code.
- external_id: External transaction ID used for idempotent sync.
+ external_id: User-provided unique ID.
- posted: Posted timestamp in ISO 8601 format.
+ posted: Timestamp when the transaction was posted. Uses ISO 8601 format.
- tags: Optional metadata tags for this transaction
+ tags: Tags for the transaction.
extra_headers: Send extra headers
@@ -822,11 +836,10 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionRetrieveResponse:
"""
- Gets a transaction by ID or external ID
+ Retrieves a transaction by ID or external ID.
Args:
- transaction_ref: Transaction reference. Accepts either an encoded Fragment ID (txn_xxx) or an
- external ID.
+ transaction_ref: Transaction `id` or `external_id`.
extra_headers: Send extra headers
@@ -846,28 +859,31 @@ async def retrieve(
cast_to=TransactionRetrieveResponse,
)
- async def list(
+ async def update(
self,
+ transaction_ref: str,
*,
- account: str | Omit = omit,
- reconciliation_status: Literal["reconciled", "unreconciled"] | Omit = omit,
+ current_transaction_version: int,
+ allocations: transaction_update_params.Allocations | Omit = omit,
+ tags: transaction_update_params.Tags | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> TransactionListResponse:
- """Lists all transactions for the workspace
+ ) -> TransactionUpdateResponse:
+ """
+ Updates a transaction.
Args:
- account: Filter by account.
+ transaction_ref: Transaction `id` or `external_id`.
+
+ current_transaction_version: Current version of the transaction. Must match the stored version.
- Encoded account ID (ext_account_xxx) or external_id. If the
- account does not exist, returns an empty list.
+ allocations: Allocation updates.
- reconciliation_status: Filter by reconciliation state. reconciled = unallocated_amount === 0;
- unreconciled = unallocated_amount !== 0. Omit for all transactions.
+ tags: Tag updates.
extra_headers: Send extra headers
@@ -877,47 +893,46 @@ async def list(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/transactions",
+ if not transaction_ref:
+ raise ValueError(f"Expected a non-empty value for `transaction_ref` but received {transaction_ref!r}")
+ return await self._patch(
+ path_template("/transactions/{transaction_ref}", transaction_ref=transaction_ref),
+ body=await async_maybe_transform(
+ {
+ "current_transaction_version": current_transaction_version,
+ "allocations": allocations,
+ "tags": tags,
+ },
+ transaction_update_params.TransactionUpdateParams,
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "account": account,
- "reconciliation_status": reconciliation_status,
- },
- transaction_list_params.TransactionListParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TransactionListResponse,
+ cast_to=TransactionUpdateResponse,
)
- async def create_allocations(
+ async def list(
self,
- transaction_ref: str,
*,
- allocation_updates: Iterable[transaction_create_allocations_params.AllocationUpdate],
- version: int,
+ account: str | Omit = omit,
+ reconciliation_status: Literal["reconciled", "unreconciled"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> TransactionCreateAllocationsResponse:
+ ) -> TransactionListResponse:
"""
- Updates allocations on an existing transaction
+ Lists all transactions.
Args:
- transaction_ref: Transaction reference. Accepts either an encoded Fragment ID (txn_xxx) or an
- external ID.
-
- allocation_updates: Allocation operations to apply
+ account: Filter by account `id` or `external_id`. If the account does not exist, returns
+ an empty list.
- version: Current transaction version for optimistic concurrency control
+ reconciliation_status: Filter by reconciliation status. `reconciled` returns transactions where
+ unallocated_amount is 0. `unreconciled` returns transactions where
+ unallocated_amount is not 0. Omit for all transactions.
extra_headers: Send extra headers
@@ -927,21 +942,22 @@ async def create_allocations(
timeout: Override the client-level default timeout for this request, in seconds
"""
- if not transaction_ref:
- raise ValueError(f"Expected a non-empty value for `transaction_ref` but received {transaction_ref!r}")
- return await self._post(
- path_template("/transactions/{transaction_ref}/allocations", transaction_ref=transaction_ref),
- body=await async_maybe_transform(
- {
- "allocation_updates": allocation_updates,
- "version": version,
- },
- transaction_create_allocations_params.TransactionCreateAllocationsParams,
- ),
+ return await self._get(
+ "/transactions",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "account": account,
+ "reconciliation_status": reconciliation_status,
+ },
+ transaction_list_params.TransactionListParams,
+ ),
),
- cast_to=TransactionCreateAllocationsResponse,
+ cast_to=TransactionListResponse,
)
async def list_history(
@@ -956,11 +972,10 @@ async def list_history(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionListHistoryResponse:
"""
- Gets the version history of a transaction
+ Retrieves the version history of a transaction.
Args:
- transaction_ref: Transaction reference. Accepts either an encoded Fragment ID (txn_xxx) or an
- external ID.
+ transaction_ref: Transaction `id` or `external_id`.
extra_headers: Send extra headers
@@ -984,6 +999,7 @@ async def search(
self,
*,
filter: transaction_search_params.Filter,
+ page_info: transaction_search_params.PageInfo | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -992,10 +1008,12 @@ async def search(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionSearchResponse:
"""
- Searches transactions by filter criteria
+ Searches transactions.
Args:
- filter: Filter criteria for searching transactions.
+ filter: Filter for searching transactions.
+
+ page_info: Pagination parameters.
extra_headers: Send extra headers
@@ -1007,7 +1025,13 @@ async def search(
"""
return await self._post(
"/transactions/search",
- body=await async_maybe_transform({"filter": filter}, transaction_search_params.TransactionSearchParams),
+ body=await async_maybe_transform(
+ {
+ "filter": filter,
+ "page_info": page_info,
+ },
+ transaction_search_params.TransactionSearchParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1026,10 +1050,10 @@ async def search_allocations(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionSearchAllocationsResponse:
"""
- Searches transaction allocations by filter criteria
+ Searches transaction allocations.
Args:
- filter: Filter criteria for searching transaction allocations.
+ filter: Filter for searching transaction allocations.
extra_headers: Send extra headers
@@ -1061,12 +1085,12 @@ def __init__(self, transactions: TransactionsResource) -> None:
self.retrieve = to_raw_response_wrapper(
transactions.retrieve,
)
+ self.update = to_raw_response_wrapper(
+ transactions.update,
+ )
self.list = to_raw_response_wrapper(
transactions.list,
)
- self.create_allocations = to_raw_response_wrapper(
- transactions.create_allocations,
- )
self.list_history = to_raw_response_wrapper(
transactions.list_history,
)
@@ -1088,12 +1112,12 @@ def __init__(self, transactions: AsyncTransactionsResource) -> None:
self.retrieve = async_to_raw_response_wrapper(
transactions.retrieve,
)
+ self.update = async_to_raw_response_wrapper(
+ transactions.update,
+ )
self.list = async_to_raw_response_wrapper(
transactions.list,
)
- self.create_allocations = async_to_raw_response_wrapper(
- transactions.create_allocations,
- )
self.list_history = async_to_raw_response_wrapper(
transactions.list_history,
)
@@ -1115,12 +1139,12 @@ def __init__(self, transactions: TransactionsResource) -> None:
self.retrieve = to_streamed_response_wrapper(
transactions.retrieve,
)
+ self.update = to_streamed_response_wrapper(
+ transactions.update,
+ )
self.list = to_streamed_response_wrapper(
transactions.list,
)
- self.create_allocations = to_streamed_response_wrapper(
- transactions.create_allocations,
- )
self.list_history = to_streamed_response_wrapper(
transactions.list_history,
)
@@ -1142,12 +1166,12 @@ def __init__(self, transactions: AsyncTransactionsResource) -> None:
self.retrieve = async_to_streamed_response_wrapper(
transactions.retrieve,
)
+ self.update = async_to_streamed_response_wrapper(
+ transactions.update,
+ )
self.list = async_to_streamed_response_wrapper(
transactions.list,
)
- self.create_allocations = async_to_streamed_response_wrapper(
- transactions.create_allocations,
- )
self.list_history = async_to_streamed_response_wrapper(
transactions.list_history,
)
diff --git a/src/fragment/resources/users.py b/src/fragment/resources/users.py
index d37e0eb..7994af1 100644
--- a/src/fragment/resources/users.py
+++ b/src/fragment/resources/users.py
@@ -23,6 +23,8 @@
class UsersResource(SyncAPIResource):
+ """User management operations"""
+
@cached_property
def with_raw_response(self) -> UsersResourceWithRawResponse:
"""
@@ -55,12 +57,12 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> UserCreateResponse:
"""
- Creates a new user
+ Creates a user.
Args:
- external_id: External ID for the user
+ external_id: User-provided unique ID.
- role: Role of the user
+ role: Name of the role to assign. Must match an existing role.
extra_headers: Send extra headers
@@ -95,7 +97,7 @@ def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> UserListResponse:
- """Lists all users for the workspace"""
+ """Lists all users."""
return self._get(
"/users",
options=make_request_options(
@@ -106,6 +108,8 @@ def list(
class AsyncUsersResource(AsyncAPIResource):
+ """User management operations"""
+
@cached_property
def with_raw_response(self) -> AsyncUsersResourceWithRawResponse:
"""
@@ -138,12 +142,12 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> UserCreateResponse:
"""
- Creates a new user
+ Creates a user.
Args:
- external_id: External ID for the user
+ external_id: User-provided unique ID.
- role: Role of the user
+ role: Name of the role to assign. Must match an existing role.
extra_headers: Send extra headers
@@ -178,7 +182,7 @@ async def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> UserListResponse:
- """Lists all users for the workspace"""
+ """Lists all users."""
return await self._get(
"/users",
options=make_request_options(
diff --git a/src/fragment/types/__init__.py b/src/fragment/types/__init__.py
index 5f5dbd0..290f576 100644
--- a/src/fragment/types/__init__.py
+++ b/src/fragment/types/__init__.py
@@ -30,23 +30,19 @@
from .transaction_create_params import TransactionCreateParams as TransactionCreateParams
from .transaction_list_response import TransactionListResponse as TransactionListResponse
from .transaction_search_params import TransactionSearchParams as TransactionSearchParams
+from .transaction_update_params import TransactionUpdateParams as TransactionUpdateParams
from .transaction_create_response import TransactionCreateResponse as TransactionCreateResponse
from .transaction_search_response import TransactionSearchResponse as TransactionSearchResponse
+from .transaction_update_response import TransactionUpdateResponse as TransactionUpdateResponse
from .invoice_list_history_response import InvoiceListHistoryResponse as InvoiceListHistoryResponse
from .transaction_retrieve_response import TransactionRetrieveResponse as TransactionRetrieveResponse
from .external_account_create_params import ExternalAccountCreateParams as ExternalAccountCreateParams
from .external_account_list_response import ExternalAccountListResponse as ExternalAccountListResponse
from .external_account_create_response import ExternalAccountCreateResponse as ExternalAccountCreateResponse
from .transaction_list_history_response import TransactionListHistoryResponse as TransactionListHistoryResponse
-from .transaction_create_allocations_params import (
- TransactionCreateAllocationsParams as TransactionCreateAllocationsParams,
-)
from .transaction_search_allocations_params import (
TransactionSearchAllocationsParams as TransactionSearchAllocationsParams,
)
-from .transaction_create_allocations_response import (
- TransactionCreateAllocationsResponse as TransactionCreateAllocationsResponse,
-)
from .transaction_search_allocations_response import (
TransactionSearchAllocationsResponse as TransactionSearchAllocationsResponse,
)
diff --git a/src/fragment/types/external_account.py b/src/fragment/types/external_account.py
index 2129b3d..02f2920 100644
--- a/src/fragment/types/external_account.py
+++ b/src/fragment/types/external_account.py
@@ -6,13 +6,13 @@
class ExternalAccount(BaseModel):
- """External account object"""
+ """External account object."""
id: str
- """Fragment-generated unique ID for the external account"""
+ """FRAGMENT generated unique ID."""
external_id: str
- """User-provided external ID"""
+ """User-provided unique ID."""
name: str
- """Human-readable name for the external account"""
+ """Name of the account."""
diff --git a/src/fragment/types/external_account_create_params.py b/src/fragment/types/external_account_create_params.py
index e4113a5..ee8aaa3 100644
--- a/src/fragment/types/external_account_create_params.py
+++ b/src/fragment/types/external_account_create_params.py
@@ -9,7 +9,7 @@
class ExternalAccountCreateParams(TypedDict, total=False):
external_id: Required[str]
- """External ID for the account (user-provided, unique, mutable)"""
+ """User-provided unique ID."""
name: Required[str]
- """Human-readable name for the external account (mutable)"""
+ """Name of the account."""
diff --git a/src/fragment/types/external_account_create_response.py b/src/fragment/types/external_account_create_response.py
index ee0c3ec..9062890 100644
--- a/src/fragment/types/external_account_create_response.py
+++ b/src/fragment/types/external_account_create_response.py
@@ -8,4 +8,4 @@
class ExternalAccountCreateResponse(BaseModel):
data: ExternalAccount
- """External account object"""
+ """External account object."""
diff --git a/src/fragment/types/external_account_list_response.py b/src/fragment/types/external_account_list_response.py
index fe69982..eb11ebd 100644
--- a/src/fragment/types/external_account_list_response.py
+++ b/src/fragment/types/external_account_list_response.py
@@ -9,6 +9,6 @@
class ExternalAccountListResponse(BaseModel):
- """List of external accounts"""
+ """List of external accounts."""
data: List[ExternalAccount]
diff --git a/src/fragment/types/invoice.py b/src/fragment/types/invoice.py
index 57bbe8f..0d994a9 100644
--- a/src/fragment/types/invoice.py
+++ b/src/fragment/types/invoice.py
@@ -10,48 +10,48 @@
class Tag(BaseModel):
- """A key-value tag pair"""
+ """A key-value tag pair."""
key: str
- """Tag key"""
+ """Tag key."""
value: str
- """Tag value"""
+ """Tag value."""
class LineItemPrice(BaseModel):
- """Price breakdown containing amount, unit price, and quantity"""
+ """Price breakdown."""
amount: str
- """Total amount in smallest currency unit (represented as string for bigint)"""
+ """Total amount as a string in the smallest currency unit, such as cents for USD."""
quantity: int
- """Quantity of units for this line item"""
+ """Number of units."""
unit_price: str
- """Unit price in smallest currency unit (represented as string for bigint)"""
+ """Unit price as a string in the smallest currency unit, such as cents for USD."""
class LineItemTag(BaseModel):
- """A key-value tag pair"""
+ """A key-value tag pair."""
key: str
- """Tag key"""
+ """Tag key."""
value: str
- """Tag value"""
+ """Tag value."""
class LineItem(BaseModel):
- """Invoice line item object"""
+ """Invoice line item."""
id: str
- """Unique identifier for the line item"""
+ """FRAGMENT generated unique ID."""
amount: str
- """Deprecated: use price.amount instead.
+ """Total amount as a string in the smallest currency unit, such as cents for USD.
- Total amount in smallest currency unit (represented as string for bigint)
+ Deprecated, use price.amount instead.
"""
currency_code: Literal[
@@ -235,53 +235,50 @@ class LineItem(BaseModel):
"LOGICAL",
"CUSTOM",
]
- """Currency code (ISO 4217 or crypto)"""
+ """ISO 4217 or crypto currency code."""
description: str
- """Description of the line item"""
+ """Description of the line item."""
price: LineItemPrice
- """Price breakdown containing amount, unit price, and quantity"""
+ """Price breakdown."""
product_id: str
- """ID of the product/catalog item"""
+ """Unique identifier for the product."""
tags: List[LineItemTag]
- """Metadata tags for this line item"""
+ """Tags for the line item."""
type: Literal["payin", "payout"]
- """The type of the line item"""
+ """Type of the line item."""
user_id: str
- """External ID of the user associated with this line item"""
+ """User-provided unique external ID."""
class Invoice(BaseModel):
- """Invoice object"""
+ """Invoice object."""
id: str
- """Unique identifier for the invoice"""
+ """Unique invoice ID."""
created: datetime
- """ISO 8601 timestamp when the invoice was created"""
+ """Timestamp when the invoice was created. Uses ISO 8601 format."""
status: Literal["active"]
- """The status of the invoice"""
+ """Status of the invoice. Deprecated."""
tags: List[Tag]
- """Metadata tags for this invoice"""
+ """Tags for the invoice."""
version: float
- """The current version of the invoice.
-
- Pass this value when updating to ensure thread safety.
- """
+ """Current version of the invoice."""
workspace_id: str
- """Workspace ID this invoice belongs to"""
+ """Workspace the invoice belongs to."""
line_items: Optional[List[LineItem]] = None
- """List of line items associated with this invoice"""
+ """Line items for the invoice."""
modified: Optional[datetime] = None
- """ISO 8601 timestamp when the invoice was last modified"""
+ """Timestamp when the invoice was last modified. Uses ISO 8601 format."""
diff --git a/src/fragment/types/invoice_create_params.py b/src/fragment/types/invoice_create_params.py
index 13fbb5a..33a09b3 100644
--- a/src/fragment/types/invoice_create_params.py
+++ b/src/fragment/types/invoice_create_params.py
@@ -19,82 +19,76 @@
class InvoiceCreateParams(TypedDict, total=False):
invoice_id: Required[str]
- """Unique identifier for the invoice.
-
- Make this the canonical ID from your system for the transaction.
- """
+ """Unique ID for the invoice."""
line_items: Required[Iterable[LineItem]]
- """List of line items to create with the invoice"""
+ """Line items to create with the invoice."""
tags: Iterable[Tag]
- """Optional metadata tags for this invoice"""
+ """Tags for the invoice."""
class LineItemUserID(TypedDict, total=False):
id: Required[str]
- """FRAGMENT generated ID of the user"""
+ """FRAGMENT generated unique ID."""
class LineItemUserExternalID(TypedDict, total=False):
external_id: Required[str]
- """External ID of the user"""
+ """User-provided unique ID."""
LineItemUser: TypeAlias = Union[LineItemUserID, LineItemUserExternalID]
class LineItemPrice(TypedDict, total=False):
- """Price breakdown. Provide amount, or unit_price + quantity, or all three."""
+ """Price breakdown. Provide amount, or unit_price and quantity, or all three."""
amount: str
- """Total amount in smallest currency unit.
+ """Total amount as a string in the smallest currency unit, such as cents for USD.
Required if unit_price and quantity are not provided.
"""
quantity: int
- """Number of units for this line item."""
+ """Number of units for the line item."""
unit_price: str
- """Price per unit in smallest currency unit."""
+ """
+ Price per unit as a string in the smallest currency unit, such as cents for USD.
+ """
class LineItemTag(TypedDict, total=False):
- """A key-value tag pair for metadata"""
+ """A key-value tag pair for metadata."""
key: Required[str]
- """Tag key.
-
- Must be a valid safe string (no special characters like #, /, :). Max 50
- characters.
- """
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
value: Required[str]
- """Tag value.
-
- Must be a valid safe string (no special characters like #, /, :). Max 200
- characters.
- """
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
class LineItem(TypedDict, total=False):
"""Data to create a line item."""
description: Required[str]
- """Description of the line item"""
+ """Description of the line item."""
product_id: Required[str]
- """ID of the product/catalog item"""
+ """Unique identifier for the product."""
type: Required[Literal["payin", "payout"]]
- """The type of the line item"""
+ """Type of the line item."""
user: Required[LineItemUser]
- """Identifies a user by Fragment-generated id or external_id (request body)."""
+ """Identifies a user by `id` or `external_id`."""
amount: str
- """Deprecated: use price instead. Total amount in smallest currency unit."""
+ """Total amount as a string in the smallest currency unit, such as cents for USD.
+
+ Deprecated, use price instead.
+ """
currency_code: Literal[
"ADA",
@@ -277,28 +271,20 @@ class LineItem(TypedDict, total=False):
"LOGICAL",
"CUSTOM",
]
- """Currency code (ISO 4217 or crypto)"""
+ """ISO 4217 or crypto currency code."""
price: LineItemPrice
- """Price breakdown. Provide amount, or unit_price + quantity, or all three."""
+ """Price breakdown. Provide amount, or unit_price and quantity, or all three."""
tags: Iterable[LineItemTag]
- """Optional metadata tags for this line item"""
+ """Tags for the line item."""
class Tag(TypedDict, total=False):
- """A key-value tag pair for metadata"""
+ """A key-value tag pair for metadata."""
key: Required[str]
- """Tag key.
-
- Must be a valid safe string (no special characters like #, /, :). Max 50
- characters.
- """
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
value: Required[str]
- """Tag value.
-
- Must be a valid safe string (no special characters like #, /, :). Max 200
- characters.
- """
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
diff --git a/src/fragment/types/invoice_create_response.py b/src/fragment/types/invoice_create_response.py
index eec755f..0199cce 100644
--- a/src/fragment/types/invoice_create_response.py
+++ b/src/fragment/types/invoice_create_response.py
@@ -8,4 +8,4 @@
class InvoiceCreateResponse(BaseModel):
data: Invoice
- """Invoice object"""
+ """Invoice object."""
diff --git a/src/fragment/types/invoice_list_history_response.py b/src/fragment/types/invoice_list_history_response.py
index ed3d106..af74d5b 100644
--- a/src/fragment/types/invoice_list_history_response.py
+++ b/src/fragment/types/invoice_list_history_response.py
@@ -1,579 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Union, Optional
-from typing_extensions import Literal, TypeAlias
+from typing import List
from .invoice import Invoice
from .._models import BaseModel
-__all__ = [
- "InvoiceListHistoryResponse",
- "Data",
- "DataDiff",
- "DataDiffAddDiffEntry",
- "DataDiffAddDiffEntryItem",
- "DataDiffAddDiffEntryItemPrice",
- "DataDiffAddDiffEntryItemTag",
- "DataDiffUpdateDiffEntry",
- "DataDiffUpdateDiffEntryNewPrice",
- "DataDiffUpdateDiffEntryOldPrice",
- "DataDiffDeleteDiffEntry",
- "DataDiffDeleteDiffEntryItem",
- "DataDiffDeleteDiffEntryItemPrice",
- "DataDiffDeleteDiffEntryItemTag",
-]
-
-
-class DataDiffAddDiffEntryItemPrice(BaseModel):
- """Price breakdown containing amount, unit price, and quantity"""
-
- amount: str
- """Total amount in smallest currency unit (represented as string for bigint)"""
-
- quantity: int
- """Quantity of units for this line item"""
-
- unit_price: str
- """Unit price in smallest currency unit (represented as string for bigint)"""
-
-
-class DataDiffAddDiffEntryItemTag(BaseModel):
- """A key-value tag pair"""
-
- key: str
- """Tag key"""
-
- value: str
- """Tag value"""
-
-
-class DataDiffAddDiffEntryItem(BaseModel):
- """Invoice line item object"""
-
- id: str
- """Unique identifier for the line item"""
-
- amount: str
- """Deprecated: use price.amount instead.
-
- Total amount in smallest currency unit (represented as string for bigint)
- """
-
- currency_code: Literal[
- "ADA",
- "BTC",
- "DAI",
- "ETH",
- "SOL",
- "USDC",
- "USDT",
- "USDG",
- "EURC",
- "CADC",
- "CADT",
- "XLM",
- "UNI",
- "BCH",
- "LTC",
- "AAVE",
- "LINK",
- "MATIC",
- "PTS",
- "AED",
- "AFN",
- "ALL",
- "AMD",
- "ANG",
- "AOA",
- "ARS",
- "AUD",
- "AWG",
- "AZN",
- "BAM",
- "BBD",
- "BDT",
- "BGN",
- "BHD",
- "BIF",
- "BMD",
- "BND",
- "BOB",
- "BRL",
- "BSD",
- "BTN",
- "BWP",
- "BYR",
- "BZD",
- "CAD",
- "CDF",
- "CHF",
- "CLP",
- "CNY",
- "COP",
- "CRC",
- "CUC",
- "CUP",
- "CVE",
- "CZK",
- "DJF",
- "DKK",
- "DOP",
- "DZD",
- "EGP",
- "ERN",
- "ETB",
- "EUR",
- "FJD",
- "FKP",
- "GBP",
- "GEL",
- "GGP",
- "GHS",
- "GIP",
- "GMD",
- "GNF",
- "GTQ",
- "GYD",
- "HKD",
- "HNL",
- "HRK",
- "HTG",
- "HUF",
- "IDR",
- "ILS",
- "IMP",
- "INR",
- "IQD",
- "IRR",
- "ISK",
- "JMD",
- "JOD",
- "JPY",
- "KES",
- "KGS",
- "KHR",
- "KMF",
- "KPW",
- "KRW",
- "KWD",
- "KYD",
- "KZT",
- "LAK",
- "LBP",
- "LKR",
- "LRD",
- "LSL",
- "LYD",
- "MAD",
- "MDL",
- "MGA",
- "MKD",
- "MMK",
- "MNT",
- "MOP",
- "MUR",
- "MVR",
- "MWK",
- "MXN",
- "MYR",
- "MZN",
- "NAD",
- "NGN",
- "NIO",
- "NOK",
- "NPR",
- "NZD",
- "OMR",
- "PAB",
- "PEN",
- "PGK",
- "PHP",
- "PKR",
- "PLN",
- "PYG",
- "QAR",
- "RON",
- "RSD",
- "RUB",
- "RWF",
- "SAR",
- "SBD",
- "SCR",
- "SDG",
- "SEK",
- "SGD",
- "SHP",
- "SLL",
- "SOS",
- "SPL",
- "SRD",
- "SVC",
- "SYP",
- "STN",
- "SZL",
- "THB",
- "TJS",
- "TMT",
- "TND",
- "TOP",
- "TRY",
- "TTD",
- "TVD",
- "TWD",
- "TZS",
- "UAH",
- "UGX",
- "USD",
- "UYU",
- "UZS",
- "VEF",
- "VND",
- "VUV",
- "WST",
- "XAF",
- "XCD",
- "XOF",
- "XPF",
- "YER",
- "ZAR",
- "ZMW",
- "LOGICAL",
- "CUSTOM",
- ]
- """Currency code (ISO 4217 or crypto)"""
-
- description: str
- """Description of the line item"""
-
- price: DataDiffAddDiffEntryItemPrice
- """Price breakdown containing amount, unit price, and quantity"""
-
- product_id: str
- """ID of the product/catalog item"""
-
- tags: List[DataDiffAddDiffEntryItemTag]
- """Metadata tags for this line item"""
-
- type: Literal["payin", "payout"]
- """The type of the line item"""
-
- user_id: str
- """External ID of the user associated with this line item"""
-
-
-class DataDiffAddDiffEntry(BaseModel):
- item: DataDiffAddDiffEntryItem
- """Invoice line item object"""
-
- op: Literal["add"]
- """A line item was added"""
-
-
-class DataDiffUpdateDiffEntryNewPrice(BaseModel):
- """Price breakdown containing amount, unit price, and quantity"""
-
- amount: str
- """Total amount in smallest currency unit (represented as string for bigint)"""
-
- quantity: int
- """Quantity of units for this line item"""
-
- unit_price: str
- """Unit price in smallest currency unit (represented as string for bigint)"""
-
-
-class DataDiffUpdateDiffEntryOldPrice(BaseModel):
- """Price breakdown containing amount, unit price, and quantity"""
-
- amount: str
- """Total amount in smallest currency unit (represented as string for bigint)"""
-
- quantity: int
- """Quantity of units for this line item"""
-
- unit_price: str
- """Unit price in smallest currency unit (represented as string for bigint)"""
-
-
-class DataDiffUpdateDiffEntry(BaseModel):
- id: str
- """ID of the updated line item"""
-
- new_amount: str
- """Deprecated: use new_price.amount instead. New amount after the update"""
-
- new_price: DataDiffUpdateDiffEntryNewPrice
- """Price breakdown containing amount, unit price, and quantity"""
-
- old_amount: str
- """Deprecated: use old_price.amount instead. Amount before the update"""
-
- old_price: DataDiffUpdateDiffEntryOldPrice
- """Price breakdown containing amount, unit price, and quantity"""
-
- op: Literal["update"]
- """A line item was updated"""
-
-
-class DataDiffDeleteDiffEntryItemPrice(BaseModel):
- """Price breakdown containing amount, unit price, and quantity"""
-
- amount: str
- """Total amount in smallest currency unit (represented as string for bigint)"""
-
- quantity: int
- """Quantity of units for this line item"""
-
- unit_price: str
- """Unit price in smallest currency unit (represented as string for bigint)"""
-
-
-class DataDiffDeleteDiffEntryItemTag(BaseModel):
- """A key-value tag pair"""
-
- key: str
- """Tag key"""
-
- value: str
- """Tag value"""
-
-
-class DataDiffDeleteDiffEntryItem(BaseModel):
- """Invoice line item object"""
-
- id: str
- """Unique identifier for the line item"""
-
- amount: str
- """Deprecated: use price.amount instead.
-
- Total amount in smallest currency unit (represented as string for bigint)
- """
-
- currency_code: Literal[
- "ADA",
- "BTC",
- "DAI",
- "ETH",
- "SOL",
- "USDC",
- "USDT",
- "USDG",
- "EURC",
- "CADC",
- "CADT",
- "XLM",
- "UNI",
- "BCH",
- "LTC",
- "AAVE",
- "LINK",
- "MATIC",
- "PTS",
- "AED",
- "AFN",
- "ALL",
- "AMD",
- "ANG",
- "AOA",
- "ARS",
- "AUD",
- "AWG",
- "AZN",
- "BAM",
- "BBD",
- "BDT",
- "BGN",
- "BHD",
- "BIF",
- "BMD",
- "BND",
- "BOB",
- "BRL",
- "BSD",
- "BTN",
- "BWP",
- "BYR",
- "BZD",
- "CAD",
- "CDF",
- "CHF",
- "CLP",
- "CNY",
- "COP",
- "CRC",
- "CUC",
- "CUP",
- "CVE",
- "CZK",
- "DJF",
- "DKK",
- "DOP",
- "DZD",
- "EGP",
- "ERN",
- "ETB",
- "EUR",
- "FJD",
- "FKP",
- "GBP",
- "GEL",
- "GGP",
- "GHS",
- "GIP",
- "GMD",
- "GNF",
- "GTQ",
- "GYD",
- "HKD",
- "HNL",
- "HRK",
- "HTG",
- "HUF",
- "IDR",
- "ILS",
- "IMP",
- "INR",
- "IQD",
- "IRR",
- "ISK",
- "JMD",
- "JOD",
- "JPY",
- "KES",
- "KGS",
- "KHR",
- "KMF",
- "KPW",
- "KRW",
- "KWD",
- "KYD",
- "KZT",
- "LAK",
- "LBP",
- "LKR",
- "LRD",
- "LSL",
- "LYD",
- "MAD",
- "MDL",
- "MGA",
- "MKD",
- "MMK",
- "MNT",
- "MOP",
- "MUR",
- "MVR",
- "MWK",
- "MXN",
- "MYR",
- "MZN",
- "NAD",
- "NGN",
- "NIO",
- "NOK",
- "NPR",
- "NZD",
- "OMR",
- "PAB",
- "PEN",
- "PGK",
- "PHP",
- "PKR",
- "PLN",
- "PYG",
- "QAR",
- "RON",
- "RSD",
- "RUB",
- "RWF",
- "SAR",
- "SBD",
- "SCR",
- "SDG",
- "SEK",
- "SGD",
- "SHP",
- "SLL",
- "SOS",
- "SPL",
- "SRD",
- "SVC",
- "SYP",
- "STN",
- "SZL",
- "THB",
- "TJS",
- "TMT",
- "TND",
- "TOP",
- "TRY",
- "TTD",
- "TVD",
- "TWD",
- "TZS",
- "UAH",
- "UGX",
- "USD",
- "UYU",
- "UZS",
- "VEF",
- "VND",
- "VUV",
- "WST",
- "XAF",
- "XCD",
- "XOF",
- "XPF",
- "YER",
- "ZAR",
- "ZMW",
- "LOGICAL",
- "CUSTOM",
- ]
- """Currency code (ISO 4217 or crypto)"""
-
- description: str
- """Description of the line item"""
-
- price: DataDiffDeleteDiffEntryItemPrice
- """Price breakdown containing amount, unit price, and quantity"""
-
- product_id: str
- """ID of the product/catalog item"""
-
- tags: List[DataDiffDeleteDiffEntryItemTag]
- """Metadata tags for this line item"""
-
- type: Literal["payin", "payout"]
- """The type of the line item"""
-
- user_id: str
- """External ID of the user associated with this line item"""
-
-
-class DataDiffDeleteDiffEntry(BaseModel):
- item: DataDiffDeleteDiffEntryItem
- """Invoice line item object"""
-
- op: Literal["delete"]
- """A line item was deleted"""
-
-
-DataDiff: TypeAlias = Union[DataDiffAddDiffEntry, DataDiffUpdateDiffEntry, DataDiffDeleteDiffEntry]
-
-
-class Data(Invoice):
- """A versioned snapshot of an invoice"""
-
- diff: Optional[List[DataDiff]] = None
- """Cumulative diff of changes applied to the invoice"""
-
- version: Optional[float] = None # type: ignore
- """Version number of this invoice snapshot"""
+__all__ = ["InvoiceListHistoryResponse"]
class InvoiceListHistoryResponse(BaseModel):
- """Version history of an invoice"""
-
- data: List[Data]
+ data: List[Invoice]
+ """Version history of the invoice."""
diff --git a/src/fragment/types/invoice_list_response.py b/src/fragment/types/invoice_list_response.py
index 8f42ec0..b9a2949 100644
--- a/src/fragment/types/invoice_list_response.py
+++ b/src/fragment/types/invoice_list_response.py
@@ -9,6 +9,5 @@
class InvoiceListResponse(BaseModel):
- """List of invoices"""
-
data: List[Invoice]
+ """List of invoices."""
diff --git a/src/fragment/types/invoice_retrieve_response.py b/src/fragment/types/invoice_retrieve_response.py
index a0d6748..77389ce 100644
--- a/src/fragment/types/invoice_retrieve_response.py
+++ b/src/fragment/types/invoice_retrieve_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import List
from datetime import datetime
from typing_extensions import Literal
@@ -27,87 +27,117 @@
class DataBalanceNet(BaseModel):
+ """Net balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataBalancePayins(BaseModel):
+ """Payins balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataBalancePayouts(BaseModel):
+ """Payouts balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataBalance(BaseModel):
currency: str
- """Currency code"""
+ """ISO 4217 or crypto currency code."""
net: DataBalanceNet
+ """Net balance breakdown."""
payins: DataBalancePayins
+ """Payins balance breakdown."""
payouts: DataBalancePayouts
+ """Payouts balance breakdown."""
class DataPaymentTransactionTag(BaseModel):
- """A key-value tag pair"""
+ """A key-value tag pair."""
key: str
- """Tag key"""
+ """Tag key."""
value: str
- """Tag value"""
+ """Tag value."""
class DataPaymentTransaction(BaseModel):
- """Reference to a transaction by encoded ID and external ID."""
+ """Transaction the payment is applied to."""
id: str
- """Encoded transaction ID."""
+ """FRAGMENT generated unique ID."""
external_id: str
- """External transaction ID."""
+ """User-provided unique ID."""
tags: List[DataPaymentTransactionTag]
- """Metadata tags from the parent transaction."""
+ """Tags from the parent transaction."""
class DataPaymentUser(BaseModel):
- """User reference in API responses: Fragment user id and optional external_id."""
+ """User associated with the payment."""
id: str
- """FRAGMENT generated ID of the user"""
+ """FRAGMENT generated unique ID."""
- external_id: Optional[str] = None
- """External ID of the user"""
+ external_id: str
+ """User-provided unique ID."""
class DataPayment(BaseModel):
- """A payment allocated to this invoice."""
+ """A payment allocated to the invoice."""
amount: str
- """Amount allocated in smallest currency unit as stringified bigint."""
+ """
+ Amount allocated as a string in the smallest currency unit, such as cents for
+ USD.
+ """
currency: Literal[
"ADA",
@@ -290,86 +320,116 @@ class DataPayment(BaseModel):
"LOGICAL",
"CUSTOM",
]
- """Currency code (ISO 4217 or crypto)"""
+ """ISO 4217 or crypto currency code."""
posted: datetime
- """Posted timestamp of the parent transaction in ISO 8601 format."""
+ """Timestamp when the parent transaction was posted. Uses ISO 8601 format."""
transaction: DataPaymentTransaction
- """Reference to a transaction by encoded ID and external ID."""
+ """Transaction the payment is applied to."""
type: Literal["payin", "payout"]
- """The type of the payment."""
+ """Type of the payment."""
user: DataPaymentUser
- """User reference in API responses: Fragment user id and optional external_id."""
+ """User associated with the payment."""
class DataUserBalanceNet(BaseModel):
+ """Net balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataUserBalancePayins(BaseModel):
+ """Payins balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataUserBalancePayouts(BaseModel):
+ """Payouts balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataUserBalance(BaseModel):
currency: str
- """Currency code"""
+ """ISO 4217 or crypto currency code."""
net: DataUserBalanceNet
+ """Net balance breakdown."""
payins: DataUserBalancePayins
+ """Payins balance breakdown."""
payouts: DataUserBalancePayouts
+ """Payouts balance breakdown."""
class DataUser(BaseModel):
id: str
- """User/party ID"""
+ """User-provided unique external ID."""
balances: List[DataUserBalance]
- """Per-currency balance breakdown for this user"""
+ """Per-currency balance breakdown for the user."""
+
+ external_id: str
+ """User-provided unique ID."""
class Data(Invoice):
- """Invoice with balance details"""
+ """Invoice with balance details."""
balances: List[DataBalance]
- """Invoice-level balances by currency: payins, payouts, and net (payins - payouts)"""
+ """Invoice-level balances by currency."""
payments: List[DataPayment]
- """Transaction allocations (payments) associated with this invoice."""
+ """Payments allocated to the invoice."""
users: List[DataUser]
- """Users/parties involved in the invoice"""
+ """Users involved in the invoice."""
class InvoiceRetrieveResponse(BaseModel):
data: Data
- """Invoice with balance details"""
+ """Invoice with balance details."""
diff --git a/src/fragment/types/invoice_search_params.py b/src/fragment/types/invoice_search_params.py
index c10ea93..f63f61e 100644
--- a/src/fragment/types/invoice_search_params.py
+++ b/src/fragment/types/invoice_search_params.py
@@ -3,17 +3,17 @@
from __future__ import annotations
from typing import Iterable
-from typing_extensions import Required, TypedDict
+from typing_extensions import Literal, Required, TypedDict
__all__ = ["InvoiceSearchParams", "Filter", "FilterTags", "FilterTagsAll", "FilterTagsAny", "PageInfo"]
class InvoiceSearchParams(TypedDict, total=False):
filter: Required[Filter]
- """Filter criteria for the search"""
+ """Filter criteria for the search."""
- page_info: Required[PageInfo]
- """Pagination parameters"""
+ page_info: PageInfo
+ """Pagination parameters."""
class FilterTagsAll(TypedDict, total=False):
@@ -53,14 +53,20 @@ class FilterTags(TypedDict, total=False):
"""
all: Iterable[FilterTagsAll]
- """Returns invoices matching every specified tag (AND)."""
+ """Returns invoices matching every specified tag, using AND logic."""
any: Iterable[FilterTagsAny]
- """Returns invoices matching at least one of the specified tags (OR)."""
+ """Returns invoices matching at least one of the specified tags, using OR logic."""
class Filter(TypedDict, total=False):
- """Filter criteria for the search"""
+ """Filter criteria for the search."""
+
+ status: Literal["open"]
+ """Filter by invoice status.
+
+ `open` returns invoices with non-zero clearing account balances.
+ """
tags: FilterTags
"""Tag-based filter criteria.
@@ -71,10 +77,10 @@ class Filter(TypedDict, total=False):
class PageInfo(TypedDict, total=False):
- """Pagination parameters"""
+ """Pagination parameters."""
after: str
- """Cursor for fetching the next page of results"""
+ """Cursor for fetching the next page of results."""
limit: int
"""Number of results to return. Defaults to 20."""
diff --git a/src/fragment/types/invoice_search_response.py b/src/fragment/types/invoice_search_response.py
index 57102c0..fa1ed31 100644
--- a/src/fragment/types/invoice_search_response.py
+++ b/src/fragment/types/invoice_search_response.py
@@ -29,87 +29,117 @@
class DataInvoiceBalanceNet(BaseModel):
+ """Net balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataInvoiceBalancePayins(BaseModel):
+ """Payins balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataInvoiceBalancePayouts(BaseModel):
+ """Payouts balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataInvoiceBalance(BaseModel):
currency: str
- """Currency code"""
+ """ISO 4217 or crypto currency code."""
net: DataInvoiceBalanceNet
+ """Net balance breakdown."""
payins: DataInvoiceBalancePayins
+ """Payins balance breakdown."""
payouts: DataInvoiceBalancePayouts
+ """Payouts balance breakdown."""
class DataInvoicePaymentTransactionTag(BaseModel):
- """A key-value tag pair"""
+ """A key-value tag pair."""
key: str
- """Tag key"""
+ """Tag key."""
value: str
- """Tag value"""
+ """Tag value."""
class DataInvoicePaymentTransaction(BaseModel):
- """Reference to a transaction by encoded ID and external ID."""
+ """Transaction the payment is applied to."""
id: str
- """Encoded transaction ID."""
+ """FRAGMENT generated unique ID."""
external_id: str
- """External transaction ID."""
+ """User-provided unique ID."""
tags: List[DataInvoicePaymentTransactionTag]
- """Metadata tags from the parent transaction."""
+ """Tags from the parent transaction."""
class DataInvoicePaymentUser(BaseModel):
- """User reference in API responses: Fragment user id and optional external_id."""
+ """User associated with the payment."""
id: str
- """FRAGMENT generated ID of the user"""
+ """FRAGMENT generated unique ID."""
- external_id: Optional[str] = None
- """External ID of the user"""
+ external_id: str
+ """User-provided unique ID."""
class DataInvoicePayment(BaseModel):
- """A payment allocated to this invoice."""
+ """A payment allocated to the invoice."""
amount: str
- """Amount allocated in smallest currency unit as stringified bigint."""
+ """
+ Amount allocated as a string in the smallest currency unit, such as cents for
+ USD.
+ """
currency: Literal[
"ADA",
@@ -292,102 +322,135 @@ class DataInvoicePayment(BaseModel):
"LOGICAL",
"CUSTOM",
]
- """Currency code (ISO 4217 or crypto)"""
+ """ISO 4217 or crypto currency code."""
posted: datetime
- """Posted timestamp of the parent transaction in ISO 8601 format."""
+ """Timestamp when the parent transaction was posted. Uses ISO 8601 format."""
transaction: DataInvoicePaymentTransaction
- """Reference to a transaction by encoded ID and external ID."""
+ """Transaction the payment is applied to."""
type: Literal["payin", "payout"]
- """The type of the payment."""
+ """Type of the payment."""
user: DataInvoicePaymentUser
- """User reference in API responses: Fragment user id and optional external_id."""
+ """User associated with the payment."""
class DataInvoiceUserBalanceNet(BaseModel):
+ """Net balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataInvoiceUserBalancePayins(BaseModel):
+ """Payins balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataInvoiceUserBalancePayouts(BaseModel):
+ """Payouts balance breakdown."""
+
actual: str
- """Actual amount (represented as string)"""
+ """Actual amount as a string in the smallest currency unit, such as cents for USD."""
expected: str
- """Expected amount (represented as string)"""
+ """
+ Expected amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
remaining: str
- """Remaining amount (expected - actual, represented as string)"""
+ """
+ Remaining amount as a string in the smallest currency unit, such as cents for
+ USD.
+ """
class DataInvoiceUserBalance(BaseModel):
currency: str
- """Currency code"""
+ """ISO 4217 or crypto currency code."""
net: DataInvoiceUserBalanceNet
+ """Net balance breakdown."""
payins: DataInvoiceUserBalancePayins
+ """Payins balance breakdown."""
payouts: DataInvoiceUserBalancePayouts
+ """Payouts balance breakdown."""
class DataInvoiceUser(BaseModel):
id: str
- """User/party ID"""
+ """User-provided unique external ID."""
balances: List[DataInvoiceUserBalance]
- """Per-currency balance breakdown for this user"""
+ """Per-currency balance breakdown for the user."""
+
+ external_id: str
+ """User-provided unique ID."""
class DataInvoice(Invoice):
- """Invoice with balance details"""
+ """Invoice with balance details."""
balances: List[DataInvoiceBalance]
- """Invoice-level balances by currency: payins, payouts, and net (payins - payouts)"""
+ """Invoice-level balances by currency."""
payments: List[DataInvoicePayment]
- """Transaction allocations (payments) associated with this invoice."""
+ """Payments allocated to the invoice."""
users: List[DataInvoiceUser]
- """Users/parties involved in the invoice"""
+ """Users involved in the invoice."""
class DataPageInfo(BaseModel):
"""Pagination cursors."""
next_cursor: Optional[str] = None
- """Cursor to fetch the next page of results"""
+ """Cursor to fetch the next page of results."""
class Data(BaseModel):
+ """Search results for invoices."""
+
invoices: List[DataInvoice]
- """List of invoices matching the search criteria"""
+ """Invoices matching the search criteria."""
page_info: DataPageInfo
"""Pagination cursors."""
class InvoiceSearchResponse(BaseModel):
- """Response body for searching invoices"""
+ """Search results for invoices."""
data: Data
+ """Search results for invoices."""
diff --git a/src/fragment/types/invoice_update_params.py b/src/fragment/types/invoice_update_params.py
index ad3ca78..c29afab 100644
--- a/src/fragment/types/invoice_update_params.py
+++ b/src/fragment/types/invoice_update_params.py
@@ -20,91 +20,88 @@
"LineItemsUpdateTags",
"LineItemsUpdateTagsCreate",
"LineItemsUpdateTagsDelete",
+ "LineItemsUpdateTagsSet",
"LineItemsUpdateTagsUpdate",
"Tags",
"TagsCreate",
"TagsDelete",
+ "TagsSet",
"TagsUpdate",
]
class InvoiceUpdateParams(TypedDict, total=False):
current_invoice_version: Required[float]
- """The current version of the invoice.
-
- Must match the stored version for the update to succeed (optimistic
- concurrency).
- """
+ """Current version of the invoice. Must match the stored version."""
line_items: LineItems
+ """Line item updates."""
tags: Tags
+ """Tag updates."""
class LineItemsCreateUserID(TypedDict, total=False):
id: Required[str]
- """FRAGMENT generated ID of the user"""
+ """FRAGMENT generated unique ID."""
class LineItemsCreateUserExternalID(TypedDict, total=False):
external_id: Required[str]
- """External ID of the user"""
+ """User-provided unique ID."""
LineItemsCreateUser: TypeAlias = Union[LineItemsCreateUserID, LineItemsCreateUserExternalID]
class LineItemsCreatePrice(TypedDict, total=False):
- """Price breakdown. Provide amount, or unit_price + quantity, or all three."""
+ """Price breakdown. Provide amount, or unit_price and quantity, or all three."""
amount: str
- """Total amount in smallest currency unit.
+ """Total amount as a string in the smallest currency unit, such as cents for USD.
Required if unit_price and quantity are not provided.
"""
quantity: int
- """Number of units for this line item."""
+ """Number of units for the line item."""
unit_price: str
- """Price per unit in smallest currency unit."""
+ """
+ Price per unit as a string in the smallest currency unit, such as cents for USD.
+ """
class LineItemsCreateTag(TypedDict, total=False):
- """A key-value tag pair for metadata"""
+ """A key-value tag pair for metadata."""
key: Required[str]
- """Tag key.
-
- Must be a valid safe string (no special characters like #, /, :). Max 50
- characters.
- """
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
value: Required[str]
- """Tag value.
-
- Must be a valid safe string (no special characters like #, /, :). Max 200
- characters.
- """
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
class LineItemsCreate(TypedDict, total=False):
"""Data to create a line item."""
description: Required[str]
- """Description of the line item"""
+ """Description of the line item."""
product_id: Required[str]
- """ID of the product/catalog item"""
+ """Unique identifier for the product."""
type: Required[Literal["payin", "payout"]]
- """The type of the line item"""
+ """Type of the line item."""
user: Required[LineItemsCreateUser]
- """Identifies a user by Fragment-generated id or external_id (request body)."""
+ """Identifies a user by `id` or `external_id`."""
amount: str
- """Deprecated: use price instead. Total amount in smallest currency unit."""
+ """Total amount as a string in the smallest currency unit, such as cents for USD.
+
+ Deprecated, use price instead.
+ """
currency_code: Literal[
"ADA",
@@ -287,160 +284,157 @@ class LineItemsCreate(TypedDict, total=False):
"LOGICAL",
"CUSTOM",
]
- """Currency code (ISO 4217 or crypto)"""
+ """ISO 4217 or crypto currency code."""
price: LineItemsCreatePrice
- """Price breakdown. Provide amount, or unit_price + quantity, or all three."""
+ """Price breakdown. Provide amount, or unit_price and quantity, or all three."""
tags: Iterable[LineItemsCreateTag]
- """Optional metadata tags for this line item"""
+ """Tags for the line item."""
class LineItemsDelete(TypedDict, total=False):
id: Required[str]
- """ID of the line item to delete"""
+ """Unique identifier for the line item to delete."""
class LineItemsUpdatePrice(TypedDict, total=False):
quantity: Required[int]
- """Number of units for this line item."""
+ """Number of units for the line item."""
unit_price: Required[str]
- """Price per unit in smallest currency unit."""
+ """
+ Price per unit as a string in the smallest currency unit, such as cents for USD.
+ """
amount: str
- """Total amount in smallest currency unit."""
+ """Total amount as a string in the smallest currency unit, such as cents for USD."""
class LineItemsUpdateTagsCreate(TypedDict, total=False):
- """A key-value tag pair for metadata"""
+ """A key-value tag pair for metadata."""
key: Required[str]
- """Tag key.
-
- Must be a valid safe string (no special characters like #, /, :). Max 50
- characters.
- """
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
value: Required[str]
- """Tag value.
-
- Must be a valid safe string (no special characters like #, /, :). Max 200
- characters.
- """
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
class LineItemsUpdateTagsDelete(TypedDict, total=False):
key: Required[str]
- """Tag key to delete"""
+ """Tag key to delete."""
-class LineItemsUpdateTagsUpdate(TypedDict, total=False):
- """A key-value tag pair for metadata"""
+class LineItemsUpdateTagsSet(TypedDict, total=False):
+ """A key-value tag pair for metadata."""
key: Required[str]
- """Tag key.
-
- Must be a valid safe string (no special characters like #, /, :). Max 50
- characters.
- """
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
value: Required[str]
- """Tag value.
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
- Must be a valid safe string (no special characters like #, /, :). Max 200
- characters.
- """
+
+class LineItemsUpdateTagsUpdate(TypedDict, total=False):
+ """A key-value tag pair for metadata."""
+
+ key: Required[str]
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
+
+ value: Required[str]
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
class LineItemsUpdateTags(TypedDict, total=False):
+ """Tag updates."""
+
create: Iterable[LineItemsUpdateTagsCreate]
- """Tags to add"""
+ """Tags to create. The tag key must not already exist."""
delete: Iterable[LineItemsUpdateTagsDelete]
- """Tags to remove by key"""
+ """Tags to remove."""
- update: Iterable[LineItemsUpdateTagsUpdate]
- """Tags to update.
+ set: Iterable[LineItemsUpdateTagsSet]
+ """Tags to set. Creates a new tag or updates an existing tag."""
- The key identifies the existing tag; the value is the new value.
- """
+ update: Iterable[LineItemsUpdateTagsUpdate]
+ """Tags to update. The tag key must already exist."""
class LineItemsUpdate(TypedDict, total=False):
- """Partial update for an existing line item. All fields except id are optional."""
+ """Data for updating a line item."""
id: Required[str]
- """ID of the line item to update"""
+ """Unique identifier for the line item to update."""
description: str
price: LineItemsUpdatePrice
tags: LineItemsUpdateTags
+ """Tag updates."""
class LineItems(TypedDict, total=False):
+ """Line item updates."""
+
create: Iterable[LineItemsCreate]
- """Line items to add to the invoice"""
+ """Line items to add to the invoice."""
delete: Iterable[LineItemsDelete]
- """Line items to remove from the invoice"""
+ """Line items to remove from the invoice."""
update: Iterable[LineItemsUpdate]
- """Existing line items to update"""
+ """Existing line items to update."""
class TagsCreate(TypedDict, total=False):
- """A key-value tag pair for metadata"""
+ """A key-value tag pair for metadata."""
key: Required[str]
- """Tag key.
-
- Must be a valid safe string (no special characters like #, /, :). Max 50
- characters.
- """
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
value: Required[str]
- """Tag value.
-
- Must be a valid safe string (no special characters like #, /, :). Max 200
- characters.
- """
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
class TagsDelete(TypedDict, total=False):
key: Required[str]
- """Tag key to delete"""
+ """Tag key to delete."""
-class TagsUpdate(TypedDict, total=False):
- """A key-value tag pair for metadata"""
+class TagsSet(TypedDict, total=False):
+ """A key-value tag pair for metadata."""
key: Required[str]
- """Tag key.
-
- Must be a valid safe string (no special characters like #, /, :). Max 50
- characters.
- """
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
value: Required[str]
- """Tag value.
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
- Must be a valid safe string (no special characters like #, /, :). Max 200
- characters.
- """
+
+class TagsUpdate(TypedDict, total=False):
+ """A key-value tag pair for metadata."""
+
+ key: Required[str]
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
+
+ value: Required[str]
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
class Tags(TypedDict, total=False):
+ """Tag updates."""
+
create: Iterable[TagsCreate]
- """Tags to add"""
+ """Tags to create. The tag key must not already exist."""
delete: Iterable[TagsDelete]
- """Tags to remove by key"""
+ """Tags to remove."""
- update: Iterable[TagsUpdate]
- """Tags to update.
+ set: Iterable[TagsSet]
+ """Tags to set. Creates a new tag or updates an existing tag."""
- The key identifies the existing tag; the value is the new value.
- """
+ update: Iterable[TagsUpdate]
+ """Tags to update. The tag key must already exist."""
diff --git a/src/fragment/types/invoice_update_response.py b/src/fragment/types/invoice_update_response.py
index 4f8409a..2ceb944 100644
--- a/src/fragment/types/invoice_update_response.py
+++ b/src/fragment/types/invoice_update_response.py
@@ -8,4 +8,4 @@
class InvoiceUpdateResponse(BaseModel):
data: Invoice
- """Invoice object"""
+ """Invoice object."""
diff --git a/src/fragment/types/product.py b/src/fragment/types/product.py
index 23f9c30..66b73b8 100644
--- a/src/fragment/types/product.py
+++ b/src/fragment/types/product.py
@@ -12,45 +12,45 @@ class PaidByRole(BaseModel):
"""Role reference in product API responses."""
id: str
- """The unique ID of the role"""
+ """FRAGMENT generated unique ID."""
name: str
- """The name of the role"""
+ """Name of the role."""
class PaidToRole(BaseModel):
"""Role reference in product API responses."""
id: str
- """The unique ID of the role"""
+ """FRAGMENT generated unique ID."""
name: str
- """The name of the role"""
+ """Name of the role."""
class Product(BaseModel):
- """Product object"""
+ """Product object."""
id: str
- """Unique identifier for the product"""
+ """FRAGMENT generated unique ID."""
code: str
- """User-defined product identifier."""
+ """Product code."""
created: datetime
- """ISO 8601 timestamp when the product was created"""
+ """Timestamp when the product was created. Uses ISO 8601 format."""
paid_by_roles: List[PaidByRole]
- """User roles that can pay for this product"""
+ """Roles that can pay for the product."""
paid_to_roles: List[PaidToRole]
- """User roles that receive payment for this product"""
+ """Roles that can receive payment for the product."""
update_version: float
- """Version number for optimistic locking"""
+ """Current version of the product."""
workspace_id: str
- """Workspace ID this product belongs to"""
+ """Workspace ID of the product."""
description: Optional[str] = None
- """Description of the product"""
+ """Product description."""
diff --git a/src/fragment/types/product_create_params.py b/src/fragment/types/product_create_params.py
index 99c8cba..07e7515 100644
--- a/src/fragment/types/product_create_params.py
+++ b/src/fragment/types/product_create_params.py
@@ -18,34 +18,34 @@
class ProductCreateParams(TypedDict, total=False):
code: Required[str]
- """Product code (unique identifier)"""
+ """Unique product code."""
description: str
- """Description of the product"""
+ """Product description."""
paid_by_roles: Iterable[PaidByRole]
- """Roles that can pay for this product.
+ """Roles that can pay for the product.
- Reference roles by id or name. At least one of paid_by_roles or paid_to_roles
- must be provided.
+ Reference roles by `id` or `name`. At least one of `paid_by_roles` or
+ `paid_to_roles` must be provided.
"""
paid_to_roles: Iterable[PaidToRole]
- """Roles that receive payment for this product.
+ """Roles that can receive payment for the product.
- Reference roles by id or name. At least one of paid_by_roles or paid_to_roles
- must be provided.
+ Reference roles by `id` or `name`. At least one of `paid_by_roles` or
+ `paid_to_roles` must be provided.
"""
class PaidByRoleID(TypedDict, total=False):
id: Required[str]
- """The unique ID of the role"""
+ """FRAGMENT generated unique ID."""
class PaidByRoleName(TypedDict, total=False):
name: Required[str]
- """The name of the role"""
+ """Name of the role."""
PaidByRole: TypeAlias = Union[PaidByRoleID, PaidByRoleName]
@@ -53,12 +53,12 @@ class PaidByRoleName(TypedDict, total=False):
class PaidToRoleID(TypedDict, total=False):
id: Required[str]
- """The unique ID of the role"""
+ """FRAGMENT generated unique ID."""
class PaidToRoleName(TypedDict, total=False):
name: Required[str]
- """The name of the role"""
+ """Name of the role."""
PaidToRole: TypeAlias = Union[PaidToRoleID, PaidToRoleName]
diff --git a/src/fragment/types/product_create_response.py b/src/fragment/types/product_create_response.py
index f921f55..389e24b 100644
--- a/src/fragment/types/product_create_response.py
+++ b/src/fragment/types/product_create_response.py
@@ -8,4 +8,4 @@
class ProductCreateResponse(BaseModel):
data: Product
- """Product object"""
+ """Product object."""
diff --git a/src/fragment/types/product_list_response.py b/src/fragment/types/product_list_response.py
index 8b2c8b1..7c4e7c6 100644
--- a/src/fragment/types/product_list_response.py
+++ b/src/fragment/types/product_list_response.py
@@ -9,6 +9,5 @@
class ProductListResponse(BaseModel):
- """List of products"""
-
data: List[Product]
+ """List of products."""
diff --git a/src/fragment/types/product_retrieve_response.py b/src/fragment/types/product_retrieve_response.py
index ab4a8dc..594d653 100644
--- a/src/fragment/types/product_retrieve_response.py
+++ b/src/fragment/types/product_retrieve_response.py
@@ -8,4 +8,4 @@
class ProductRetrieveResponse(BaseModel):
data: Product
- """Product object"""
+ """Product object."""
diff --git a/src/fragment/types/role.py b/src/fragment/types/role.py
index d094b48..0716049 100644
--- a/src/fragment/types/role.py
+++ b/src/fragment/types/role.py
@@ -6,10 +6,10 @@
class Role(BaseModel):
- """Role object"""
+ """Role object."""
id: str
- """Unique role ID"""
+ """FRAGMENT generated unique ID."""
role: str
- """Name of the role"""
+ """Name of the role."""
diff --git a/src/fragment/types/role_create_params.py b/src/fragment/types/role_create_params.py
index 855e332..cde32ed 100644
--- a/src/fragment/types/role_create_params.py
+++ b/src/fragment/types/role_create_params.py
@@ -9,4 +9,4 @@
class RoleCreateParams(TypedDict, total=False):
role: Required[str]
- """Name of the role"""
+ """Name of the role."""
diff --git a/src/fragment/types/role_create_response.py b/src/fragment/types/role_create_response.py
index 9f1dedd..c3baf28 100644
--- a/src/fragment/types/role_create_response.py
+++ b/src/fragment/types/role_create_response.py
@@ -8,4 +8,4 @@
class RoleCreateResponse(BaseModel):
data: Role
- """Role object"""
+ """Role object."""
diff --git a/src/fragment/types/role_list_response.py b/src/fragment/types/role_list_response.py
index f945539..0d8c7f9 100644
--- a/src/fragment/types/role_list_response.py
+++ b/src/fragment/types/role_list_response.py
@@ -9,6 +9,7 @@
class RoleListResponse(BaseModel):
- """List of roles"""
+ """List of roles."""
data: List[Role]
+ """List of roles."""
diff --git a/src/fragment/types/transaction.py b/src/fragment/types/transaction.py
index c6f9908..b1ce279 100644
--- a/src/fragment/types/transaction.py
+++ b/src/fragment/types/transaction.py
@@ -10,70 +10,74 @@
class Account(BaseModel):
- """External account reference on transaction responses."""
+ """External account for the transaction."""
id: str
- """User-facing encoded account ID."""
+ """FRAGMENT generated unique ID."""
external_id: str
- """External account reference ID."""
+ """User-provided unique ID."""
class AllocationUser(BaseModel):
- """User reference in API responses: Fragment user id and optional external_id."""
+ """User associated with the allocation."""
id: str
- """FRAGMENT generated ID of the user"""
+ """FRAGMENT generated unique ID."""
- external_id: Optional[str] = None
- """External ID of the user"""
+ external_id: str
+ """User-provided unique ID."""
class Allocation(BaseModel):
- """Transaction allocation against an invoice."""
+ """An allocation linking a transaction to an invoice."""
amount: str
- """Amount to allocate in smallest currency unit as stringified bigint."""
+ """
+ Allocated amount, as a positive string in the smallest currency unit, such as
+ cents for USD.
+ """
invoice_id: str
- """The invoice to allocate against."""
+ """Invoice the allocation is applied against."""
type: Literal["invoice_payin", "invoice_payout"]
- """The type of allocation."""
+ """Type of allocation."""
user: AllocationUser
- """User reference in API responses: Fragment user id and optional external_id."""
+ """User associated with the allocation."""
class Tag(BaseModel):
- """A key-value tag pair"""
+ """A key-value tag pair."""
key: str
- """Tag key"""
+ """Tag key."""
value: str
- """Tag value"""
+ """Tag value."""
class Transaction(BaseModel):
"""Transaction object."""
id: str
- """User-facing encoded transaction ID."""
+ """FRAGMENT generated unique ID."""
account: Account
- """External account reference on transaction responses."""
+ """External account for the transaction."""
allocations: List[Allocation]
+ """Allocations applied to the transaction."""
amount: str
"""
- Amount in smallest currency unit as stringified bigint (can be positive or
- negative).
+ Transaction amount, as a string in the smallest currency unit, such as cents for
+ USD. Can be positive or negative.
"""
created: datetime
- """Creation timestamp."""
+ """Timestamp when the transaction was created. Uses ISO 8601 format."""
currency: Literal[
"ADA",
@@ -256,22 +260,22 @@ class Transaction(BaseModel):
"LOGICAL",
"CUSTOM",
]
- """Currency code (ISO 4217 or crypto)"""
+ """ISO 4217 or crypto currency code."""
external_id: str
- """External idempotency key provided by the user."""
+ """User-provided unique ID."""
posted: datetime
- """Posted timestamp in ISO 8601 format."""
+ """Timestamp when the transaction was posted. Uses ISO 8601 format."""
tags: List[Tag]
- """Metadata tags associated with this transaction."""
+ """Tags for the transaction."""
unallocated_amount: str
- """Read-only amount not yet allocated."""
+ """Amount not yet allocated, as a string."""
version: int
- """Current version of the transaction, used for optimistic concurrency control."""
+ """Current version of the transaction."""
modified: Optional[datetime] = None
- """Last modified timestamp."""
+ """Timestamp when the transaction was last modified. Uses ISO 8601 format."""
diff --git a/src/fragment/types/transaction_create_allocations_params.py b/src/fragment/types/transaction_create_allocations_params.py
deleted file mode 100644
index 1885ef8..0000000
--- a/src/fragment/types/transaction_create_allocations_params.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union, Iterable
-from typing_extensions import Literal, Required, TypeAlias, TypedDict
-
-__all__ = [
- "TransactionCreateAllocationsParams",
- "AllocationUpdate",
- "AllocationUpdateAddAllocationOperation",
- "AllocationUpdateAddAllocationOperationUser",
- "AllocationUpdateAddAllocationOperationUserID",
- "AllocationUpdateAddAllocationOperationUserExternalID",
- "AllocationUpdateDeleteAllocationOperation",
-]
-
-
-class TransactionCreateAllocationsParams(TypedDict, total=False):
- allocation_updates: Required[Iterable[AllocationUpdate]]
- """Allocation operations to apply"""
-
- version: Required[int]
- """Current transaction version for optimistic concurrency control"""
-
-
-class AllocationUpdateAddAllocationOperationUserID(TypedDict, total=False):
- id: Required[str]
- """FRAGMENT generated ID of the user"""
-
-
-class AllocationUpdateAddAllocationOperationUserExternalID(TypedDict, total=False):
- external_id: Required[str]
- """External ID of the user"""
-
-
-AllocationUpdateAddAllocationOperationUser: TypeAlias = Union[
- AllocationUpdateAddAllocationOperationUserID, AllocationUpdateAddAllocationOperationUserExternalID
-]
-
-
-class AllocationUpdateAddAllocationOperation(TypedDict, total=False):
- amount: Required[str]
- """Amount to allocate in smallest currency unit as stringified bigint."""
-
- invoice_id: Required[str]
- """The invoice to allocate against."""
-
- op: Required[Literal["add"]]
- """Add a new allocation"""
-
- type: Required[Literal["invoice_payin", "invoice_payout"]]
- """The type of allocation."""
-
- user: Required[AllocationUpdateAddAllocationOperationUser]
- """Identifies a user by Fragment-generated id or external_id (request body)."""
-
-
-class AllocationUpdateDeleteAllocationOperation(TypedDict, total=False):
- id: Required[str]
- """The ID of the allocation to remove."""
-
- op: Required[Literal["delete"]]
- """Delete an allocation"""
-
-
-AllocationUpdate: TypeAlias = Union[AllocationUpdateAddAllocationOperation, AllocationUpdateDeleteAllocationOperation]
diff --git a/src/fragment/types/transaction_create_params.py b/src/fragment/types/transaction_create_params.py
index 8af2d0c..847df59 100644
--- a/src/fragment/types/transaction_create_params.py
+++ b/src/fragment/types/transaction_create_params.py
@@ -21,15 +21,18 @@
class TransactionCreateParams(TypedDict, total=False):
account: Required[Account]
- """Account reference. Provide id, external_id, or both."""
+ """External account for the transaction.
+
+ Identify it by `id`, `external_id`, or both.
+ """
allocations: Required[Iterable[Allocation]]
- """Allocation entries for this transaction. Empty indicates unreconciled funds."""
+ """Allocations for the transaction. An empty array indicates unreconciled funds."""
amount: Required[str]
"""
- Amount in smallest currency unit as stringified bigint (can be positive or
- negative).
+ Transaction amount, as a string in the smallest currency unit, such as cents for
+ USD. Can be positive or negative.
"""
currency: Required[
@@ -215,70 +218,68 @@ class TransactionCreateParams(TypedDict, total=False):
"CUSTOM",
]
]
- """Currency code (ISO 4217 or crypto)"""
+ """ISO 4217 or crypto currency code."""
external_id: Required[str]
- """External transaction ID used for idempotent sync."""
+ """User-provided unique ID."""
posted: Required[Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]]
- """Posted timestamp in ISO 8601 format."""
+ """Timestamp when the transaction was posted. Uses ISO 8601 format."""
tags: Iterable[Tag]
- """Optional metadata tags for this transaction"""
+ """Tags for the transaction."""
class Account(TypedDict, total=False):
- """Account reference. Provide id, external_id, or both."""
+ """External account for the transaction.
+
+ Identify it by `id`, `external_id`, or both.
+ """
id: str
- """User-facing encoded account ID."""
+ """FRAGMENT generated unique ID."""
external_id: str
- """External account reference ID."""
+ """User-provided unique ID."""
class AllocationUserID(TypedDict, total=False):
id: Required[str]
- """FRAGMENT generated ID of the user"""
+ """FRAGMENT generated unique ID."""
class AllocationUserExternalID(TypedDict, total=False):
external_id: Required[str]
- """External ID of the user"""
+ """User-provided unique ID."""
AllocationUser: TypeAlias = Union[AllocationUserID, AllocationUserExternalID]
class Allocation(TypedDict, total=False):
- """Transaction allocation against an invoice."""
+ """An allocation linking a transaction to an invoice."""
amount: Required[str]
- """Amount to allocate in smallest currency unit as stringified bigint."""
+ """
+ Allocation amount, as a positive string in the smallest currency unit, such as
+ cents for USD.
+ """
invoice_id: Required[str]
- """The invoice to allocate against."""
+ """Invoice to allocate against."""
type: Required[Literal["invoice_payin", "invoice_payout"]]
- """The type of allocation."""
+ """Type of allocation."""
user: Required[AllocationUser]
- """Identifies a user by Fragment-generated id or external_id (request body)."""
+ """Identifies a user by `id` or `external_id`."""
class Tag(TypedDict, total=False):
- """A key-value tag pair for metadata"""
+ """A key-value tag pair for metadata."""
key: Required[str]
- """Tag key.
-
- Must be a valid safe string (no special characters like #, /, :). Max 50
- characters.
- """
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
value: Required[str]
- """Tag value.
-
- Must be a valid safe string (no special characters like #, /, :). Max 200
- characters.
- """
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
diff --git a/src/fragment/types/transaction_list_history_response.py b/src/fragment/types/transaction_list_history_response.py
index fb1338d..0f63fec 100644
--- a/src/fragment/types/transaction_list_history_response.py
+++ b/src/fragment/types/transaction_list_history_response.py
@@ -1,110 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Union, Optional
-from typing_extensions import Literal, TypeAlias
+from typing import List
from .._models import BaseModel
from .transaction import Transaction
-__all__ = [
- "TransactionListHistoryResponse",
- "Data",
- "DataDiff",
- "DataDiffAddAllocationDiffEntry",
- "DataDiffAddAllocationDiffEntryItem",
- "DataDiffAddAllocationDiffEntryItemUser",
- "DataDiffDeleteAllocationDiffEntry",
- "DataDiffDeleteAllocationDiffEntryItem",
- "DataDiffDeleteAllocationDiffEntryItemUser",
-]
-
-
-class DataDiffAddAllocationDiffEntryItemUser(BaseModel):
- """User reference in API responses: Fragment user id and optional external_id."""
-
- id: str
- """FRAGMENT generated ID of the user"""
-
- external_id: Optional[str] = None
- """External ID of the user"""
-
-
-class DataDiffAddAllocationDiffEntryItem(BaseModel):
- """Transaction allocation against an invoice."""
-
- amount: str
- """Amount to allocate in smallest currency unit as stringified bigint."""
-
- invoice_id: str
- """The invoice to allocate against."""
-
- type: Literal["invoice_payin", "invoice_payout"]
- """The type of allocation."""
-
- user: DataDiffAddAllocationDiffEntryItemUser
- """User reference in API responses: Fragment user id and optional external_id."""
-
-
-class DataDiffAddAllocationDiffEntry(BaseModel):
- item: DataDiffAddAllocationDiffEntryItem
- """Transaction allocation against an invoice."""
-
- op: Literal["add"]
- """An allocation was added"""
-
-
-class DataDiffDeleteAllocationDiffEntryItemUser(BaseModel):
- """User reference in API responses: Fragment user id and optional external_id."""
-
- id: str
- """FRAGMENT generated ID of the user"""
-
- external_id: Optional[str] = None
- """External ID of the user"""
-
-
-class DataDiffDeleteAllocationDiffEntryItem(BaseModel):
- """Transaction allocation against an invoice."""
-
- amount: str
- """Amount to allocate in smallest currency unit as stringified bigint."""
-
- invoice_id: str
- """The invoice to allocate against."""
-
- type: Literal["invoice_payin", "invoice_payout"]
- """The type of allocation."""
-
- user: DataDiffDeleteAllocationDiffEntryItemUser
- """User reference in API responses: Fragment user id and optional external_id."""
-
-
-class DataDiffDeleteAllocationDiffEntry(BaseModel):
- item: DataDiffDeleteAllocationDiffEntryItem
- """Transaction allocation against an invoice."""
-
- op: Literal["delete"]
- """An allocation was deleted"""
-
-
-DataDiff: TypeAlias = Union[DataDiffAddAllocationDiffEntry, DataDiffDeleteAllocationDiffEntry]
-
-
-class Data(Transaction):
- """A versioned snapshot of a transaction"""
-
- diff: Optional[List[DataDiff]] = None
- """Allocation changes applied in this version.
-
- Absent on version 1 (initial creation). Each entry describes an allocation that
- was added or deleted.
- """
-
- version: Optional[int] = None # type: ignore
- """Version number of this transaction snapshot."""
+__all__ = ["TransactionListHistoryResponse"]
class TransactionListHistoryResponse(BaseModel):
- """Version history of a transaction"""
-
- data: List[Data]
+ data: List[Transaction]
+ """List of transaction versions over time, ordered by version, oldest first."""
diff --git a/src/fragment/types/transaction_list_params.py b/src/fragment/types/transaction_list_params.py
index b5b8db4..e4b4620 100644
--- a/src/fragment/types/transaction_list_params.py
+++ b/src/fragment/types/transaction_list_params.py
@@ -9,15 +9,15 @@
class TransactionListParams(TypedDict, total=False):
account: str
- """Filter by account.
+ """Filter by account `id` or `external_id`.
- Encoded account ID (ext_account_xxx) or external_id. If the account does not
- exist, returns an empty list.
+ If the account does not exist, returns an empty list.
"""
reconciliation_status: Literal["reconciled", "unreconciled"]
- """Filter by reconciliation state.
+ """Filter by reconciliation status.
- reconciled = unallocated_amount === 0; unreconciled = unallocated_amount !== 0.
- Omit for all transactions.
+ `reconciled` returns transactions where unallocated_amount is 0. `unreconciled`
+ returns transactions where unallocated_amount is not 0. Omit for all
+ transactions.
"""
diff --git a/src/fragment/types/transaction_list_response.py b/src/fragment/types/transaction_list_response.py
index fc72d31..3e1be12 100644
--- a/src/fragment/types/transaction_list_response.py
+++ b/src/fragment/types/transaction_list_response.py
@@ -9,6 +9,5 @@
class TransactionListResponse(BaseModel):
- """List of transactions"""
-
data: List[Transaction]
+ """List of transaction objects matching the filter criteria."""
diff --git a/src/fragment/types/transaction_search_allocations_params.py b/src/fragment/types/transaction_search_allocations_params.py
index c1c8ee8..ab556ca 100644
--- a/src/fragment/types/transaction_search_allocations_params.py
+++ b/src/fragment/types/transaction_search_allocations_params.py
@@ -11,15 +11,18 @@
class TransactionSearchAllocationsParams(TypedDict, total=False):
filter: Required[Filter]
- """Filter criteria for searching transaction allocations."""
+ """Filter for searching transaction allocations."""
class FilterInvoiceID(TypedDict, total=False):
+ """Invoice ID filter."""
+
any: Required[SequenceNotStr[str]]
- """Match allocations where invoice_id is any of these values (OR)."""
+ """Match allocations where invoice_id is any of these values, using OR logic."""
class Filter(TypedDict, total=False):
- """Filter criteria for searching transaction allocations."""
+ """Filter for searching transaction allocations."""
invoice_id: Required[FilterInvoiceID]
+ """Invoice ID filter."""
diff --git a/src/fragment/types/transaction_search_allocations_response.py b/src/fragment/types/transaction_search_allocations_response.py
index 12f6f25..81c7994 100644
--- a/src/fragment/types/transaction_search_allocations_response.py
+++ b/src/fragment/types/transaction_search_allocations_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import List
from datetime import datetime
from typing_extensions import Literal
@@ -10,51 +10,53 @@
class DataTransaction(BaseModel):
- """Reference to a transaction by encoded ID and external ID."""
+ """Transaction the allocation is applied to."""
id: str
- """Encoded transaction ID."""
+ """FRAGMENT generated unique ID."""
external_id: str
- """External transaction ID."""
+ """User-provided unique ID."""
class DataUser(BaseModel):
- """User reference in API responses: Fragment user id and optional external_id."""
+ """User associated with the allocation."""
id: str
- """FRAGMENT generated ID of the user"""
+ """FRAGMENT generated unique ID."""
- external_id: Optional[str] = None
- """External ID of the user"""
+ external_id: str
+ """User-provided unique ID."""
class Data(BaseModel):
- """A flattened allocation with a reference to its parent transaction."""
+ """An allocation with a reference to its parent transaction."""
id: str
- """Allocation ID."""
+ """FRAGMENT generated unique ID."""
amount: str
- """Amount to allocate in smallest currency unit as stringified bigint."""
+ """
+ Allocated amount, as a positive string in the smallest currency unit, such as
+ cents for USD.
+ """
invoice_id: str
- """The invoice to allocate against."""
+ """Invoice the allocation is applied against."""
posted: datetime
- """Posted timestamp of the parent transaction in ISO 8601 format."""
+ """Timestamp when the parent transaction was posted. Uses ISO 8601 format."""
transaction: DataTransaction
- """Reference to a transaction by encoded ID and external ID."""
+ """Transaction the allocation is applied to."""
type: Literal["invoice_payin", "invoice_payout"]
- """The type of allocation."""
+ """Type of allocation."""
user: DataUser
- """User reference in API responses: Fragment user id and optional external_id."""
+ """User associated with the allocation."""
class TransactionSearchAllocationsResponse(BaseModel):
- """Search results for transaction allocations."""
-
data: List[Data]
+ """List of allocation search results."""
diff --git a/src/fragment/types/transaction_search_params.py b/src/fragment/types/transaction_search_params.py
index bb5005b..94db272 100644
--- a/src/fragment/types/transaction_search_params.py
+++ b/src/fragment/types/transaction_search_params.py
@@ -5,30 +5,111 @@
from typing import Iterable
from typing_extensions import Required, TypedDict
-__all__ = ["TransactionSearchParams", "Filter", "FilterAccount", "FilterAccountAny"]
+__all__ = [
+ "TransactionSearchParams",
+ "Filter",
+ "FilterAccount",
+ "FilterAccountAny",
+ "FilterTags",
+ "FilterTagsAll",
+ "FilterTagsAny",
+ "PageInfo",
+]
class TransactionSearchParams(TypedDict, total=False):
filter: Required[Filter]
- """Filter criteria for searching transactions."""
+ """Filter for searching transactions."""
+
+ page_info: PageInfo
+ """Pagination parameters."""
class FilterAccountAny(TypedDict, total=False):
- """Account reference. Provide id, external_id, or both."""
+ """External account for the transaction.
+
+ Identify it by `id`, `external_id`, or both.
+ """
id: str
- """User-facing encoded account ID."""
+ """FRAGMENT generated unique ID."""
external_id: str
- """External account reference ID."""
+ """User-provided unique ID."""
class FilterAccount(TypedDict, total=False):
+ """Account filter."""
+
any: Required[Iterable[FilterAccountAny]]
- """Match transactions belonging to any of these accounts (OR)."""
+ """Match transactions belonging to any of these accounts, using OR logic."""
+
+
+class FilterTagsAll(TypedDict, total=False):
+ """A tag filter."""
+
+ key: Required[str]
+ """Tag key to filter on. Must be an exact match; wildcards are not supported."""
+
+ value: Required[str]
+ """Tag value pattern to filter on.
+
+ Supports wildcards: `*` matches any characters, `?` matches a single character.
+ Use `\\**` or `\\??` to match literal asterisks or question marks. Use `*` to match
+ any value for the given key.
+ """
+
+
+class FilterTagsAny(TypedDict, total=False):
+ """A tag filter."""
+
+ key: Required[str]
+ """Tag key to filter on. Must be an exact match; wildcards are not supported."""
+
+ value: Required[str]
+ """Tag value pattern to filter on.
+
+ Supports wildcards: `*` matches any characters, `?` matches a single character.
+ Use `\\**` or `\\??` to match literal asterisks or question marks. Use `*` to match
+ any value for the given key.
+ """
+
+
+class FilterTags(TypedDict, total=False):
+ """Tag-based filter criteria.
+
+ When both `any` and `all` are provided, results must match every entry in `all` AND at least one entry in `any`.
+ """
+
+ all: Iterable[FilterTagsAll]
+ """Returns transactions matching every specified tag, using AND logic."""
+
+ any: Iterable[FilterTagsAny]
+ """
+ Returns transactions matching at least one of the specified tags, using OR
+ logic.
+ """
class Filter(TypedDict, total=False):
- """Filter criteria for searching transactions."""
+ """Filter for searching transactions."""
+
+ account: FilterAccount
+ """Account filter."""
+
+ tags: FilterTags
+ """Tag-based filter criteria.
+
+ When both `any` and `all` are provided, results must match every entry in `all`
+ AND at least one entry in `any`.
+ """
+
+
+class PageInfo(TypedDict, total=False):
+ """Pagination parameters."""
+
+ after: str
+ """Cursor for fetching the next page of results."""
- account: Required[FilterAccount]
+ limit: int
+ """Number of results to return. Defaults to 20."""
diff --git a/src/fragment/types/transaction_search_response.py b/src/fragment/types/transaction_search_response.py
index 4f1daf9..70246fb 100644
--- a/src/fragment/types/transaction_search_response.py
+++ b/src/fragment/types/transaction_search_response.py
@@ -1,110 +1,34 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Union, Optional
-from typing_extensions import Literal, TypeAlias
+from typing import List, Optional
from .._models import BaseModel
from .transaction import Transaction
-__all__ = [
- "TransactionSearchResponse",
- "Data",
- "DataDiff",
- "DataDiffAddAllocationDiffEntry",
- "DataDiffAddAllocationDiffEntryItem",
- "DataDiffAddAllocationDiffEntryItemUser",
- "DataDiffDeleteAllocationDiffEntry",
- "DataDiffDeleteAllocationDiffEntryItem",
- "DataDiffDeleteAllocationDiffEntryItemUser",
-]
+__all__ = ["TransactionSearchResponse", "DataV2", "DataV2PageInfo"]
-class DataDiffAddAllocationDiffEntryItemUser(BaseModel):
- """User reference in API responses: Fragment user id and optional external_id."""
+class DataV2PageInfo(BaseModel):
+ """Pagination cursors."""
- id: str
- """FRAGMENT generated ID of the user"""
+ next_cursor: Optional[str] = None
+ """Cursor to fetch the next page of results."""
- external_id: Optional[str] = None
- """External ID of the user"""
+class DataV2(BaseModel):
+ page_info: DataV2PageInfo
+ """Pagination cursors."""
-class DataDiffAddAllocationDiffEntryItem(BaseModel):
- """Transaction allocation against an invoice."""
+ transactions: List[Transaction]
+ """Transactions matching the search criteria."""
- amount: str
- """Amount to allocate in smallest currency unit as stringified bigint."""
- invoice_id: str
- """The invoice to allocate against."""
-
- type: Literal["invoice_payin", "invoice_payout"]
- """The type of allocation."""
-
- user: DataDiffAddAllocationDiffEntryItemUser
- """User reference in API responses: Fragment user id and optional external_id."""
-
-
-class DataDiffAddAllocationDiffEntry(BaseModel):
- item: DataDiffAddAllocationDiffEntryItem
- """Transaction allocation against an invoice."""
-
- op: Literal["add"]
- """An allocation was added"""
-
-
-class DataDiffDeleteAllocationDiffEntryItemUser(BaseModel):
- """User reference in API responses: Fragment user id and optional external_id."""
-
- id: str
- """FRAGMENT generated ID of the user"""
-
- external_id: Optional[str] = None
- """External ID of the user"""
-
-
-class DataDiffDeleteAllocationDiffEntryItem(BaseModel):
- """Transaction allocation against an invoice."""
-
- amount: str
- """Amount to allocate in smallest currency unit as stringified bigint."""
-
- invoice_id: str
- """The invoice to allocate against."""
-
- type: Literal["invoice_payin", "invoice_payout"]
- """The type of allocation."""
-
- user: DataDiffDeleteAllocationDiffEntryItemUser
- """User reference in API responses: Fragment user id and optional external_id."""
-
-
-class DataDiffDeleteAllocationDiffEntry(BaseModel):
- item: DataDiffDeleteAllocationDiffEntryItem
- """Transaction allocation against an invoice."""
-
- op: Literal["delete"]
- """An allocation was deleted"""
-
-
-DataDiff: TypeAlias = Union[DataDiffAddAllocationDiffEntry, DataDiffDeleteAllocationDiffEntry]
-
-
-class Data(Transaction):
- """A versioned snapshot of a transaction"""
-
- diff: Optional[List[DataDiff]] = None
- """Allocation changes applied in this version.
+class TransactionSearchResponse(BaseModel):
+ data: List[Transaction]
+ """Deprecated.
- Absent on version 1 (initial creation). Each entry describes an allocation that
- was added or deleted.
+ Use `data_v2.transactions` instead. Returns the full unpaginated list of
+ matching transactions.
"""
- version: Optional[int] = None # type: ignore
- """Version number of this transaction snapshot."""
-
-
-class TransactionSearchResponse(BaseModel):
- """Search results for transactions."""
-
- data: List[Data]
+ data_v2: DataV2
diff --git a/src/fragment/types/transaction_update_params.py b/src/fragment/types/transaction_update_params.py
new file mode 100644
index 0000000..2f2898a
--- /dev/null
+++ b/src/fragment/types/transaction_update_params.py
@@ -0,0 +1,136 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Iterable
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+__all__ = [
+ "TransactionUpdateParams",
+ "Allocations",
+ "AllocationsCreate",
+ "AllocationsCreateUser",
+ "AllocationsCreateUserID",
+ "AllocationsCreateUserExternalID",
+ "AllocationsUpdate",
+ "Tags",
+ "TagsCreate",
+ "TagsDelete",
+ "TagsSet",
+ "TagsUpdate",
+]
+
+
+class TransactionUpdateParams(TypedDict, total=False):
+ current_transaction_version: Required[int]
+ """Current version of the transaction. Must match the stored version."""
+
+ allocations: Allocations
+ """Allocation updates."""
+
+ tags: Tags
+ """Tag updates."""
+
+
+class AllocationsCreateUserID(TypedDict, total=False):
+ id: Required[str]
+ """FRAGMENT generated unique ID."""
+
+
+class AllocationsCreateUserExternalID(TypedDict, total=False):
+ external_id: Required[str]
+ """User-provided unique ID."""
+
+
+AllocationsCreateUser: TypeAlias = Union[AllocationsCreateUserID, AllocationsCreateUserExternalID]
+
+
+class AllocationsCreate(TypedDict, total=False):
+ """An allocation linking a transaction to an invoice."""
+
+ amount: Required[str]
+ """
+ Allocation amount, as a positive string in the smallest currency unit, such as
+ cents for USD.
+ """
+
+ invoice_id: Required[str]
+ """Invoice to allocate against."""
+
+ type: Required[Literal["invoice_payin", "invoice_payout"]]
+ """Type of allocation."""
+
+ user: Required[AllocationsCreateUser]
+ """Identifies a user by `id` or `external_id`."""
+
+
+class AllocationsUpdate(TypedDict, total=False):
+ id: Required[str]
+ """Allocation to update."""
+
+ amount: Required[str]
+ """
+ Updated allocation amount, as a positive string in the smallest currency unit,
+ such as cents for USD.
+ """
+
+
+class Allocations(TypedDict, total=False):
+ """Allocation updates."""
+
+ create: Iterable[AllocationsCreate]
+ """Allocations to create."""
+
+ update: Iterable[AllocationsUpdate]
+ """Allocations to update."""
+
+
+class TagsCreate(TypedDict, total=False):
+ """A key-value tag pair for metadata."""
+
+ key: Required[str]
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
+
+ value: Required[str]
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
+
+
+class TagsDelete(TypedDict, total=False):
+ key: Required[str]
+ """Tag key to delete."""
+
+
+class TagsSet(TypedDict, total=False):
+ """A key-value tag pair for metadata."""
+
+ key: Required[str]
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
+
+ value: Required[str]
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
+
+
+class TagsUpdate(TypedDict, total=False):
+ """A key-value tag pair for metadata."""
+
+ key: Required[str]
+ """Tag key. Must not contain #, /, or :. Max 50 characters."""
+
+ value: Required[str]
+ """Tag value. Must not contain #, /, or :. Max 200 characters."""
+
+
+class Tags(TypedDict, total=False):
+ """Tag updates."""
+
+ create: Iterable[TagsCreate]
+ """Tags to create. The tag key must not already exist."""
+
+ delete: Iterable[TagsDelete]
+ """Tags to remove."""
+
+ set: Iterable[TagsSet]
+ """Tags to set. Creates a new tag or updates an existing tag."""
+
+ update: Iterable[TagsUpdate]
+ """Tags to update. The tag key must already exist."""
diff --git a/src/fragment/types/transaction_create_allocations_response.py b/src/fragment/types/transaction_update_response.py
similarity index 66%
rename from src/fragment/types/transaction_create_allocations_response.py
rename to src/fragment/types/transaction_update_response.py
index b9887f3..54a3d8a 100644
--- a/src/fragment/types/transaction_create_allocations_response.py
+++ b/src/fragment/types/transaction_update_response.py
@@ -3,9 +3,9 @@
from .._models import BaseModel
from .transaction import Transaction
-__all__ = ["TransactionCreateAllocationsResponse"]
+__all__ = ["TransactionUpdateResponse"]
-class TransactionCreateAllocationsResponse(BaseModel):
+class TransactionUpdateResponse(BaseModel):
data: Transaction
"""Transaction object."""
diff --git a/src/fragment/types/user.py b/src/fragment/types/user.py
index 7eea5f1..ca34e05 100644
--- a/src/fragment/types/user.py
+++ b/src/fragment/types/user.py
@@ -6,13 +6,13 @@
class User(BaseModel):
- """User object"""
+ """User object."""
id: str
- """Unique user ID"""
+ """FRAGMENT generated unique ID."""
external_id: str
- """External ID for the user"""
+ """User-provided unique ID."""
role: str
- """Role of the user"""
+ """Name of the user's role."""
diff --git a/src/fragment/types/user_create_params.py b/src/fragment/types/user_create_params.py
index 997cb6c..adf66eb 100644
--- a/src/fragment/types/user_create_params.py
+++ b/src/fragment/types/user_create_params.py
@@ -9,7 +9,7 @@
class UserCreateParams(TypedDict, total=False):
external_id: Required[str]
- """External ID for the user"""
+ """User-provided unique ID."""
role: Required[str]
- """Role of the user"""
+ """Name of the role to assign. Must match an existing role."""
diff --git a/src/fragment/types/user_create_response.py b/src/fragment/types/user_create_response.py
index 8584137..8a27ae5 100644
--- a/src/fragment/types/user_create_response.py
+++ b/src/fragment/types/user_create_response.py
@@ -8,4 +8,4 @@
class UserCreateResponse(BaseModel):
data: User
- """User object"""
+ """User object."""
diff --git a/src/fragment/types/user_list_response.py b/src/fragment/types/user_list_response.py
index 95d7d93..f4a0a11 100644
--- a/src/fragment/types/user_list_response.py
+++ b/src/fragment/types/user_list_response.py
@@ -9,6 +9,7 @@
class UserListResponse(BaseModel):
- """List of users"""
+ """List of users."""
data: List[User]
+ """List of users."""
diff --git a/tests/api_resources/test_invoices.py b/tests/api_resources/test_invoices.py
index 29c5d56..232f3da 100644
--- a/tests/api_resources/test_invoices.py
+++ b/tests/api_resources/test_invoices.py
@@ -60,16 +60,16 @@ def test_method_create_with_all_params(self, client: Fragment) -> None:
},
"tags": [
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
}
],
tags=[
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
)
@@ -190,8 +190,8 @@ def test_method_update_with_all_params(self, client: Fragment) -> None:
},
"tags": [
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
}
@@ -209,15 +209,21 @@ def test_method_update_with_all_params(self, client: Fragment) -> None:
"tags": {
"create": [
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
"delete": [{"key": "key"}],
+ "set": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
"update": [
{
- "key": "region",
- "value": "eu-west-1",
+ "key": "department",
+ "value": "engineering",
}
],
},
@@ -227,15 +233,21 @@ def test_method_update_with_all_params(self, client: Fragment) -> None:
tags={
"create": [
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
"delete": [{"key": "key"}],
+ "set": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
"update": [
{
- "key": "region",
- "value": "eu-west-1",
+ "key": "department",
+ "value": "engineering",
}
],
},
@@ -354,7 +366,6 @@ def test_path_params_list_history(self, client: Fragment) -> None:
def test_method_search(self, client: Fragment) -> None:
invoice = client.invoices.search(
filter={},
- page_info={},
)
assert_matches_type(InvoiceSearchResponse, invoice, path=["response"])
@@ -363,20 +374,21 @@ def test_method_search(self, client: Fragment) -> None:
def test_method_search_with_all_params(self, client: Fragment) -> None:
invoice = client.invoices.search(
filter={
+ "status": "open",
"tags": {
"all": [
{
- "key": "env",
- "value": "prod",
+ "key": "department",
+ "value": "engineering",
}
],
"any": [
{
- "key": "region",
- "value": "us-*",
+ "key": "department",
+ "value": "eng*",
}
],
- }
+ },
},
page_info={
"after": "after",
@@ -390,7 +402,6 @@ def test_method_search_with_all_params(self, client: Fragment) -> None:
def test_raw_response_search(self, client: Fragment) -> None:
response = client.invoices.with_raw_response.search(
filter={},
- page_info={},
)
assert response.is_closed is True
@@ -403,7 +414,6 @@ def test_raw_response_search(self, client: Fragment) -> None:
def test_streaming_response_search(self, client: Fragment) -> None:
with client.invoices.with_streaming_response.search(
filter={},
- page_info={},
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -455,16 +465,16 @@ async def test_method_create_with_all_params(self, async_client: AsyncFragment)
},
"tags": [
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
}
],
tags=[
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
)
@@ -585,8 +595,8 @@ async def test_method_update_with_all_params(self, async_client: AsyncFragment)
},
"tags": [
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
}
@@ -604,15 +614,21 @@ async def test_method_update_with_all_params(self, async_client: AsyncFragment)
"tags": {
"create": [
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
"delete": [{"key": "key"}],
+ "set": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
"update": [
{
- "key": "region",
- "value": "eu-west-1",
+ "key": "department",
+ "value": "engineering",
}
],
},
@@ -622,15 +638,21 @@ async def test_method_update_with_all_params(self, async_client: AsyncFragment)
tags={
"create": [
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
"delete": [{"key": "key"}],
+ "set": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
"update": [
{
- "key": "region",
- "value": "eu-west-1",
+ "key": "department",
+ "value": "engineering",
}
],
},
@@ -749,7 +771,6 @@ async def test_path_params_list_history(self, async_client: AsyncFragment) -> No
async def test_method_search(self, async_client: AsyncFragment) -> None:
invoice = await async_client.invoices.search(
filter={},
- page_info={},
)
assert_matches_type(InvoiceSearchResponse, invoice, path=["response"])
@@ -758,20 +779,21 @@ async def test_method_search(self, async_client: AsyncFragment) -> None:
async def test_method_search_with_all_params(self, async_client: AsyncFragment) -> None:
invoice = await async_client.invoices.search(
filter={
+ "status": "open",
"tags": {
"all": [
{
- "key": "env",
- "value": "prod",
+ "key": "department",
+ "value": "engineering",
}
],
"any": [
{
- "key": "region",
- "value": "us-*",
+ "key": "department",
+ "value": "eng*",
}
],
- }
+ },
},
page_info={
"after": "after",
@@ -785,7 +807,6 @@ async def test_method_search_with_all_params(self, async_client: AsyncFragment)
async def test_raw_response_search(self, async_client: AsyncFragment) -> None:
response = await async_client.invoices.with_raw_response.search(
filter={},
- page_info={},
)
assert response.is_closed is True
@@ -798,7 +819,6 @@ async def test_raw_response_search(self, async_client: AsyncFragment) -> None:
async def test_streaming_response_search(self, async_client: AsyncFragment) -> None:
async with async_client.invoices.with_streaming_response.search(
filter={},
- page_info={},
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/api_resources/test_transactions.py b/tests/api_resources/test_transactions.py
index 2bfb29f..c7fa19b 100644
--- a/tests/api_resources/test_transactions.py
+++ b/tests/api_resources/test_transactions.py
@@ -13,9 +13,9 @@
TransactionListResponse,
TransactionCreateResponse,
TransactionSearchResponse,
+ TransactionUpdateResponse,
TransactionRetrieveResponse,
TransactionListHistoryResponse,
- TransactionCreateAllocationsResponse,
TransactionSearchAllocationsResponse,
)
from fragment._utils import parse_datetime
@@ -42,7 +42,7 @@ def test_method_create(self, client: Fragment) -> None:
amount="-1000",
currency="USD",
external_id="bank_txn_123",
- posted=parse_datetime("2026-02-12T00:00:00.000Z"),
+ posted=parse_datetime("2024-01-13T00:00:00Z"),
)
assert_matches_type(TransactionCreateResponse, transaction, path=["response"])
@@ -65,11 +65,11 @@ def test_method_create_with_all_params(self, client: Fragment) -> None:
amount="-1000",
currency="USD",
external_id="bank_txn_123",
- posted=parse_datetime("2026-02-12T00:00:00.000Z"),
+ posted=parse_datetime("2024-01-13T00:00:00Z"),
tags=[
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
)
@@ -91,7 +91,7 @@ def test_raw_response_create(self, client: Fragment) -> None:
amount="-1000",
currency="USD",
external_id="bank_txn_123",
- posted=parse_datetime("2026-02-12T00:00:00.000Z"),
+ posted=parse_datetime("2024-01-13T00:00:00Z"),
)
assert response.is_closed is True
@@ -115,7 +115,7 @@ def test_streaming_response_create(self, client: Fragment) -> None:
amount="-1000",
currency="USD",
external_id="bank_txn_123",
- posted=parse_datetime("2026-02-12T00:00:00.000Z"),
+ posted=parse_datetime("2024-01-13T00:00:00Z"),
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -169,123 +169,133 @@ def test_path_params_retrieve(self, client: Fragment) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_list(self, client: Fragment) -> None:
- transaction = client.transactions.list()
- assert_matches_type(TransactionListResponse, transaction, path=["response"])
+ def test_method_update(self, client: Fragment) -> None:
+ transaction = client.transactions.update(
+ transaction_ref="txn_abc123",
+ current_transaction_version=0,
+ )
+ assert_matches_type(TransactionUpdateResponse, transaction, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_list_with_all_params(self, client: Fragment) -> None:
- transaction = client.transactions.list(
- account="ext_account_YWJjMTIz",
- reconciliation_status="reconciled",
+ def test_method_update_with_all_params(self, client: Fragment) -> None:
+ transaction = client.transactions.update(
+ transaction_ref="txn_abc123",
+ current_transaction_version=0,
+ allocations={
+ "create": [
+ {
+ "amount": "1000",
+ "invoice_id": "inv_abc123",
+ "type": "invoice_payin",
+ "user": {"id": "user_abc123"},
+ }
+ ],
+ "update": [
+ {
+ "id": "alloc_abc123",
+ "amount": "2000",
+ }
+ ],
+ },
+ tags={
+ "create": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
+ "delete": [{"key": "key"}],
+ "set": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
+ "update": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
+ },
)
- assert_matches_type(TransactionListResponse, transaction, path=["response"])
+ assert_matches_type(TransactionUpdateResponse, transaction, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_list(self, client: Fragment) -> None:
- response = client.transactions.with_raw_response.list()
+ def test_raw_response_update(self, client: Fragment) -> None:
+ response = client.transactions.with_raw_response.update(
+ transaction_ref="txn_abc123",
+ current_transaction_version=0,
+ )
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transaction = response.parse()
- assert_matches_type(TransactionListResponse, transaction, path=["response"])
+ assert_matches_type(TransactionUpdateResponse, transaction, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_list(self, client: Fragment) -> None:
- with client.transactions.with_streaming_response.list() as response:
+ def test_streaming_response_update(self, client: Fragment) -> None:
+ with client.transactions.with_streaming_response.update(
+ transaction_ref="txn_abc123",
+ current_transaction_version=0,
+ ) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transaction = response.parse()
- assert_matches_type(TransactionListResponse, transaction, path=["response"])
+ assert_matches_type(TransactionUpdateResponse, transaction, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_create_allocations(self, client: Fragment) -> None:
- transaction = client.transactions.create_allocations(
- transaction_ref="txn_abc123",
- allocation_updates=[
- {
- "amount": "1000",
- "invoice_id": "inv_abc123",
- "op": "add",
- "type": "invoice_payin",
- "user": {"id": "user_abc123"},
- }
- ],
- version=0,
- )
- assert_matches_type(TransactionCreateAllocationsResponse, transaction, path=["response"])
+ def test_path_params_update(self, client: Fragment) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `transaction_ref` but received ''"):
+ client.transactions.with_raw_response.update(
+ transaction_ref="",
+ current_transaction_version=0,
+ )
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_create_allocations(self, client: Fragment) -> None:
- response = client.transactions.with_raw_response.create_allocations(
- transaction_ref="txn_abc123",
- allocation_updates=[
- {
- "amount": "1000",
- "invoice_id": "inv_abc123",
- "op": "add",
- "type": "invoice_payin",
- "user": {"id": "user_abc123"},
- }
- ],
- version=0,
+ def test_method_list(self, client: Fragment) -> None:
+ transaction = client.transactions.list()
+ assert_matches_type(TransactionListResponse, transaction, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Fragment) -> None:
+ transaction = client.transactions.list(
+ account="ext_account_YWJjMTIz",
+ reconciliation_status="reconciled",
)
+ assert_matches_type(TransactionListResponse, transaction, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Fragment) -> None:
+ response = client.transactions.with_raw_response.list()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transaction = response.parse()
- assert_matches_type(TransactionCreateAllocationsResponse, transaction, path=["response"])
+ assert_matches_type(TransactionListResponse, transaction, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_create_allocations(self, client: Fragment) -> None:
- with client.transactions.with_streaming_response.create_allocations(
- transaction_ref="txn_abc123",
- allocation_updates=[
- {
- "amount": "1000",
- "invoice_id": "inv_abc123",
- "op": "add",
- "type": "invoice_payin",
- "user": {"id": "user_abc123"},
- }
- ],
- version=0,
- ) as response:
+ def test_streaming_response_list(self, client: Fragment) -> None:
+ with client.transactions.with_streaming_response.list() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transaction = response.parse()
- assert_matches_type(TransactionCreateAllocationsResponse, transaction, path=["response"])
+ assert_matches_type(TransactionListResponse, transaction, path=["response"])
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_path_params_create_allocations(self, client: Fragment) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `transaction_ref` but received ''"):
- client.transactions.with_raw_response.create_allocations(
- transaction_ref="",
- allocation_updates=[
- {
- "amount": "1000",
- "invoice_id": "inv_abc123",
- "op": "add",
- "type": "invoice_payin",
- "user": {"id": "user_abc123"},
- }
- ],
- version=0,
- )
-
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_list_history(self, client: Fragment) -> None:
@@ -332,7 +342,42 @@ def test_path_params_list_history(self, client: Fragment) -> None:
@parametrize
def test_method_search(self, client: Fragment) -> None:
transaction = client.transactions.search(
- filter={"account": {"any": [{}]}},
+ filter={},
+ )
+ assert_matches_type(TransactionSearchResponse, transaction, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_search_with_all_params(self, client: Fragment) -> None:
+ transaction = client.transactions.search(
+ filter={
+ "account": {
+ "any": [
+ {
+ "id": "ext_account_YWJjMTIz",
+ "external_id": "acct_external_123",
+ }
+ ]
+ },
+ "tags": {
+ "all": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
+ "any": [
+ {
+ "key": "department",
+ "value": "eng*",
+ }
+ ],
+ },
+ },
+ page_info={
+ "after": "after",
+ "limit": 20,
+ },
)
assert_matches_type(TransactionSearchResponse, transaction, path=["response"])
@@ -340,7 +385,7 @@ def test_method_search(self, client: Fragment) -> None:
@parametrize
def test_raw_response_search(self, client: Fragment) -> None:
response = client.transactions.with_raw_response.search(
- filter={"account": {"any": [{}]}},
+ filter={},
)
assert response.is_closed is True
@@ -352,7 +397,7 @@ def test_raw_response_search(self, client: Fragment) -> None:
@parametrize
def test_streaming_response_search(self, client: Fragment) -> None:
with client.transactions.with_streaming_response.search(
- filter={"account": {"any": [{}]}},
+ filter={},
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -418,7 +463,7 @@ async def test_method_create(self, async_client: AsyncFragment) -> None:
amount="-1000",
currency="USD",
external_id="bank_txn_123",
- posted=parse_datetime("2026-02-12T00:00:00.000Z"),
+ posted=parse_datetime("2024-01-13T00:00:00Z"),
)
assert_matches_type(TransactionCreateResponse, transaction, path=["response"])
@@ -441,11 +486,11 @@ async def test_method_create_with_all_params(self, async_client: AsyncFragment)
amount="-1000",
currency="USD",
external_id="bank_txn_123",
- posted=parse_datetime("2026-02-12T00:00:00.000Z"),
+ posted=parse_datetime("2024-01-13T00:00:00Z"),
tags=[
{
- "key": "region",
- "value": "us-east",
+ "key": "department",
+ "value": "engineering",
}
],
)
@@ -467,7 +512,7 @@ async def test_raw_response_create(self, async_client: AsyncFragment) -> None:
amount="-1000",
currency="USD",
external_id="bank_txn_123",
- posted=parse_datetime("2026-02-12T00:00:00.000Z"),
+ posted=parse_datetime("2024-01-13T00:00:00Z"),
)
assert response.is_closed is True
@@ -491,7 +536,7 @@ async def test_streaming_response_create(self, async_client: AsyncFragment) -> N
amount="-1000",
currency="USD",
external_id="bank_txn_123",
- posted=parse_datetime("2026-02-12T00:00:00.000Z"),
+ posted=parse_datetime("2024-01-13T00:00:00Z"),
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -545,123 +590,133 @@ async def test_path_params_retrieve(self, async_client: AsyncFragment) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_list(self, async_client: AsyncFragment) -> None:
- transaction = await async_client.transactions.list()
- assert_matches_type(TransactionListResponse, transaction, path=["response"])
+ async def test_method_update(self, async_client: AsyncFragment) -> None:
+ transaction = await async_client.transactions.update(
+ transaction_ref="txn_abc123",
+ current_transaction_version=0,
+ )
+ assert_matches_type(TransactionUpdateResponse, transaction, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncFragment) -> None:
- transaction = await async_client.transactions.list(
- account="ext_account_YWJjMTIz",
- reconciliation_status="reconciled",
+ async def test_method_update_with_all_params(self, async_client: AsyncFragment) -> None:
+ transaction = await async_client.transactions.update(
+ transaction_ref="txn_abc123",
+ current_transaction_version=0,
+ allocations={
+ "create": [
+ {
+ "amount": "1000",
+ "invoice_id": "inv_abc123",
+ "type": "invoice_payin",
+ "user": {"id": "user_abc123"},
+ }
+ ],
+ "update": [
+ {
+ "id": "alloc_abc123",
+ "amount": "2000",
+ }
+ ],
+ },
+ tags={
+ "create": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
+ "delete": [{"key": "key"}],
+ "set": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
+ "update": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
+ },
)
- assert_matches_type(TransactionListResponse, transaction, path=["response"])
+ assert_matches_type(TransactionUpdateResponse, transaction, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_list(self, async_client: AsyncFragment) -> None:
- response = await async_client.transactions.with_raw_response.list()
+ async def test_raw_response_update(self, async_client: AsyncFragment) -> None:
+ response = await async_client.transactions.with_raw_response.update(
+ transaction_ref="txn_abc123",
+ current_transaction_version=0,
+ )
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transaction = await response.parse()
- assert_matches_type(TransactionListResponse, transaction, path=["response"])
+ assert_matches_type(TransactionUpdateResponse, transaction, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_list(self, async_client: AsyncFragment) -> None:
- async with async_client.transactions.with_streaming_response.list() as response:
+ async def test_streaming_response_update(self, async_client: AsyncFragment) -> None:
+ async with async_client.transactions.with_streaming_response.update(
+ transaction_ref="txn_abc123",
+ current_transaction_version=0,
+ ) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transaction = await response.parse()
- assert_matches_type(TransactionListResponse, transaction, path=["response"])
+ assert_matches_type(TransactionUpdateResponse, transaction, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_create_allocations(self, async_client: AsyncFragment) -> None:
- transaction = await async_client.transactions.create_allocations(
- transaction_ref="txn_abc123",
- allocation_updates=[
- {
- "amount": "1000",
- "invoice_id": "inv_abc123",
- "op": "add",
- "type": "invoice_payin",
- "user": {"id": "user_abc123"},
- }
- ],
- version=0,
- )
- assert_matches_type(TransactionCreateAllocationsResponse, transaction, path=["response"])
+ async def test_path_params_update(self, async_client: AsyncFragment) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `transaction_ref` but received ''"):
+ await async_client.transactions.with_raw_response.update(
+ transaction_ref="",
+ current_transaction_version=0,
+ )
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_create_allocations(self, async_client: AsyncFragment) -> None:
- response = await async_client.transactions.with_raw_response.create_allocations(
- transaction_ref="txn_abc123",
- allocation_updates=[
- {
- "amount": "1000",
- "invoice_id": "inv_abc123",
- "op": "add",
- "type": "invoice_payin",
- "user": {"id": "user_abc123"},
- }
- ],
- version=0,
+ async def test_method_list(self, async_client: AsyncFragment) -> None:
+ transaction = await async_client.transactions.list()
+ assert_matches_type(TransactionListResponse, transaction, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncFragment) -> None:
+ transaction = await async_client.transactions.list(
+ account="ext_account_YWJjMTIz",
+ reconciliation_status="reconciled",
)
+ assert_matches_type(TransactionListResponse, transaction, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncFragment) -> None:
+ response = await async_client.transactions.with_raw_response.list()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transaction = await response.parse()
- assert_matches_type(TransactionCreateAllocationsResponse, transaction, path=["response"])
+ assert_matches_type(TransactionListResponse, transaction, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_create_allocations(self, async_client: AsyncFragment) -> None:
- async with async_client.transactions.with_streaming_response.create_allocations(
- transaction_ref="txn_abc123",
- allocation_updates=[
- {
- "amount": "1000",
- "invoice_id": "inv_abc123",
- "op": "add",
- "type": "invoice_payin",
- "user": {"id": "user_abc123"},
- }
- ],
- version=0,
- ) as response:
+ async def test_streaming_response_list(self, async_client: AsyncFragment) -> None:
+ async with async_client.transactions.with_streaming_response.list() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
transaction = await response.parse()
- assert_matches_type(TransactionCreateAllocationsResponse, transaction, path=["response"])
+ assert_matches_type(TransactionListResponse, transaction, path=["response"])
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_path_params_create_allocations(self, async_client: AsyncFragment) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `transaction_ref` but received ''"):
- await async_client.transactions.with_raw_response.create_allocations(
- transaction_ref="",
- allocation_updates=[
- {
- "amount": "1000",
- "invoice_id": "inv_abc123",
- "op": "add",
- "type": "invoice_payin",
- "user": {"id": "user_abc123"},
- }
- ],
- version=0,
- )
-
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_list_history(self, async_client: AsyncFragment) -> None:
@@ -708,7 +763,42 @@ async def test_path_params_list_history(self, async_client: AsyncFragment) -> No
@parametrize
async def test_method_search(self, async_client: AsyncFragment) -> None:
transaction = await async_client.transactions.search(
- filter={"account": {"any": [{}]}},
+ filter={},
+ )
+ assert_matches_type(TransactionSearchResponse, transaction, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_search_with_all_params(self, async_client: AsyncFragment) -> None:
+ transaction = await async_client.transactions.search(
+ filter={
+ "account": {
+ "any": [
+ {
+ "id": "ext_account_YWJjMTIz",
+ "external_id": "acct_external_123",
+ }
+ ]
+ },
+ "tags": {
+ "all": [
+ {
+ "key": "department",
+ "value": "engineering",
+ }
+ ],
+ "any": [
+ {
+ "key": "department",
+ "value": "eng*",
+ }
+ ],
+ },
+ },
+ page_info={
+ "after": "after",
+ "limit": 20,
+ },
)
assert_matches_type(TransactionSearchResponse, transaction, path=["response"])
@@ -716,7 +806,7 @@ async def test_method_search(self, async_client: AsyncFragment) -> None:
@parametrize
async def test_raw_response_search(self, async_client: AsyncFragment) -> None:
response = await async_client.transactions.with_raw_response.search(
- filter={"account": {"any": [{}]}},
+ filter={},
)
assert response.is_closed is True
@@ -728,7 +818,7 @@ async def test_raw_response_search(self, async_client: AsyncFragment) -> None:
@parametrize
async def test_streaming_response_search(self, async_client: AsyncFragment) -> None:
async with async_client.transactions.with_streaming_response.search(
- filter={"account": {"any": [{}]}},
+ filter={},
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/test_client.py b/tests/test_client.py
index 10cfb2e..3bf1432 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -458,6 +458,30 @@ def test_default_query_option(self) -> None:
client.close()
+ def test_hardcoded_query_params_in_url(self, client: Fragment) -> None:
+ request = client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true"))
+ url = httpx.URL(request.url)
+ assert dict(url.params) == {"beta": "true"}
+
+ request = client._build_request(
+ FinalRequestOptions(
+ method="get",
+ url="/foo?beta=true",
+ params={"limit": "10", "page": "abc"},
+ )
+ )
+ url = httpx.URL(request.url)
+ assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"}
+
+ request = client._build_request(
+ FinalRequestOptions(
+ method="get",
+ url="/files/a%2Fb?beta=true",
+ params={"limit": "10"},
+ )
+ )
+ assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10"
+
def test_request_extra_json(self, client: Fragment) -> None:
request = client._build_request(
FinalRequestOptions(
@@ -1423,6 +1447,30 @@ async def test_default_query_option(self) -> None:
await client.close()
+ async def test_hardcoded_query_params_in_url(self, async_client: AsyncFragment) -> None:
+ request = async_client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true"))
+ url = httpx.URL(request.url)
+ assert dict(url.params) == {"beta": "true"}
+
+ request = async_client._build_request(
+ FinalRequestOptions(
+ method="get",
+ url="/foo?beta=true",
+ params={"limit": "10", "page": "abc"},
+ )
+ )
+ url = httpx.URL(request.url)
+ assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"}
+
+ request = async_client._build_request(
+ FinalRequestOptions(
+ method="get",
+ url="/files/a%2Fb?beta=true",
+ params={"limit": "10"},
+ )
+ )
+ assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10"
+
def test_request_extra_json(self, client: Fragment) -> None:
request = client._build_request(
FinalRequestOptions(
diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py
index 783e4c7..3a59a56 100644
--- a/tests/test_extract_files.py
+++ b/tests/test_extract_files.py
@@ -35,6 +35,15 @@ def test_multiple_files() -> None:
assert query == {"documents": [{}, {}]}
+def test_top_level_file_array() -> None:
+ query = {"files": [b"file one", b"file two"], "title": "hello"}
+ assert extract_files(query, paths=[["files", ""]]) == [
+ ("files[]", b"file one"),
+ ("files[]", b"file two"),
+ ]
+ assert query == {"title": "hello"}
+
+
@pytest.mark.parametrize(
"query,paths,expected",
[