From d53ec11a86bec6cdf14903f2a70204fca3880100 Mon Sep 17 00:00:00 2001
From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com>
Date: Wed, 10 Dec 2025 16:40:03 +0000
Subject: [PATCH] SDK regeneration
---
poetry.lock | 12 +-
pyproject.toml | 2 +-
reference.md | 193 +++++++
src/sayari/__init__.py | 8 +
src/sayari/core/client_wrapper.py | 2 +-
.../generated_types/types/identifier_type.py | 7 +
src/sayari/generated_types/types/risk.py | 23 +
.../types/weak_identifier_type.py | 2 +
src/sayari/project/__init__.py | 2 +
src/sayari/project/client.py | 13 +
src/sayari/project/types/__init__.py | 2 +
.../project/types/create_project_request.py | 9 +-
.../project/types/create_project_response.py | 1 +
.../project/types/delete_project_response.py | 1 +
.../project/types/get_projects_response.py | 2 +
src/sayari/project/types/project.py | 8 +-
src/sayari/project/types/project_type.py | 5 +
src/sayari/project_entity/__init__.py | 4 +
src/sayari/project_entity/client.py | 538 +++++++++++++++++-
src/sayari/project_entity/types/__init__.py | 4 +
.../types/project_entities_response.py | 9 +-
.../types/project_entity_response.py | 5 +-
.../types/single_project_entity_response.py | 9 +-
.../update_project_entity_matches_body.py | 28 +
.../update_project_entity_matches_response.py | 22 +
src/sayari/shared_types/__init__.py | 2 +
src/sayari/shared_types/types/__init__.py | 2 +
src/sayari/shared_types/types/case_info.py | 23 +
.../shared_types/types/possibly_same_as.py | 2 +-
29 files changed, 917 insertions(+), 23 deletions(-)
create mode 100644 src/sayari/project/types/project_type.py
create mode 100644 src/sayari/project_entity/types/update_project_entity_matches_body.py
create mode 100644 src/sayari/project_entity/types/update_project_entity_matches_response.py
create mode 100644 src/sayari/shared_types/types/case_info.py
diff --git a/poetry.lock b/poetry.lock
index ea08ef08..f4d44285 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -38,13 +38,13 @@ trio = ["trio (>=0.26.1)"]
[[package]]
name = "certifi"
-version = "2025.10.5"
+version = "2025.11.12"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.7"
files = [
- {file = "certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de"},
- {file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"},
+ {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"},
+ {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"},
]
[[package]]
@@ -60,13 +60,13 @@ files = [
[[package]]
name = "exceptiongroup"
-version = "1.3.0"
+version = "1.3.1"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
- {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"},
- {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"},
+ {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"},
+ {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"},
]
[package.dependencies]
diff --git a/pyproject.toml b/pyproject.toml
index c9f17861..f9299f31 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,7 +3,7 @@ name = "sayari"
[tool.poetry]
name = "sayari"
-version = "0.1.43"
+version = "0.1.44"
description = "A Python SDK for Sayari"
readme = "README.md"
authors = [
diff --git a/reference.md b/reference.md
index 3121accd..d9af5d89 100644
--- a/reference.md
+++ b/reference.md
@@ -3684,6 +3684,190 @@ client.project_entity.get_project_entity(
+
+
+
+
+client.project_entity.add_project_entity_matches(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Adds matches to a project entity.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from sayari import Sayari
+from sayari.project_entity import UpdateProjectEntityMatchesBody
+
+client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+)
+client.project_entity.add_project_entity_matches(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ request=UpdateProjectEntityMatchesBody(
+ entity_ids=["entity_ids", "entity_ids"],
+ ),
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**project_id:** `str`
+
+
+
+
+
+-
+
+**project_entity_id:** `str`
+
+
+
+
+
+-
+
+**request:** `UpdateProjectEntityMatchesBody`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+
+
+
+
+client.project_entity.replace_project_entity_matches(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Replace matches in a project entity.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from sayari import Sayari
+from sayari.project_entity import UpdateProjectEntityMatchesBody
+
+client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+)
+client.project_entity.replace_project_entity_matches(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ request=UpdateProjectEntityMatchesBody(
+ entity_ids=["entity_ids", "entity_ids"],
+ ),
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**project_id:** `str`
+
+
+
+
+
+-
+
+**project_entity_id:** `str`
+
+
+
+
+
+-
+
+**request:** `UpdateProjectEntityMatchesBody`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
@@ -5016,6 +5200,7 @@ client = Sayari(
client.project.create_project(
request=CreateProjectRequest(
label="My First Project",
+ type="network",
share=ProjectShareOnCreate(
org="admin",
),
@@ -5140,6 +5325,14 @@ client.project.get_projects(
-
+**type:** `typing.Optional[ProjectType]` — Which project types to return
+
+
+
+
+
+-
+
**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
diff --git a/src/sayari/__init__.py b/src/sayari/__init__.py
index d73b5232..26543ce7 100644
--- a/src/sayari/__init__.py
+++ b/src/sayari/__init__.py
@@ -204,6 +204,7 @@
ProjectEntity,
ProjectEntityUpstream,
ProjectShareOnCreate,
+ ProjectType,
ProjectWithMembers,
PsaSummary,
Role,
@@ -279,6 +280,8 @@
TradeCounts,
Translation,
UpdateEntityTagsResponse,
+ UpdateProjectEntityMatchesBody,
+ UpdateProjectEntityMatchesResponse,
UpdateProjectEntityTagsBody,
UpstreamCount,
UpstreamInfo,
@@ -353,6 +356,7 @@
UnprocessableContentResponse,
)
from .shared_types import (
+ CaseInfo,
CaseStatus,
ClientName,
CompanyType,
@@ -467,6 +471,7 @@
"BusinessPurposeProperties",
"BusinessPurposeStandard",
"BuyerSearchResponse",
+ "CaseInfo",
"CaseStatus",
"ClientName",
"CompanyStatus",
@@ -692,6 +697,7 @@
"ProjectRiskChangesResponseData",
"ProjectRiskFactor",
"ProjectShareOnCreate",
+ "ProjectType",
"ProjectWithMembers",
"Psa",
"PsaEntity",
@@ -817,6 +823,8 @@
"UpdateProjectEntityAttributeRequest",
"UpdateProjectEntityAttributeResponse",
"UpdateProjectEntityAttributeResponseData",
+ "UpdateProjectEntityMatchesBody",
+ "UpdateProjectEntityMatchesResponse",
"UpdateProjectEntityTagsBody",
"UpstreamCount",
"UpstreamInfo",
diff --git a/src/sayari/core/client_wrapper.py b/src/sayari/core/client_wrapper.py
index f5ae1103..b2e88806 100644
--- a/src/sayari/core/client_wrapper.py
+++ b/src/sayari/core/client_wrapper.py
@@ -22,7 +22,7 @@ def get_headers(self) -> typing.Dict[str, str]:
headers: typing.Dict[str, str] = {
"X-Fern-Language": "Python",
"X-Fern-SDK-Name": "sayari",
- "X-Fern-SDK-Version": "0.1.43",
+ "X-Fern-SDK-Version": "0.1.44",
}
token = self._get_token()
if token is not None:
diff --git a/src/sayari/generated_types/types/identifier_type.py b/src/sayari/generated_types/types/identifier_type.py
index defba80a..bde8faac 100644
--- a/src/sayari/generated_types/types/identifier_type.py
+++ b/src/sayari/generated_types/types/identifier_type.py
@@ -44,6 +44,7 @@
"aus_credit_licence_number",
"aus_credit_rep_number",
"aus_passport",
+ "aus_trademark_reg_no",
"aut_firmenbuch_no",
"aut_uid",
"aze_tin_number",
@@ -287,8 +288,10 @@
"ind_passport",
"ind_permanent_account_number",
"ind_society_registration_number",
+ "ind_techsalerator_id",
"ind_tin",
"ind_trademark_submission_ref",
+ "ind_udyam",
"int_maritime_org_id",
"internal_curated_merge_id",
"internal_curated_split_id",
@@ -328,6 +331,7 @@
"jpn_edinet_code",
"jpn_trade_internal_shipment_id",
"kaz_bin",
+ "kaz_business_identification_number",
"kaz_identifier",
"kaz_okpo_num",
"kaz_state_reg_num",
@@ -545,6 +549,8 @@
"tjk_ein_number",
"tjk_tin_number",
"tokyo_stock_exchange_no",
+ "ton_reg_id",
+ "ton_tax_id",
"tto_biz_number",
"tun_passport",
"tur_id",
@@ -701,6 +707,7 @@
"wcpfc_rfmo_id",
"wipo_intl_ref_no",
"wipo_intl_reg_no",
+ "wsm_reg_id",
"xxx_acuris_id",
"xxx_cedar_rose_uid",
"xxx_crb_monitor_entity_id",
diff --git a/src/sayari/generated_types/types/risk.py b/src/sayari/generated_types/types/risk.py
index 46dcb8d2..478a2ac0 100644
--- a/src/sayari/generated_types/types/risk.py
+++ b/src/sayari/generated_types/types/risk.py
@@ -8,12 +8,17 @@
"aspi_uyghur_forced_labor_report_entity_adjacent",
"basel_aml",
"bis_addresses_high_diversion_risk",
+ "bis_affiliates_50_percent_rule",
"bis_boycott_requester_list",
+ "bis_entity_minority_ownership",
+ "bis_meu_minority_ownership",
"chinese_soe_adjacent",
"chinese_state_owned",
"cmic_entity",
"cmic_entity_50_percent_rule",
"controlled_by_aus_sanctioned",
+ "controlled_by_bis_entity",
+ "controlled_by_bis_meu",
"controlled_by_eu_sanctioned",
"controlled_by_jpn_sanctioned",
"controlled_by_ofac_fto_sanctioned",
@@ -40,12 +45,15 @@
"export_controls_bis_entity_50_percent_rule",
"export_controls_bis_meu",
"export_controls_bis_meu_50_percent_rule",
+ "export_controls_other",
+ "export_controls_other_adjacent",
"export_controls_section_1260h",
"export_controls_section_1260h_50_percent_rule",
"export_controls_unverified_list",
"export_controls_unverified_list_50_percent_rule",
"export_to_chinese_soe",
"export_to_sanctioned",
+ "export_to_sanctioned_other",
"export_to_soe",
"exports_bis_high_priority_items_critical_components_direct",
"exports_bis_high_priority_items_critical_components_indirect",
@@ -202,6 +210,7 @@
"owned_by_chinese_soe",
"owned_by_cmic_entity",
"owned_by_entity_in_export_controls",
+ "owned_by_entity_in_export_controls_other",
"owned_by_forced_labor_xinjiang_uflpa",
"owned_by_jpn_meti_end_user_entity",
"owned_by_jpn_mofa_export_ban_entity",
@@ -233,6 +242,7 @@
"owned_by_sanctioned_mys_moha_entity",
"owned_by_sanctioned_nld_mofa_entity",
"owned_by_sanctioned_nzl_mfat_rus_entity",
+ "owned_by_sanctioned_other_entity",
"owned_by_sanctioned_pol_mia_entity",
"owned_by_sanctioned_sgp_agc_entity",
"owned_by_sanctioned_ukr_nsdc_entity",
@@ -257,6 +267,7 @@
"owner_of_aspi_forced_labor_entity",
"owner_of_chinese_soe",
"owner_of_export_controls_entity",
+ "owner_of_export_controls_other_entity",
"owner_of_forced_labor_xinjiang_entity",
"owner_of_forced_labor_xinjiang_uflpa",
"owner_of_jpn_meti_end_user_entity",
@@ -289,6 +300,7 @@
"owner_of_sanctioned_mys_moha_entity",
"owner_of_sanctioned_nld_mofa_entity",
"owner_of_sanctioned_nzl_mfat_rus_entity",
+ "owner_of_sanctioned_other_entity",
"owner_of_sanctioned_pol_mia_entity",
"owner_of_sanctioned_sgp_agc_entity",
"owner_of_sanctioned_ukr_nsdc_entity",
@@ -311,6 +323,8 @@
"pep",
"pep_adjacent",
"psa_bis_boycott_requester_list",
+ "psa_bis_entity_minority_ownership",
+ "psa_bis_meu_minority_ownership",
"psa_chinese_state_owned",
"psa_cmic_entity_50_percent_rule",
"psa_entity_licensed_with_fsb_rf",
@@ -319,10 +333,12 @@
"psa_export_controls",
"psa_export_controls_bis_entity_50_percent_rule",
"psa_export_controls_bis_meu_50_percent_rule",
+ "psa_export_controls_other",
"psa_export_controls_section_1260h_50_percent_rule",
"psa_export_controls_unverified_list_50_percent_rule",
"psa_export_to_chinese_soe",
"psa_export_to_sanctioned",
+ "psa_export_to_sanctioned_other",
"psa_export_to_soe",
"psa_exports_bis_high_priority_items_critical_components_direct",
"psa_exports_bis_high_priority_items_critical_components_indirect",
@@ -429,6 +445,7 @@
"psa_owned_by_chinese_soe",
"psa_owned_by_cmic_entity",
"psa_owned_by_entity_in_export_controls",
+ "psa_owned_by_entity_in_export_controls_other",
"psa_owned_by_forced_labor_xinjiang_uflpa",
"psa_owned_by_jpn_meti_end_user_entity",
"psa_owned_by_jpn_mofa_export_ban_entity",
@@ -460,6 +477,7 @@
"psa_owned_by_sanctioned_mys_moha_entity",
"psa_owned_by_sanctioned_nld_mofa_entity",
"psa_owned_by_sanctioned_nzl_mfat_rus_entity",
+ "psa_owned_by_sanctioned_other_entity",
"psa_owned_by_sanctioned_pol_mia_entity",
"psa_owned_by_sanctioned_sgp_agc_entity",
"psa_owned_by_sanctioned_ukr_nsdc_entity",
@@ -484,6 +502,7 @@
"psa_owner_of_aspi_forced_labor_entity",
"psa_owner_of_chinese_soe",
"psa_owner_of_export_controls_entity",
+ "psa_owner_of_export_controls_other_entity",
"psa_owner_of_forced_labor_xinjiang_entity",
"psa_owner_of_forced_labor_xinjiang_uflpa",
"psa_owner_of_jpn_meti_end_user_entity",
@@ -516,6 +535,7 @@
"psa_owner_of_sanctioned_mys_moha_entity",
"psa_owner_of_sanctioned_nld_mofa_entity",
"psa_owner_of_sanctioned_nzl_mfat_rus_entity",
+ "psa_owner_of_sanctioned_other_entity",
"psa_owner_of_sanctioned_pol_mia_entity",
"psa_owner_of_sanctioned_sgp_agc_entity",
"psa_owner_of_sanctioned_ukr_nsdc_entity",
@@ -558,6 +578,7 @@
"psa_sanctioned_mys_moha",
"psa_sanctioned_nld_mofa",
"psa_sanctioned_nzl_mfat_rus",
+ "psa_sanctioned_other",
"psa_sanctioned_pol_mia",
"psa_sanctioned_sgp_agc",
"psa_sanctioned_ukr_nsdc",
@@ -616,6 +637,8 @@
"sanctioned_mys_moha",
"sanctioned_nld_mofa",
"sanctioned_nzl_mfat_rus",
+ "sanctioned_other",
+ "sanctioned_other_adjacent",
"sanctioned_pol_mia",
"sanctioned_sgp_agc",
"sanctioned_ukr_nsdc",
diff --git a/src/sayari/generated_types/types/weak_identifier_type.py b/src/sayari/generated_types/types/weak_identifier_type.py
index efdfc676..f5b9dd81 100644
--- a/src/sayari/generated_types/types/weak_identifier_type.py
+++ b/src/sayari/generated_types/types/weak_identifier_type.py
@@ -54,6 +54,7 @@
"ind_sebi",
"ind_shipment_bill_id",
"int_trade_internal_shipment_id",
+ "international_trademark_no",
"irl_registration_no",
"irn_reg_number",
"irq_provision_card",
@@ -129,6 +130,7 @@
"south_africa_partial_id_number",
"svk_filing_number",
"tokyo_shoko_id",
+ "ton_foreign_investor_id",
"tur_declaration_number",
"tur_office_registration_number",
"tur_partial_mersis_number",
diff --git a/src/sayari/project/__init__.py b/src/sayari/project/__init__.py
index 8570e7de..bc92b03d 100644
--- a/src/sayari/project/__init__.py
+++ b/src/sayari/project/__init__.py
@@ -17,6 +17,7 @@
ProjectEntity,
ProjectEntityUpstream,
ProjectShareOnCreate,
+ ProjectType,
ProjectWithMembers,
PsaSummary,
Role,
@@ -47,6 +48,7 @@
"ProjectEntity",
"ProjectEntityUpstream",
"ProjectShareOnCreate",
+ "ProjectType",
"ProjectWithMembers",
"PsaSummary",
"Role",
diff --git a/src/sayari/project/client.py b/src/sayari/project/client.py
index 6962d3d7..a570b664 100644
--- a/src/sayari/project/client.py
+++ b/src/sayari/project/client.py
@@ -21,6 +21,7 @@
from ..shared_errors.types.internal_server_error_response import InternalServerErrorResponse
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
+from .types.project_type import ProjectType
from .types.get_projects_response import GetProjectsResponse
from .types.delete_project_response import DeleteProjectResponse
from ..core.jsonable_encoder import jsonable_encoder
@@ -63,6 +64,7 @@ def create_project(
client.project.create_project(
request=CreateProjectRequest(
label="My First Project",
+ type="network",
share=ProjectShareOnCreate(
org="admin",
),
@@ -159,6 +161,7 @@ def get_projects(
prev: typing.Optional[str] = None,
limit: typing.Optional[int] = None,
archived: typing.Optional[bool] = None,
+ type: typing.Optional[ProjectType] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> GetProjectsResponse:
"""
@@ -178,6 +181,9 @@ def get_projects(
archived : typing.Optional[bool]
Toggle between projects that have been archived (true) or not (false). Defaults to false.
+ type : typing.Optional[ProjectType]
+ Which project types to return
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -206,6 +212,7 @@ def get_projects(
"prev": prev,
"limit": limit,
"archived": archived,
+ "type": type,
},
request_options=request_options,
)
@@ -430,6 +437,7 @@ async def main() -> None:
await client.project.create_project(
request=CreateProjectRequest(
label="My First Project",
+ type="network",
share=ProjectShareOnCreate(
org="admin",
),
@@ -529,6 +537,7 @@ async def get_projects(
prev: typing.Optional[str] = None,
limit: typing.Optional[int] = None,
archived: typing.Optional[bool] = None,
+ type: typing.Optional[ProjectType] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> GetProjectsResponse:
"""
@@ -548,6 +557,9 @@ async def get_projects(
archived : typing.Optional[bool]
Toggle between projects that have been archived (true) or not (false). Defaults to false.
+ type : typing.Optional[ProjectType]
+ Which project types to return
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -584,6 +596,7 @@ async def main() -> None:
"prev": prev,
"limit": limit,
"archived": archived,
+ "type": type,
},
request_options=request_options,
)
diff --git a/src/sayari/project/types/__init__.py b/src/sayari/project/types/__init__.py
index 51e53adf..22242d37 100644
--- a/src/sayari/project/types/__init__.py
+++ b/src/sayari/project/types/__init__.py
@@ -16,6 +16,7 @@
from .project_entity import ProjectEntity
from .project_entity_upstream import ProjectEntityUpstream
from .project_share_on_create import ProjectShareOnCreate
+from .project_type import ProjectType
from .project_with_members import ProjectWithMembers
from .psa_summary import PsaSummary
from .role import Role
@@ -45,6 +46,7 @@
"ProjectEntity",
"ProjectEntityUpstream",
"ProjectShareOnCreate",
+ "ProjectType",
"ProjectWithMembers",
"PsaSummary",
"Role",
diff --git a/src/sayari/project/types/create_project_request.py b/src/sayari/project/types/create_project_request.py
index a35ec56e..88a13eee 100644
--- a/src/sayari/project/types/create_project_request.py
+++ b/src/sayari/project/types/create_project_request.py
@@ -2,8 +2,9 @@
from ...core.pydantic_utilities import UniversalBaseModel
import typing
-from .project_share_on_create import ProjectShareOnCreate
+from .project_type import ProjectType
import pydantic
+from .project_share_on_create import ProjectShareOnCreate
from ...core.pydantic_utilities import IS_PYDANTIC_V2
@@ -15,6 +16,7 @@ class CreateProjectRequest(UniversalBaseModel):
CreateProjectRequest(
label="My First Project",
+ type="network",
share=ProjectShareOnCreate(
org="admin",
),
@@ -22,6 +24,11 @@ class CreateProjectRequest(UniversalBaseModel):
"""
label: str
+ type: typing.Optional[ProjectType] = pydantic.Field(default=None)
+ """
+ Specifies which type of project to create. Defaults to 'network'
+ """
+
share: typing.Optional[ProjectShareOnCreate] = pydantic.Field(default=None)
"""
Specifies access levels available to users in a project within an organization. For comprehensive access, the admin role is recommended.
diff --git a/src/sayari/project/types/create_project_response.py b/src/sayari/project/types/create_project_response.py
index 8ba9371f..0e0ea8ec 100644
--- a/src/sayari/project/types/create_project_response.py
+++ b/src/sayari/project/types/create_project_response.py
@@ -27,6 +27,7 @@ class CreateProjectResponse(UniversalBaseModel):
search=0,
),
is_scrm=False,
+ type="network",
),
)
"""
diff --git a/src/sayari/project/types/delete_project_response.py b/src/sayari/project/types/delete_project_response.py
index 6fc75cc3..6d6ba11a 100644
--- a/src/sayari/project/types/delete_project_response.py
+++ b/src/sayari/project/types/delete_project_response.py
@@ -20,6 +20,7 @@ class DeleteProjectResponse(UniversalBaseModel):
archived=False,
created="2024-04-24 13:43:56.546705+00",
updated="2024-04-24 13:43:56.546705+00",
+ type="network",
counts=ProjectCounts(
entity=2,
graph=0,
diff --git a/src/sayari/project/types/get_projects_response.py b/src/sayari/project/types/get_projects_response.py
index 10ef3ec1..74c539a3 100644
--- a/src/sayari/project/types/get_projects_response.py
+++ b/src/sayari/project/types/get_projects_response.py
@@ -29,6 +29,7 @@ class GetProjectsResponse(UniversalBaseModel):
archived=False,
created="2023-10-25 14:44:06.322117+00",
updated="2023-10-25 14:44:06.322117+00",
+ type="network",
counts=ProjectCounts(),
members=[
RoleMember(
@@ -46,6 +47,7 @@ class GetProjectsResponse(UniversalBaseModel):
archived=False,
created="2023-10-24 20:41:21.235451+00",
updated="2023-10-24 20:41:21.235451+00",
+ type="network",
counts=ProjectCounts(
graph=1,
entity=2530,
diff --git a/src/sayari/project/types/project.py b/src/sayari/project/types/project.py
index 55dc9eaf..d063a54c 100644
--- a/src/sayari/project/types/project.py
+++ b/src/sayari/project/types/project.py
@@ -4,6 +4,7 @@
import pydantic
from .project_counts import ProjectCounts
import typing
+from .project_type import ProjectType
from ...core.pydantic_utilities import IS_PYDANTIC_V2
@@ -26,7 +27,12 @@ class Project(UniversalBaseModel):
created: str
updated: str
counts: ProjectCounts
- is_scrm: typing.Optional[bool] = None
+ is_scrm: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ **Deprecated.** Use `type == 'supply_chain'` instead.
+ """
+
+ type: ProjectType
if IS_PYDANTIC_V2:
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
diff --git a/src/sayari/project/types/project_type.py b/src/sayari/project/types/project_type.py
new file mode 100644
index 00000000..caf22caf
--- /dev/null
+++ b/src/sayari/project/types/project_type.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+ProjectType = typing.Union[typing.Literal["network", "supply_chain"], typing.Any]
diff --git a/src/sayari/project_entity/__init__.py b/src/sayari/project_entity/__init__.py
index e5d8e9bb..74f0784c 100644
--- a/src/sayari/project_entity/__init__.py
+++ b/src/sayari/project_entity/__init__.py
@@ -63,6 +63,8 @@
TradeCounts,
Translation,
UpdateEntityTagsResponse,
+ UpdateProjectEntityMatchesBody,
+ UpdateProjectEntityMatchesResponse,
UpdateProjectEntityTagsBody,
UpstreamCount,
UpstreamInfo,
@@ -131,6 +133,8 @@
"TradeCounts",
"Translation",
"UpdateEntityTagsResponse",
+ "UpdateProjectEntityMatchesBody",
+ "UpdateProjectEntityMatchesResponse",
"UpdateProjectEntityTagsBody",
"UpstreamCount",
"UpstreamInfo",
diff --git a/src/sayari/project_entity/client.py b/src/sayari/project_entity/client.py
index 427139e7..668880ab 100644
--- a/src/sayari/project_entity/client.py
+++ b/src/sayari/project_entity/client.py
@@ -24,6 +24,8 @@
from ..core.api_error import ApiError
from .types.project_entities_filter import ProjectEntitiesFilter
from .types.project_entities_response import ProjectEntitiesResponse
+from .types.update_project_entity_matches_body import UpdateProjectEntityMatchesBody
+from .types.update_project_entity_matches_response import UpdateProjectEntityMatchesResponse
from .types.resolution_attributes import ResolutionAttributes
from .types.project_entity_id_response import ProjectEntityIdResponse
from .types.save_project_entity_body import SaveProjectEntityBody
@@ -439,6 +441,258 @@ def get_project_entity(
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ def add_project_entity_matches(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ *,
+ request: UpdateProjectEntityMatchesBody,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateProjectEntityMatchesResponse:
+ """
+ Adds matches to a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ request : UpdateProjectEntityMatchesBody
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateProjectEntityMatchesResponse
+
+ Examples
+ --------
+ from sayari import Sayari
+ from sayari.project_entity import UpdateProjectEntityMatchesBody
+
+ client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+ client.project_entity.add_project_entity_matches(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ request=UpdateProjectEntityMatchesBody(
+ entity_ids=["entity_ids", "entity_ids"],
+ ),
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/matches",
+ method="POST",
+ json=convert_and_respect_annotation_metadata(
+ object_=request, annotation=UpdateProjectEntityMatchesBody, direction="write"
+ ),
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ UpdateProjectEntityMatchesResponse,
+ parse_obj_as(
+ type_=UpdateProjectEntityMatchesResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ if _response.status_code == 400:
+ raise BadRequest(
+ typing.cast(
+ BadRequestResponse,
+ parse_obj_as(
+ type_=BadRequestResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 401:
+ raise Unauthorized(
+ typing.cast(
+ UnauthorizedResponse,
+ parse_obj_as(
+ type_=UnauthorizedResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFound(
+ typing.cast(
+ NotFoundResponse,
+ parse_obj_as(
+ type_=NotFoundResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 405:
+ raise MethodNotAllowed(
+ typing.cast(
+ MethodNotAllowedResponse,
+ parse_obj_as(
+ type_=MethodNotAllowedResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 429:
+ raise RateLimitExceeded(
+ typing.cast(
+ RateLimitResponse,
+ parse_obj_as(
+ type_=RateLimitResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ InternalServerErrorResponse,
+ parse_obj_as(
+ type_=InternalServerErrorResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
+ def replace_project_entity_matches(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ *,
+ request: UpdateProjectEntityMatchesBody,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateProjectEntityMatchesResponse:
+ """
+ Replace matches in a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ request : UpdateProjectEntityMatchesBody
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateProjectEntityMatchesResponse
+
+ Examples
+ --------
+ from sayari import Sayari
+ from sayari.project_entity import UpdateProjectEntityMatchesBody
+
+ client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+ client.project_entity.replace_project_entity_matches(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ request=UpdateProjectEntityMatchesBody(
+ entity_ids=["entity_ids", "entity_ids"],
+ ),
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/matches",
+ method="PATCH",
+ json=convert_and_respect_annotation_metadata(
+ object_=request, annotation=UpdateProjectEntityMatchesBody, direction="write"
+ ),
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ UpdateProjectEntityMatchesResponse,
+ parse_obj_as(
+ type_=UpdateProjectEntityMatchesResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ if _response.status_code == 400:
+ raise BadRequest(
+ typing.cast(
+ BadRequestResponse,
+ parse_obj_as(
+ type_=BadRequestResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 401:
+ raise Unauthorized(
+ typing.cast(
+ UnauthorizedResponse,
+ parse_obj_as(
+ type_=UnauthorizedResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFound(
+ typing.cast(
+ NotFoundResponse,
+ parse_obj_as(
+ type_=NotFoundResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 405:
+ raise MethodNotAllowed(
+ typing.cast(
+ MethodNotAllowedResponse,
+ parse_obj_as(
+ type_=MethodNotAllowedResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 429:
+ raise RateLimitExceeded(
+ typing.cast(
+ RateLimitResponse,
+ parse_obj_as(
+ type_=RateLimitResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ InternalServerErrorResponse,
+ parse_obj_as(
+ type_=InternalServerErrorResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
def delete_project_entity(
self, project_id: str, project_entity_id: str, *, request_options: typing.Optional[RequestOptions] = None
) -> None:
@@ -782,7 +1036,7 @@ def save_project_entity(
*,
request: SaveProjectEntityBody,
request_options: typing.Optional[RequestOptions] = None,
- ) -> ProjectEntityIdResponse:
+ ) -> SingleProjectEntityResponse:
"""
Stores a project entity given entity IDs and a list of attributes.
@@ -797,7 +1051,7 @@ def save_project_entity(
Returns
-------
- ProjectEntityIdResponse
+ SingleProjectEntityResponse
Examples
--------
@@ -832,9 +1086,9 @@ def save_project_entity(
try:
if 200 <= _response.status_code < 300:
return typing.cast(
- ProjectEntityIdResponse,
+ SingleProjectEntityResponse,
parse_obj_as(
- type_=ProjectEntityIdResponse, # type: ignore
+ type_=SingleProjectEntityResponse, # type: ignore
object_=_response.json(),
),
)
@@ -2391,6 +2645,274 @@ async def main() -> None:
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ async def add_project_entity_matches(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ *,
+ request: UpdateProjectEntityMatchesBody,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateProjectEntityMatchesResponse:
+ """
+ Adds matches to a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ request : UpdateProjectEntityMatchesBody
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateProjectEntityMatchesResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from sayari import AsyncSayari
+ from sayari.project_entity import UpdateProjectEntityMatchesBody
+
+ client = AsyncSayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+
+
+ async def main() -> None:
+ await client.project_entity.add_project_entity_matches(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ request=UpdateProjectEntityMatchesBody(
+ entity_ids=["entity_ids", "entity_ids"],
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/matches",
+ method="POST",
+ json=convert_and_respect_annotation_metadata(
+ object_=request, annotation=UpdateProjectEntityMatchesBody, direction="write"
+ ),
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ UpdateProjectEntityMatchesResponse,
+ parse_obj_as(
+ type_=UpdateProjectEntityMatchesResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ if _response.status_code == 400:
+ raise BadRequest(
+ typing.cast(
+ BadRequestResponse,
+ parse_obj_as(
+ type_=BadRequestResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 401:
+ raise Unauthorized(
+ typing.cast(
+ UnauthorizedResponse,
+ parse_obj_as(
+ type_=UnauthorizedResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFound(
+ typing.cast(
+ NotFoundResponse,
+ parse_obj_as(
+ type_=NotFoundResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 405:
+ raise MethodNotAllowed(
+ typing.cast(
+ MethodNotAllowedResponse,
+ parse_obj_as(
+ type_=MethodNotAllowedResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 429:
+ raise RateLimitExceeded(
+ typing.cast(
+ RateLimitResponse,
+ parse_obj_as(
+ type_=RateLimitResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ InternalServerErrorResponse,
+ parse_obj_as(
+ type_=InternalServerErrorResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
+ async def replace_project_entity_matches(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ *,
+ request: UpdateProjectEntityMatchesBody,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateProjectEntityMatchesResponse:
+ """
+ Replace matches in a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ request : UpdateProjectEntityMatchesBody
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateProjectEntityMatchesResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from sayari import AsyncSayari
+ from sayari.project_entity import UpdateProjectEntityMatchesBody
+
+ client = AsyncSayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+
+
+ async def main() -> None:
+ await client.project_entity.replace_project_entity_matches(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ request=UpdateProjectEntityMatchesBody(
+ entity_ids=["entity_ids", "entity_ids"],
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/matches",
+ method="PATCH",
+ json=convert_and_respect_annotation_metadata(
+ object_=request, annotation=UpdateProjectEntityMatchesBody, direction="write"
+ ),
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ UpdateProjectEntityMatchesResponse,
+ parse_obj_as(
+ type_=UpdateProjectEntityMatchesResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ if _response.status_code == 400:
+ raise BadRequest(
+ typing.cast(
+ BadRequestResponse,
+ parse_obj_as(
+ type_=BadRequestResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 401:
+ raise Unauthorized(
+ typing.cast(
+ UnauthorizedResponse,
+ parse_obj_as(
+ type_=UnauthorizedResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFound(
+ typing.cast(
+ NotFoundResponse,
+ parse_obj_as(
+ type_=NotFoundResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 405:
+ raise MethodNotAllowed(
+ typing.cast(
+ MethodNotAllowedResponse,
+ parse_obj_as(
+ type_=MethodNotAllowedResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 429:
+ raise RateLimitExceeded(
+ typing.cast(
+ RateLimitResponse,
+ parse_obj_as(
+ type_=RateLimitResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ InternalServerErrorResponse,
+ parse_obj_as(
+ type_=InternalServerErrorResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(status_code=_response.status_code, body=_response.text)
+ raise ApiError(status_code=_response.status_code, body=_response_json)
+
async def delete_project_entity(
self, project_id: str, project_entity_id: str, *, request_options: typing.Optional[RequestOptions] = None
) -> None:
@@ -2758,7 +3280,7 @@ async def save_project_entity(
*,
request: SaveProjectEntityBody,
request_options: typing.Optional[RequestOptions] = None,
- ) -> ProjectEntityIdResponse:
+ ) -> SingleProjectEntityResponse:
"""
Stores a project entity given entity IDs and a list of attributes.
@@ -2773,7 +3295,7 @@ async def save_project_entity(
Returns
-------
- ProjectEntityIdResponse
+ SingleProjectEntityResponse
Examples
--------
@@ -2816,9 +3338,9 @@ async def main() -> None:
try:
if 200 <= _response.status_code < 300:
return typing.cast(
- ProjectEntityIdResponse,
+ SingleProjectEntityResponse,
parse_obj_as(
- type_=ProjectEntityIdResponse, # type: ignore
+ type_=SingleProjectEntityResponse, # type: ignore
object_=_response.json(),
),
)
diff --git a/src/sayari/project_entity/types/__init__.py b/src/sayari/project_entity/types/__init__.py
index 95bc28ae..8e1bf22c 100644
--- a/src/sayari/project_entity/types/__init__.py
+++ b/src/sayari/project_entity/types/__init__.py
@@ -62,6 +62,8 @@
from .trade_counts import TradeCounts
from .translation import Translation
from .update_entity_tags_response import UpdateEntityTagsResponse
+from .update_project_entity_matches_body import UpdateProjectEntityMatchesBody
+from .update_project_entity_matches_response import UpdateProjectEntityMatchesResponse
from .update_project_entity_tags_body import UpdateProjectEntityTagsBody
from .upstream_count import UpstreamCount
from .upstream_info import UpstreamInfo
@@ -129,6 +131,8 @@
"TradeCounts",
"Translation",
"UpdateEntityTagsResponse",
+ "UpdateProjectEntityMatchesBody",
+ "UpdateProjectEntityMatchesResponse",
"UpdateProjectEntityTagsBody",
"UpstreamCount",
"UpstreamInfo",
diff --git a/src/sayari/project_entity/types/project_entities_response.py b/src/sayari/project_entity/types/project_entities_response.py
index 942590db..aee894eb 100644
--- a/src/sayari/project_entity/types/project_entities_response.py
+++ b/src/sayari/project_entity/types/project_entities_response.py
@@ -27,6 +27,7 @@ class ProjectEntitiesResponse(UniversalBaseModel):
TradeCounts,
UpstreamInfo,
)
+ from sayari.shared_types import CaseInfo
ProjectEntitiesResponse(
limit=20,
@@ -38,6 +39,8 @@ class ProjectEntitiesResponse(UniversalBaseModel):
upload_ids=[],
strength="strong",
created_at="2025-04-22 22:54:00.913586+00",
+ updated_at="2025-04-23 13:37:00.215522+00",
+ updated_by="auth0|5e45bd8caccd890e68147513",
attributes={
"name": AttributeValues(
match_resolution=True,
@@ -138,7 +141,11 @@ class ProjectEntitiesResponse(UniversalBaseModel):
products=[],
),
tags=[],
- case="not_assigned",
+ case=CaseInfo(
+ id="YZB88Y",
+ status="not_assigned",
+ created_at="2025-10-02",
+ ),
matches=[
ProjectEntityMatchResponse(
match_id="52z4Wa:dy-rh2g0QtzUN_jC_e9S_A",
diff --git a/src/sayari/project_entity/types/project_entity_response.py b/src/sayari/project_entity/types/project_entity_response.py
index dbd976cf..d57032bf 100644
--- a/src/sayari/project_entity/types/project_entity_response.py
+++ b/src/sayari/project_entity/types/project_entity_response.py
@@ -8,7 +8,7 @@
from .project_risk_factor import ProjectRiskFactor
from .upstream_info import UpstreamInfo
from .tag_response import TagResponse
-from ...shared_types.types.case_status import CaseStatus
+from ...shared_types.types.case_info import CaseInfo
from .project_entity_match_response import ProjectEntityMatchResponse
from ...core.pydantic_utilities import IS_PYDANTIC_V2
import pydantic
@@ -27,9 +27,10 @@ class ProjectEntityResponse(UniversalBaseModel):
risk_factors: typing.List[ProjectRiskFactor]
upstream: UpstreamInfo
tags: typing.List[TagResponse]
- case: typing.Optional[CaseStatus] = None
+ case: typing.Optional[CaseInfo] = None
matches: typing.List[ProjectEntityMatchResponse]
updated_at: typing.Optional[str] = None
+ updated_by: typing.Optional[str] = None
if IS_PYDANTIC_V2:
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
diff --git a/src/sayari/project_entity/types/single_project_entity_response.py b/src/sayari/project_entity/types/single_project_entity_response.py
index 1f9373e5..ddb3cffe 100644
--- a/src/sayari/project_entity/types/single_project_entity_response.py
+++ b/src/sayari/project_entity/types/single_project_entity_response.py
@@ -25,6 +25,7 @@ class SingleProjectEntityResponse(UniversalBaseModel):
TradeCounts,
UpstreamInfo,
)
+ from sayari.shared_types import CaseInfo
SingleProjectEntityResponse(
data=ProjectEntityResponse(
@@ -34,6 +35,8 @@ class SingleProjectEntityResponse(UniversalBaseModel):
upload_ids=[],
strength="strong",
created_at="2025-04-22 22:54:00.913586+00",
+ updated_at="2025-04-23 13:37:00.215522+00",
+ updated_by="auth0|5e45bd8caccd890e68147513",
attributes={
"name": AttributeValues(
match_resolution=True,
@@ -134,7 +137,11 @@ class SingleProjectEntityResponse(UniversalBaseModel):
products=[],
),
tags=[],
- case="not_assigned",
+ case=CaseInfo(
+ id="YVB88Y",
+ status="not_assigned",
+ created_at="2025-10-02",
+ ),
matches=[
ProjectEntityMatchResponse(
match_id="52z4Wa:dy-rh2g0QtzUN_jC_e9S_A",
diff --git a/src/sayari/project_entity/types/update_project_entity_matches_body.py b/src/sayari/project_entity/types/update_project_entity_matches_body.py
new file mode 100644
index 00000000..aeeefcc5
--- /dev/null
+++ b/src/sayari/project_entity/types/update_project_entity_matches_body.py
@@ -0,0 +1,28 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+
+
+class UpdateProjectEntityMatchesBody(UniversalBaseModel):
+ entity_ids: typing.List[str]
+ override_deleted: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Add a previously deleted match. Defaults to false.
+ """
+
+ limit: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Limit total matches to update. Defaults to 10. Max 50.
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/sayari/project_entity/types/update_project_entity_matches_response.py b/src/sayari/project_entity/types/update_project_entity_matches_response.py
new file mode 100644
index 00000000..5c1c308e
--- /dev/null
+++ b/src/sayari/project_entity/types/update_project_entity_matches_response.py
@@ -0,0 +1,22 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+
+
+class UpdateProjectEntityMatchesResponse(UniversalBaseModel):
+ data: typing.List[str] = pydantic.Field()
+ """
+ Updated entity ids
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/sayari/shared_types/__init__.py b/src/sayari/shared_types/__init__.py
index 1a2063e3..955bbad2 100644
--- a/src/sayari/shared_types/__init__.py
+++ b/src/sayari/shared_types/__init__.py
@@ -1,6 +1,7 @@
# This file was auto-generated by Fern from our API Definition.
from .types import (
+ CaseInfo,
CaseStatus,
ClientName,
CompanyType,
@@ -42,6 +43,7 @@
)
__all__ = [
+ "CaseInfo",
"CaseStatus",
"ClientName",
"CompanyType",
diff --git a/src/sayari/shared_types/types/__init__.py b/src/sayari/shared_types/types/__init__.py
index f93f2ae6..9ae0f709 100644
--- a/src/sayari/shared_types/types/__init__.py
+++ b/src/sayari/shared_types/types/__init__.py
@@ -1,5 +1,6 @@
# This file was auto-generated by Fern from our API Definition.
+from .case_info import CaseInfo
from .case_status import CaseStatus
from .client_name import ClientName
from .company_type import CompanyType
@@ -40,6 +41,7 @@
from .status import Status
__all__ = [
+ "CaseInfo",
"CaseStatus",
"ClientName",
"CompanyType",
diff --git a/src/sayari/shared_types/types/case_info.py b/src/sayari/shared_types/types/case_info.py
new file mode 100644
index 00000000..fef5a6dc
--- /dev/null
+++ b/src/sayari/shared_types/types/case_info.py
@@ -0,0 +1,23 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+from .case_status import CaseStatus
+import typing
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class CaseInfo(UniversalBaseModel):
+ id: str
+ status: CaseStatus
+ created_at: str
+ comment: typing.Optional[str] = None
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/sayari/shared_types/types/possibly_same_as.py b/src/sayari/shared_types/types/possibly_same_as.py
index 501c0ed3..e1b975d3 100644
--- a/src/sayari/shared_types/types/possibly_same_as.py
+++ b/src/sayari/shared_types/types/possibly_same_as.py
@@ -9,7 +9,7 @@
class PossiblySameAs(PaginatedResponse):
"""
- List of entities that are Possibly the Same As (PSA) the entity.
+ This property is deprecated. List of entities that are Possibly the Same As (PSA) the entity.
"""
offset: typing.Optional[int] = None