From 1d013b424bcd9c2d7230c2d272c16bb197e233b7 Mon Sep 17 00:00:00 2001
From: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
Date: Mon, 22 Sep 2025 18:22:50 +0000
Subject: [PATCH] SDK regeneration
---
reference.md | 710 ++++++++-------
src/sayari/__init__.py | 59 +-
src/sayari/auth/__init__.py | 4 +-
src/sayari/auth/types/__init__.py | 3 +-
src/sayari/auth/types/audience.py | 5 +
src/sayari/base_client.py | 4 -
src/sayari/environment.py | 5 +
.../generated_types/types/identifier_type.py | 11 +
.../generated_types/types/measurement_type.py | 4 +-
.../types/monetary_value_context.py | 18 +-
src/sayari/generated_types/types/risk.py | 15 +
src/sayari/generated_types/types/tag.py | 1 +
src/sayari/generated_types/types/unit.py | 2 +-
.../types/weak_identifier_type.py | 16 +
src/sayari/negative_news/client.py | 8 +-
src/sayari/negative_news/types/topics.py | 11 +-
src/sayari/project/__init__.py | 2 -
src/sayari/project/types/__init__.py | 2 -
src/sayari/project_entity/__init__.py | 34 +-
src/sayari/project_entity/client.py | 647 +++++++-------
src/sayari/project_entity/types/__init__.py | 34 +-
.../project_entity/types/attribute_type.py | 4 +-
.../project_entity/types/attribute_values.py | 2 +-
.../create_resolved_project_entity_request.py | 6 +-
.../types/field_match_quality.py | 5 +
.../project_entities_custom_field_filter.py | 24 +
...es.py => project_entities_exact_filter.py} | 13 +-
.../types/project_entities_filter.py | 107 ++-
.../types/project_entities_fuzzy_filter.py | 22 +
.../types/project_entities_response.py | 65 +-
.../types/project_entity_match_explanation.py | 27 +
.../types/project_entity_match_response.py | 4 +-
.../types/project_entity_response.py | 4 +-
.../types/project_entity_risk_summary_data.py | 22 +
.../project_entity_risk_summary_filters.py} | 24 +-
...roject_entity_risk_summary_network_path.py | 28 +
.../project_entity_risk_summary_response.py | 264 ++++++
...ct_entity_risk_summary_response_filters.py | 20 +
...project_entity_risk_summary_risk_factor.py | 31 +
.../project_entity/types/share_information.py | 21 +
.../types/single_project_entity_response.py | 65 +-
.../project_entity_attributes/__init__.py | 12 +
.../project_entity_attributes/client.py | 833 ++++++++++++++++--
.../types/__init__.py | 12 +
...create_project_entity_attribute_request.py | 33 +
...reate_project_entity_attribute_response.py | 38 +
..._project_entity_attribute_response_data.py | 22 +
.../types/project_entity_attribute.py | 22 +
.../types/project_entity_attribute_value.py | 20 +
.../project_entity_attributes_response.py | 63 ++
src/sayari/resolution/client.py | 20 +
.../resolution/types/resolution_body.py | 5 +
.../types/resolution_upload_body.py | 7 +-
src/sayari/shared_errors/__init__.py | 4 +
src/sayari/shared_errors/errors/__init__.py | 2 +
.../errors/unprocessable_content.py | 9 +
src/sayari/shared_errors/types/__init__.py | 2 +
.../types/not_acceptable_response.py | 2 +-
.../types/unprocessable_content_response.py | 25 +
src/sayari/shared_types/__init__.py | 6 +
src/sayari/shared_types/types/__init__.py | 6 +
.../types/case_status.py | 0
.../types/match_count.py | 0
.../types/match_strength_enum.py | 0
src/sayari/source/__init__.py | 5 -
src/sayari/source/client.py | 486 ----------
src/sayari/source/types/__init__.py | 7 -
.../source/types/get_source_response.py | 40 -
.../source/types/list_sources_response.py | 71 --
src/sayari/trade/client.py | 24 +-
src/sayari/trade/types/trade_filter_list.py | 10 +-
71 files changed, 2669 insertions(+), 1470 deletions(-)
create mode 100644 src/sayari/auth/types/audience.py
create mode 100644 src/sayari/project_entity/types/field_match_quality.py
create mode 100644 src/sayari/project_entity/types/project_entities_custom_field_filter.py
rename src/sayari/project_entity/types/{matched_attributes.py => project_entities_exact_filter.py} (61%)
rename src/sayari/{project => project_entity}/types/project_entities_filter.py (67%)
create mode 100644 src/sayari/project_entity/types/project_entities_fuzzy_filter.py
create mode 100644 src/sayari/project_entity/types/project_entity_match_explanation.py
create mode 100644 src/sayari/project_entity/types/project_entity_risk_summary_data.py
rename src/sayari/{source/types/source.py => project_entity/types/project_entity_risk_summary_filters.py} (52%)
create mode 100644 src/sayari/project_entity/types/project_entity_risk_summary_network_path.py
create mode 100644 src/sayari/project_entity/types/project_entity_risk_summary_response.py
create mode 100644 src/sayari/project_entity/types/project_entity_risk_summary_response_filters.py
create mode 100644 src/sayari/project_entity/types/project_entity_risk_summary_risk_factor.py
create mode 100644 src/sayari/project_entity/types/share_information.py
create mode 100644 src/sayari/project_entity_attributes/types/create_project_entity_attribute_request.py
create mode 100644 src/sayari/project_entity_attributes/types/create_project_entity_attribute_response.py
create mode 100644 src/sayari/project_entity_attributes/types/create_project_entity_attribute_response_data.py
create mode 100644 src/sayari/project_entity_attributes/types/project_entity_attribute.py
create mode 100644 src/sayari/project_entity_attributes/types/project_entity_attribute_value.py
create mode 100644 src/sayari/project_entity_attributes/types/project_entity_attributes_response.py
create mode 100644 src/sayari/shared_errors/errors/unprocessable_content.py
create mode 100644 src/sayari/shared_errors/types/unprocessable_content_response.py
rename src/sayari/{project_entity => shared_types}/types/case_status.py (100%)
rename src/sayari/{project_entity => shared_types}/types/match_count.py (100%)
rename src/sayari/{project_entity => shared_types}/types/match_strength_enum.py (100%)
delete mode 100644 src/sayari/source/__init__.py
delete mode 100644 src/sayari/source/client.py
delete mode 100644 src/sayari/source/types/__init__.py
delete mode 100644 src/sayari/source/types/get_source_response.py
delete mode 100644 src/sayari/source/types/list_sources_response.py
diff --git a/reference.md b/reference.md
index a76be864..3dae59b7 100644
--- a/reference.md
+++ b/reference.md
@@ -1180,7 +1180,7 @@ client.negative_news.negative_news(
-
-**until:** `typing.Optional[dt.date]` — Date cutoff for article inclusion in `YYYY-MM-DD` format. If provided, only articles published before this date will be included in results.
+**until:** `typing.Optional[dt.date]` — Date cutoff for article inclusion in `YYYY-MM-DD` format. If provided, only articles published after this date will be included in results.
@@ -2648,7 +2648,7 @@ client.ontology.get_source_types(
## ProjectEntityAttributes
-client.project_entity_attributes.update_project_entity_attribute(...)
+client.project_entity_attributes.get_project_entity_attributes(...)
-
@@ -2660,7 +2660,7 @@ client.ontology.get_source_types(
-
-Updates a specific attribute for a project entity.
+Retrieves all attributes for a project entity.
@@ -2676,21 +2676,14 @@ Updates a specific attribute for a project entity.
```python
from sayari import Sayari
-from sayari.project_entity_attributes import UpdateProjectEntityAttributeRequest
client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-client.project_entity_attributes.update_project_entity_attribute(
+client.project_entity_attributes.get_project_entity_attributes(
project_id="V03eYM",
project_entity_id="BG72YW",
- attribute_id="xG8wYP",
- request=UpdateProjectEntityAttributeRequest(
- field="name",
- value="updated name",
- match_resolution=True,
- ),
)
```
@@ -2723,22 +2716,6 @@ client.project_entity_attributes.update_project_entity_attribute(
-
-**attribute_id:** `str`
-
-
-
-
-
--
-
-**request:** `UpdateProjectEntityAttributeRequest`
-
-
-
-
-
--
-
**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -2751,8 +2728,7 @@ client.project_entity_attributes.update_project_entity_attribute(
-## ProjectEntitySupplyChainSnapshots
-client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_snapshots(...)
+client.project_entity_attributes.create_project_entity_attribute(...)
-
@@ -2764,7 +2740,7 @@ client.project_entity_attributes.update_project_entity_attribute(
-
-Retrieves all supply chain snapshots for a project entity.
+Creates a new attribute for a project entity.
@@ -2780,14 +2756,20 @@ Retrieves all supply chain snapshots for a project entity.
```python
from sayari import Sayari
+from sayari.project_entity_attributes import CreateProjectEntityAttributeRequest
client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_snapshots(
+client.project_entity_attributes.create_project_entity_attribute(
project_id="V03eYM",
project_entity_id="BG72YW",
+ request=CreateProjectEntityAttributeRequest(
+ field="custom_phone",
+ value="+1-555-123-4567",
+ match_resolution=False,
+ ),
)
```
@@ -2820,6 +2802,14 @@ client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_sna
-
+**request:** `CreateProjectEntityAttributeRequest`
+
+
+
+
+
+-
+
**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -2832,7 +2822,7 @@ client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_sna
-client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_snapshot_by_id(...)
+client.project_entity_attributes.update_project_entity_attribute(...)
-
@@ -2844,7 +2834,7 @@ client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_sna
-
-Retrieves a specific supply chain snapshot by ID for a project entity.
+Updates a specific attribute for a project entity.
@@ -2860,15 +2850,21 @@ Retrieves a specific supply chain snapshot by ID for a project entity.
```python
from sayari import Sayari
+from sayari.project_entity_attributes import UpdateProjectEntityAttributeRequest
client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_snapshot_by_id(
+client.project_entity_attributes.update_project_entity_attribute(
project_id="V03eYM",
project_entity_id="BG72YW",
- snapshot_id="sN4p2K",
+ attribute_id="xG8wYP",
+ request=UpdateProjectEntityAttributeRequest(
+ field="name",
+ value="updated name",
+ match_resolution=True,
+ ),
)
```
@@ -2901,7 +2897,15 @@ client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_sna
-
-**snapshot_id:** `str`
+**attribute_id:** `str`
+
+
+
+
+
+-
+
+**request:** `UpdateProjectEntityAttributeRequest`
@@ -2921,7 +2925,7 @@ client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_sna
-client.project_entity_supply_chain_snapshots.create_project_entity_supply_chain_snapshot(...)
+client.project_entity_attributes.delete_project_entity_attribute(...)
-
@@ -2933,7 +2937,7 @@ client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_sna
-
-Creates a new supply chain snapshot for a project entity.
+Deletes a specific attribute for a project entity.
@@ -2949,20 +2953,15 @@ Creates a new supply chain snapshot for a project entity.
```python
from sayari import Sayari
-from sayari.project_entity_supply_chain_snapshots import (
- CreateProjectEntitySupplyChainSnapshotRequest,
-)
client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-client.project_entity_supply_chain_snapshots.create_project_entity_supply_chain_snapshot(
- project_id="V03eYM",
- project_entity_id="BG72YW",
- request=CreateProjectEntitySupplyChainSnapshotRequest(
- label="Q1 2024 Supply Chain Analysis",
- ),
+client.project_entity_attributes.delete_project_entity_attribute(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ attribute_id="attribute_id",
)
```
@@ -2995,7 +2994,7 @@ client.project_entity_supply_chain_snapshots.create_project_entity_supply_chain_
-
-**request:** `CreateProjectEntitySupplyChainSnapshotRequest`
+**attribute_id:** `str`
@@ -3015,7 +3014,8 @@ client.project_entity_supply_chain_snapshots.create_project_entity_supply_chain_
-client.project_entity_supply_chain_snapshots.delete_project_entity_supply_chain_snapshot_by_id(...)
+## ProjectEntitySupplyChainSnapshots
+client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_snapshots(...)
-
@@ -3027,7 +3027,7 @@ client.project_entity_supply_chain_snapshots.create_project_entity_supply_chain_
-
-Deletes a specific supply chain snapshot by ID for a project entity.
+Retrieves all supply chain snapshots for a project entity.
@@ -3048,10 +3048,9 @@ client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-client.project_entity_supply_chain_snapshots.delete_project_entity_supply_chain_snapshot_by_id(
- project_id="project_id",
- project_entity_id="project_entity_id",
- snapshot_id="snapshot_id",
+client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_snapshots(
+ project_id="V03eYM",
+ project_entity_id="BG72YW",
)
```
@@ -3084,14 +3083,6 @@ client.project_entity_supply_chain_snapshots.delete_project_entity_supply_chain_
-
-**snapshot_id:** `str`
-
-
-
-
-
--
-
**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3104,8 +3095,7 @@ client.project_entity_supply_chain_snapshots.delete_project_entity_supply_chain_
-## ProjectEntity
-client.project_entity.create_project_entity(...)
+client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_snapshot_by_id(...)
-
@@ -3117,7 +3107,7 @@ client.project_entity_supply_chain_snapshots.delete_project_entity_supply_chain_
-
-The resolution endpoints allow users to search for matching entities against a provided list of attributes. The endpoint is similar to the search endpoint, except it's tuned to only return the best match so the client doesn't need to do as much or any post-processing work to filter down results.
+Retrieves a specific supply chain snapshot by ID for a project entity.
@@ -3133,21 +3123,15 @@ The resolution endpoints allow users to search for matching entities against a p
```python
from sayari import Sayari
-from sayari.project_entity import CreateResolvedProjectEntityRequest
client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-client.project_entity.create_project_entity(
- project_id="0n4473",
- request=CreateResolvedProjectEntityRequest(
- name=["Marvel Garment"],
- country=["KHM"],
- address=[
- "Beung Thom 3 Village, Sangkat Beung Thom, Posenchey, Phnom Penh"
- ],
- ),
+client.project_entity_supply_chain_snapshots.get_project_entity_supply_chain_snapshot_by_id(
+ project_id="V03eYM",
+ project_entity_id="BG72YW",
+ snapshot_id="sN4p2K",
)
```
@@ -3172,7 +3156,15 @@ client.project_entity.create_project_entity(
-
-**request:** `CreateResolvedProjectEntityRequest`
+**project_entity_id:** `str`
+
+
+
+
+
+-
+
+**snapshot_id:** `str`
@@ -3192,7 +3184,7 @@ client.project_entity.create_project_entity(
-client.project_entity.get_project_entities(...)
+client.project_entity_supply_chain_snapshots.create_project_entity_supply_chain_snapshot(...)
-
@@ -3204,7 +3196,7 @@ client.project_entity.create_project_entity(
-
-Retrieves a list of entities for a specific project with pagination support.
+Creates a new supply chain snapshot for a project entity.
@@ -3220,13 +3212,20 @@ Retrieves a list of entities for a specific project with pagination support.
```python
from sayari import Sayari
+from sayari.project_entity_supply_chain_snapshots import (
+ CreateProjectEntitySupplyChainSnapshotRequest,
+)
client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-client.project_entity.get_project_entities(
- project_id="YVB88Y",
+client.project_entity_supply_chain_snapshots.create_project_entity_supply_chain_snapshot(
+ project_id="V03eYM",
+ project_entity_id="BG72YW",
+ request=CreateProjectEntitySupplyChainSnapshotRequest(
+ label="Q1 2024 Supply Chain Analysis",
+ ),
)
```
@@ -3251,7 +3250,7 @@ client.project_entity.get_project_entities(
-
-**entity_id:** `typing.Optional[typing.Sequence[str]]` — Filter by entity IDs
+**project_entity_id:** `str`
@@ -3259,7 +3258,7 @@ client.project_entity.get_project_entities(
-
-**uploads:** `typing.Optional[typing.Sequence[str]]` — Filter by upload IDs
+**request:** `CreateProjectEntitySupplyChainSnapshotRequest`
@@ -3267,63 +3266,72 @@ client.project_entity.get_project_entities(
-
-**case_status:** `typing.Optional[typing.Sequence[CaseStatus]]` — Filter by case status
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
--
-**tags:** `typing.Optional[typing.Sequence[str]]` — Filter by tag IDs
-
+
+client.project_entity_supply_chain_snapshots.delete_project_entity_supply_chain_snapshot_by_id(...)
-
-**match_count:** `typing.Optional[MatchCount]` — Filter by match count
-
-
-
+#### 📝 Description
-
-**match_strength:** `typing.Optional[typing.Sequence[MatchStrengthEnum]]` — Filter by match strength
-
-
-
-
-
-**entity_types:** `typing.Optional[typing.Sequence[str]]` — Filter by entity types
-
+Deletes a specific supply chain snapshot by ID for a project entity.
+
+
+#### 🔌 Usage
+
-
-**geo_facets:** `typing.Optional[bool]` — Include geo facets
-
-
-
-
-
-**exact_match:** `typing.Optional[bool]` — Use exact matching
-
+```python
+from sayari import Sayari
+
+client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+)
+client.project_entity_supply_chain_snapshots.delete_project_entity_supply_chain_snapshot_by_id(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ snapshot_id="snapshot_id",
+)
+
+```
+
+
+
+#### ⚙️ Parameters
-
-**hs_codes:** `typing.Optional[typing.Sequence[str]]` — Filter by HS codes
+
+-
+
+**project_id:** `str`
@@ -3331,7 +3339,7 @@ client.project_entity.get_project_entities(
-
-**received_hs_codes:** `typing.Optional[typing.Sequence[str]]` — Filter by received HS codes
+**project_entity_id:** `str`
@@ -3339,7 +3347,7 @@ client.project_entity.get_project_entities(
-
-**shipped_hs_codes:** `typing.Optional[typing.Sequence[str]]` — Filter by shipped HS codes
+**snapshot_id:** `str`
@@ -3347,47 +3355,79 @@ client.project_entity.get_project_entities(
-
-**upstream_product:** `typing.Optional[typing.Sequence[str]]` — Filter by upstream product
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
--
-**limit:** `typing.Optional[int]` — Maximum number of results to return
-
+
+## ProjectEntity
+client.project_entity.create_project_entity(...)
-
-**token:** `typing.Optional[str]` — Pagination token
-
-
-
+#### 📝 Description
-
-**sort:** `typing.Optional[typing.Sequence[str]]` — Sort fields
-
+
+-
+
+The resolution endpoints allow users to search for matching entities against a provided list of attributes. The endpoint is similar to the search endpoint, except it's tuned to only return the best match so the client doesn't need to do as much or any post-processing work to filter down results.
+
+
+#### 🔌 Usage
+
-
-**aggregations:** `typing.Optional[typing.Sequence[str]]` — Fields to aggregate
-
+
+-
+
+```python
+from sayari import Sayari
+from sayari.project_entity import CreateResolvedProjectEntityRequest
+
+client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+)
+client.project_entity.create_project_entity(
+ project_id="0n4473",
+ request=CreateResolvedProjectEntityRequest(
+ name=["Marvel Garment"],
+ country=["KHM"],
+ address=[
+ "Beung Thom 3 Village, Sangkat Beung Thom, Posenchey, Phnom Penh"
+ ],
+ ),
+)
+
+```
+
+
+#### ⚙️ Parameters
+
+
+-
+
-
-**num_aggregation_buckets:** `typing.Optional[int]` — Number of aggregation buckets
+**project_id:** `str`
@@ -3395,7 +3435,7 @@ client.project_entity.get_project_entities(
-
-**risk:** `typing.Optional[typing.Sequence[Risk]]` — List of risk factors to filter by
+**request:** `CreateResolvedProjectEntityRequest`
@@ -3403,7 +3443,7 @@ client.project_entity.get_project_entities(
-
-**risk_category:** `typing.Optional[typing.Sequence[RiskCategory]]` — List of risk categories to filter by. An entity matches if it has any risk factor belonging to one of the specified categories
+**enable_llm_clean:** `typing.Optional[bool]` — Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
@@ -3423,7 +3463,7 @@ client.project_entity.get_project_entities(
-client.project_entity.get_project_entity(...)
+client.project_entity.get_project_entities(...)
-
@@ -3435,7 +3475,19 @@ client.project_entity.get_project_entities(
-
-Retrieves a specific entity in a project.
+Retrieves a list of entities for a specific project with pagination support.
+
+**Response Formats:**
+- **JSON** (default): Returns structured data with nested objects
+- **CSV**: Returns tabular data with dynamic columns for attributes and risk categories
+
+**CSV Format:**
+The CSV response includes dynamic columns based on the data:
+- `attribute_{field_name}`: Dynamic columns for each attribute field found in the data
+- `risk_category_{category_id}`: Dynamic columns for each risk category found in the data
+- Standard columns: project_id, project_entity_id, label, project_entity_url, upload_ids, strength, countries, tags, case_status, created_at, match_count, upstream_products, upstream_risk_factors, upstream_countries
+
+Use the `Accept: text/csv` header to request CSV format.
@@ -3451,14 +3503,43 @@ Retrieves a specific entity in a project.
```python
from sayari import Sayari
+from sayari.project_entity import (
+ ProjectEntitiesExactFilter,
+ ProjectEntitiesFilter,
+ ProjectEntitiesFuzzyFilter,
+)
client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-client.project_entity.get_project_entity(
- project_id="project_id",
- project_entity_id="project_entity_id",
+client.project_entity.get_project_entities(
+ project_id="YVB88Y",
+ limit=25,
+ filter=ProjectEntitiesFilter(
+ risk_category=["sanctions", "export_controls"],
+ upstream_product=["8536", "8544"],
+ shipment_country=["CHN", "VNM"],
+ tier_1_shipment_country=["CHN"],
+ city=ProjectEntitiesFuzzyFilter(
+ fuzzy=["moscow", "beijing"],
+ ),
+ identifier=ProjectEntitiesFuzzyFilter(
+ fuzzy=["253400V1H6ART1UQ0N98"],
+ ),
+ source=ProjectEntitiesExactFilter(
+ exact=[
+ "92edb8fe6615498f6e3e7b0e220f74e6",
+ "c10d482320f207d92aa814519c3bd686",
+ ],
+ ),
+ status=["active"],
+ bounds="55.680357237879136|-71.53607290158526|41.10876347746233|-40.963927098414736",
+ match_entity_id=["dy-rh2g0QtzUN_jC_e9S_A"],
+ entity_type=["company"],
+ upload=["upload_123"],
+ match_count="one",
+ ),
)
```
@@ -3483,7 +3564,7 @@ client.project_entity.get_project_entity(
-
-**project_entity_id:** `str`
+**next:** `typing.Optional[str]` — The pagination token for the next page of projects.
@@ -3491,7 +3572,7 @@ client.project_entity.get_project_entity(
-
-**entity_id:** `typing.Optional[typing.Sequence[str]]` — Filter by entity IDs
+**prev:** `typing.Optional[str]` — The pagination token for the previous page of projects.
@@ -3499,7 +3580,7 @@ client.project_entity.get_project_entity(
-
-**uploads:** `typing.Optional[typing.Sequence[str]]` — Filter by upload IDs
+**limit:** `typing.Optional[int]` — Limit total values returned for projects. Defaults to 100. Max 100.
@@ -3507,7 +3588,7 @@ client.project_entity.get_project_entity(
-
-**case_status:** `typing.Optional[typing.Sequence[CaseStatus]]` — Filter by case status
+**filter:** `typing.Optional[ProjectEntitiesFilter]` — Filter the project entities. Supports both dot notation (e.g., 'filter.attribute.name') and bracket notation (e.g., 'filter[attribute][name]') for nested field filtering.
@@ -3515,39 +3596,71 @@ client.project_entity.get_project_entity(
-
-**tags:** `typing.Optional[typing.Sequence[str]]` — Filter by tag IDs
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
+client.project_entity.get_project_entity(...)
-
-**match_count:** `typing.Optional[MatchCount]` — Filter by match count
-
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieves a specific entity in a project.
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from sayari import Sayari
+
+client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+)
+client.project_entity.get_project_entity(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+)
+
+```
-
-
--
-
-**match_strength:** `typing.Optional[typing.Sequence[MatchStrengthEnum]]` — Filter by match strength
-
+#### ⚙️ Parameters
+
-
-**entity_types:** `typing.Optional[typing.Sequence[str]]` — Filter by entity types
-
-
-
-
-
-**risk:** `typing.Optional[typing.Sequence[Risk]]` — List of risk factors to filter by
+**project_id:** `str`
@@ -3555,7 +3668,7 @@ client.project_entity.get_project_entity(
-
-**risk_category:** `typing.Optional[typing.Sequence[RiskCategory]]` — List of risk categories to filter by. An entity matches if it has any risk factor belonging to one of the specified categories
+**project_entity_id:** `str`
@@ -4147,6 +4260,105 @@ client.project_entity.project_entity_supply_chain(
+
+
+
+
+client.project_entity.get_project_entity_risk_summary(...)
+
+-
+
+#### 📝 Description
+
+
+-
+
+
+-
+
+Retrieves a risk summary for a specific project entity, including risk factors with network paths and risk intelligence data.
+
+**Response includes:**
+- Risk factors with their levels (elevated, high, critical)
+- Network paths showing relationships between entities
+- Risk intelligence scores and metadata
+- Risk categories and source entity information
+
+
+
+
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from sayari import Sayari
+from sayari.project_entity import ProjectEntityRiskSummaryFilters
+
+client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+)
+client.project_entity.get_project_entity_risk_summary(
+ project_id="YVB88Y",
+ project_entity_id="52z4Wa",
+ filter=ProjectEntityRiskSummaryFilters(
+ risk_factor=["sanctioned", "regulatory_action"],
+ risk_category=["sanctions", "export_controls"],
+ ),
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**project_id:** `str`
+
+
+
+
+
+-
+
+**project_entity_id:** `str`
+
+
+
+
+
+-
+
+**filter:** `ProjectEntityRiskSummaryFilters` — Filter risk factors by risk factor IDs and risk categories
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
@@ -4876,6 +5088,14 @@ client.resolution.resolution(
-
+**enable_llm_clean:** `typing.Optional[bool]` — Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+
+
+
+
+
+-
+
**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -4924,9 +5144,14 @@ client = Sayari(
)
client.resolution.resolution_post(
limit=1,
+ enable_llm_clean=False,
request=ResolutionBody(
- name=["Oleg Deripaska"],
- country=["RUS"],
+ name=["Chongqing Jingyou Zhicai New Materials Co."],
+ address=[
+ "4-2, Building B2, No. 5, Middle Mount Huangshan Avenue, Gaoxinyuan, Dazhulin Street, Liangjiang New District, Chongqing,Chongqing,continuation,CN"
+ ],
+ country=["CHN"],
+ enable_llm_clean=False,
),
)
@@ -4968,6 +5193,14 @@ client.resolution.resolution_post(
-
+**enable_llm_clean:** `typing.Optional[bool]` — Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+
+
+
+
+
+-
+
**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -5118,11 +5351,17 @@ client = Sayari(
client.resolution.resolution_upload(
project_id="V03eYM",
request=ResolutionUploadBody(
- filename="vbeck.json",
+ filename="testblah.csv",
+ enable_llm_clean=False,
data=[
ResolutionBody(
- name=["victoria beckham limited"],
- tags=["spice girls"],
+ name=[
+ "Chongqing Jingyou Zhicai New Materials Co. ABC XYZ Blah Blah Nonsense 1 489 929 49492 1839 1848"
+ ],
+ address=[
+ "4-2, Building B2, No. 5, Middle Mount Huangshan Avenue, Gaoxinyuan, Dazhulin Street, Liangjiang New District, Chongqing,Chongqing,continuation,CN"
+ ],
+ country=["CHN"],
)
],
),
@@ -5789,157 +6028,6 @@ client.search.search_record_get(
-
-
-
-
-## Source
-client.source.list_sources(...)
-
--
-
-#### 📝 Description
-
-
--
-
-
--
-
-This endpoint is deprecated. Use /v1/ontology/sources instead. Returns metadata for all sources that Sayari collects data from
-
-
-
-
-
-#### 🔌 Usage
-
-
--
-
-
--
-
-```python
-from sayari import Sayari
-
-client = Sayari(
- client_id="YOUR_CLIENT_ID",
- client_secret="YOUR_CLIENT_SECRET",
-)
-client.source.list_sources(
- limit=2,
-)
-
-```
-
-
-
-
-
-#### ⚙️ Parameters
-
-
--
-
-
--
-
-**limit:** `typing.Optional[int]` — A limit on the number of objects to be returned with a range between 1 and 100. Defaults to 100.
-
-
-
-
-
--
-
-**offset:** `typing.Optional[int]` — Number of results to skip before returning response. Defaults to 0.
-
-
-
-
-
--
-
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
-
-
-
-
-
-
-
-
-
-
-
-client.source.get_source(...)
-
--
-
-#### 📝 Description
-
-
--
-
-
--
-
-This endpoint is deprecated. Use /v1/ontology/sources instead. Returns metadata for a source that Sayari collects data from
-
-
-
-
-
-#### 🔌 Usage
-
-
--
-
-
--
-
-```python
-from sayari import Sayari
-
-client = Sayari(
- client_id="YOUR_CLIENT_ID",
- client_secret="YOUR_CLIENT_SECRET",
-)
-client.source.get_source(
- id="f4396e4b8a41d1fd9f09ea94d2ebedb9",
-)
-
-```
-
-
-
-
-
-#### ⚙️ Parameters
-
-
--
-
-
--
-
-**id:** `str` — The unique identifier for a source in the database
-
-
-
-
-
--
-
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
-
-
-
-
-
-
-
@@ -6212,7 +6300,7 @@ client.trade.search_shipments(
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
@@ -6230,7 +6318,7 @@ client.trade.search_shipments(
-
-**limit:** `typing.Optional[int]` — A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+**limit:** `typing.Optional[int]` — A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
@@ -6322,7 +6410,7 @@ client.trade.search_suppliers(
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
@@ -6340,7 +6428,7 @@ client.trade.search_suppliers(
-
-**limit:** `typing.Optional[int]` — A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+**limit:** `typing.Optional[int]` — A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
@@ -6432,7 +6520,7 @@ client.trade.search_buyers(
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
@@ -6450,7 +6538,7 @@ client.trade.search_buyers(
-
-**limit:** `typing.Optional[int]` — A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+**limit:** `typing.Optional[int]` — A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
diff --git a/src/sayari/__init__.py b/src/sayari/__init__.py
index 95532d56..216b14d2 100644
--- a/src/sayari/__init__.py
+++ b/src/sayari/__init__.py
@@ -21,13 +21,12 @@
search,
shared_errors,
shared_types,
- source,
supply_chain,
trade,
traversal,
)
from .attributes import AddAttribute, AttributeProperties, AttributeResponse, AttributeResponseData, UpdateAttribute
-from .auth import AuthResponse
+from .auth import Audience, AuthResponse
from .base_types import CountQualifier, CustomFieldValue, PaginatedResponse, QualifiedCount
from .client import AsyncSayari, Sayari
from .entity import EntitySummaryResponse, GetEntityResponse
@@ -202,7 +201,6 @@
ProjectCounts,
ProjectEntitiesAggs,
ProjectEntitiesAggsDefinition,
- ProjectEntitiesFilter,
ProjectEntity,
ProjectEntityUpstream,
ProjectShareOnCreate,
@@ -225,26 +223,34 @@
AttributeValues,
AttributesResponse,
BusinessPurpose,
- CaseStatus,
CountType,
CreateResolvedProjectEntityRequest,
FacetBucket,
FacetsResponse,
+ FieldMatchQuality,
GroupedAttribute,
GroupedAttributeValue,
Location,
- MatchCount,
MatchProfileEnum,
- MatchStrengthEnum,
- MatchedAttributes,
ProductBucket,
ProductCount,
ProductMapping,
+ ProjectEntitiesCustomFieldFilter,
+ ProjectEntitiesExactFilter,
+ ProjectEntitiesFilter,
+ ProjectEntitiesFuzzyFilter,
ProjectEntitiesResponse,
ProjectEntityExistsResponseData,
ProjectEntityIdResponse,
+ ProjectEntityMatchExplanation,
ProjectEntityMatchResponse,
ProjectEntityResponse,
+ ProjectEntityRiskSummaryData,
+ ProjectEntityRiskSummaryFilters,
+ ProjectEntityRiskSummaryNetworkPath,
+ ProjectEntityRiskSummaryResponse,
+ ProjectEntityRiskSummaryResponseFilters,
+ ProjectEntityRiskSummaryRiskFactor,
ProjectEntitySupplyChainSummaryResponse,
ProjectEntitySupplyChainSummaryResponseData,
ProjectEntitySupplyChainUpstream,
@@ -254,6 +260,7 @@
ResolutionProfile,
RiskCategoriesSummary,
SaveProjectEntityBody,
+ ShareInformation,
SingleProjectEntityResponse,
SourceField,
SpecialFacetBucket,
@@ -268,6 +275,12 @@
UpstreamInfo,
)
from .project_entity_attributes import (
+ CreateProjectEntityAttributeRequest,
+ CreateProjectEntityAttributeResponse,
+ CreateProjectEntityAttributeResponseData,
+ ProjectEntityAttribute,
+ ProjectEntityAttributeValue,
+ ProjectEntityAttributesResponse,
UpdateProjectEntityAttributeRequest,
UpdateProjectEntityAttributeResponse,
UpdateProjectEntityAttributeResponseData,
@@ -327,8 +340,11 @@
RateLimitResponse,
Unauthorized,
UnauthorizedResponse,
+ UnprocessableContent,
+ UnprocessableContentResponse,
)
from .shared_types import (
+ CaseStatus,
ClientName,
CompanyType,
Coordinate,
@@ -343,6 +359,8 @@
EntitySummary,
EntityTranslatedLabel,
Identifier,
+ MatchCount,
+ MatchStrengthEnum,
PossiblySameAs,
PossiblySameAsData,
PossiblySameAsMatch,
@@ -365,7 +383,6 @@
SourceCountInfo,
Status,
)
-from .source import GetSourceResponse, ListSourcesResponse, Source
from .supply_chain import (
TradeTraversalComponent,
TradeTraversalData,
@@ -427,6 +444,7 @@
"AttributeValues",
"Attributes",
"AttributesResponse",
+ "Audience",
"AuthResponse",
"BadGateway",
"BadGatewayResponse",
@@ -463,6 +481,9 @@
"CountryData",
"CountryInfo",
"CountryProperties",
+ "CreateProjectEntityAttributeRequest",
+ "CreateProjectEntityAttributeResponse",
+ "CreateProjectEntityAttributeResponseData",
"CreateProjectEntitySupplyChainSnapshotRequest",
"CreateProjectEntitySupplyChainSnapshotResponse",
"CreateProjectRequest",
@@ -493,6 +514,7 @@
"EventInfo",
"FacetBucket",
"FacetsResponse",
+ "FieldMatchQuality",
"FilterList",
"FinanceType",
"FinancesData",
@@ -528,7 +550,6 @@
"GetProjectEntitiesResponse",
"GetProjectsResponse",
"GetRecordResponse",
- "GetSourceResponse",
"GroupedAttribute",
"GroupedAttributeValue",
"HistoryInfo",
@@ -544,7 +565,6 @@
"InternalServerError",
"InternalServerErrorResponse",
"Language",
- "ListSourcesResponse",
"Location",
"MatchCount",
"MatchExplanation",
@@ -552,7 +572,6 @@
"MatchQuality",
"MatchStrength",
"MatchStrengthEnum",
- "MatchedAttributes",
"MeasurementData",
"MeasurementInfo",
"MeasurementProperties",
@@ -625,13 +644,26 @@
"ProjectCounts",
"ProjectEntitiesAggs",
"ProjectEntitiesAggsDefinition",
+ "ProjectEntitiesCustomFieldFilter",
+ "ProjectEntitiesExactFilter",
"ProjectEntitiesFilter",
+ "ProjectEntitiesFuzzyFilter",
"ProjectEntitiesResponse",
"ProjectEntity",
+ "ProjectEntityAttribute",
+ "ProjectEntityAttributeValue",
+ "ProjectEntityAttributesResponse",
"ProjectEntityExistsResponseData",
"ProjectEntityIdResponse",
+ "ProjectEntityMatchExplanation",
"ProjectEntityMatchResponse",
"ProjectEntityResponse",
+ "ProjectEntityRiskSummaryData",
+ "ProjectEntityRiskSummaryFilters",
+ "ProjectEntityRiskSummaryNetworkPath",
+ "ProjectEntityRiskSummaryResponse",
+ "ProjectEntityRiskSummaryResponseFilters",
+ "ProjectEntityRiskSummaryRiskFactor",
"ProjectEntitySupplyChainSnapshotByIdResponse",
"ProjectEntitySupplyChainSnapshotData",
"ProjectEntitySupplyChainSnapshotDetailData",
@@ -699,6 +731,7 @@
"SayariEnvironment",
"SearchField",
"SearchResults",
+ "ShareInformation",
"SharesData",
"SharesInfo",
"SharesProperties",
@@ -714,7 +747,6 @@
"ShortestPathResponse",
"SingleProjectEntityResponse",
"SortField",
- "Source",
"SourceCountInfo",
"SourceField",
"SourceId",
@@ -760,6 +792,8 @@
"Unauthorized",
"UnauthorizedResponse",
"Unit",
+ "UnprocessableContent",
+ "UnprocessableContentResponse",
"UpdateAttribute",
"UpdateEntityTagsResponse",
"UpdateProjectEntityAttributeRequest",
@@ -799,7 +833,6 @@
"search",
"shared_errors",
"shared_types",
- "source",
"supply_chain",
"trade",
"traversal",
diff --git a/src/sayari/auth/__init__.py b/src/sayari/auth/__init__.py
index e05b0511..8efaff72 100644
--- a/src/sayari/auth/__init__.py
+++ b/src/sayari/auth/__init__.py
@@ -1,5 +1,5 @@
# This file was auto-generated by Fern from our API Definition.
-from .types import AuthResponse
+from .types import Audience, AuthResponse
-__all__ = ["AuthResponse"]
+__all__ = ["Audience", "AuthResponse"]
diff --git a/src/sayari/auth/types/__init__.py b/src/sayari/auth/types/__init__.py
index 299ab463..6e06f06e 100644
--- a/src/sayari/auth/types/__init__.py
+++ b/src/sayari/auth/types/__init__.py
@@ -1,5 +1,6 @@
# This file was auto-generated by Fern from our API Definition.
+from .audience import Audience
from .auth_response import AuthResponse
-__all__ = ["AuthResponse"]
+__all__ = ["Audience", "AuthResponse"]
diff --git a/src/sayari/auth/types/audience.py b/src/sayari/auth/types/audience.py
new file mode 100644
index 00000000..9ce8d76e
--- /dev/null
+++ b/src/sayari/auth/types/audience.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+Audience = typing.Union[typing.Literal["sayari.com", "uk.sayari.com"], typing.Any]
diff --git a/src/sayari/base_client.py b/src/sayari/base_client.py
index f4f0ab9a..81965b11 100644
--- a/src/sayari/base_client.py
+++ b/src/sayari/base_client.py
@@ -21,7 +21,6 @@
from .resolution.client import ResolutionClient
from .resource.client import ResourceClient
from .search.client import SearchClient
-from .source.client import SourceClient
from .supply_chain.client import SupplyChainClient
from .trade.client import TradeClient
from .traversal.client import TraversalClient
@@ -42,7 +41,6 @@
from .resolution.client import AsyncResolutionClient
from .resource.client import AsyncResourceClient
from .search.client import AsyncSearchClient
-from .source.client import AsyncSourceClient
from .supply_chain.client import AsyncSupplyChainClient
from .trade.client import AsyncTradeClient
from .traversal.client import AsyncTraversalClient
@@ -140,7 +138,6 @@ def __init__(
self.resolution = ResolutionClient(client_wrapper=self._client_wrapper)
self.resource = ResourceClient(client_wrapper=self._client_wrapper)
self.search = SearchClient(client_wrapper=self._client_wrapper)
- self.source = SourceClient(client_wrapper=self._client_wrapper)
self.supply_chain = SupplyChainClient(client_wrapper=self._client_wrapper)
self.trade = TradeClient(client_wrapper=self._client_wrapper)
self.traversal = TraversalClient(client_wrapper=self._client_wrapper)
@@ -238,7 +235,6 @@ def __init__(
self.resolution = AsyncResolutionClient(client_wrapper=self._client_wrapper)
self.resource = AsyncResourceClient(client_wrapper=self._client_wrapper)
self.search = AsyncSearchClient(client_wrapper=self._client_wrapper)
- self.source = AsyncSourceClient(client_wrapper=self._client_wrapper)
self.supply_chain = AsyncSupplyChainClient(client_wrapper=self._client_wrapper)
self.trade = AsyncTradeClient(client_wrapper=self._client_wrapper)
self.traversal = AsyncTraversalClient(client_wrapper=self._client_wrapper)
diff --git a/src/sayari/environment.py b/src/sayari/environment.py
index c8450a37..88b8bbe2 100644
--- a/src/sayari/environment.py
+++ b/src/sayari/environment.py
@@ -13,3 +13,8 @@ class SayariEnvironment(enum.Enum):
"""
Sayari development - utilized for internal testing before promotion to production
"""
+
+ PRODUCTION_UK = "https://api.uk.sayari.com"
+ """
+ Sayari production - UK environment
+ """
diff --git a/src/sayari/generated_types/types/identifier_type.py b/src/sayari/generated_types/types/identifier_type.py
index 1d3d269f..defba80a 100644
--- a/src/sayari/generated_types/types/identifier_type.py
+++ b/src/sayari/generated_types/types/identifier_type.py
@@ -67,6 +67,7 @@
"bih_mbs_number",
"bill_of_lading",
"bitcoin_address",
+ "blr_passport",
"blr_registration_number",
"blz_bccar_reg_no",
"bmu_registrar_of_companies_number",
@@ -108,6 +109,7 @@
"can_tm_registration_no",
"ccamlr_rfmo_id",
"ccs_registration",
+ "ccsbt_rfmo_id",
"che_ch_id_number",
"che_seco_sanction_number",
"che_uid_number",
@@ -211,6 +213,7 @@
"fl_prop_folio",
"fl_prop_folio_dade",
"fra_asset_freeze_id",
+ "fra_passport",
"fra_rna",
"fra_siren",
"fra_siret",
@@ -257,6 +260,7 @@
"hun_tax_number",
"iattc_rfmo_id",
"iban",
+ "iccat_rfmo_id",
"icij_offshore_internal_id",
"icij_offshore_node_id",
"idn_nik_id",
@@ -306,6 +310,7 @@
"isr_association_number",
"isr_company_number",
"isr_national_id",
+ "isr_passport",
"isr_pbc_number",
"ita_fiscal_code",
"ita_rea_number",
@@ -372,6 +377,7 @@
"mex_shipment_number",
"mex_tm_no",
"mex_yucatan_folio",
+ "mh_reg_id",
"mkd_archive_number",
"mkd_embs_branch_number",
"mkd_embs_number",
@@ -429,6 +435,7 @@
"omn_passport",
"on_business_id_number",
"ontario_corporation_number",
+ "open_sanctions_internal_id",
"pak_co_ntn",
"pak_egm_id",
"pak_ind_ntn",
@@ -503,6 +510,7 @@
"sgp_passport",
"sgp_unqiue_entity_number",
"siger_internal_id",
+ "slb_reg_id",
"slv_commercial_reg_number",
"slv_mcas",
"slv_numero_identificacion_tributaria",
@@ -560,6 +568,7 @@
"tza_brela_reg_num",
"tza_tansad_number",
"tza_tin",
+ "uga_tin",
"uk_company_number",
"uk_firm_reference_number",
"uk_passport",
@@ -567,6 +576,7 @@
"uk_title_number",
"ukr_fiu_list_number",
"ukr_moj_id",
+ "ukr_passport",
"ukr_reg_num",
"ukr_sanctions_nazk_company_internal_id",
"ukr_sanctions_nazk_person_internal_id",
@@ -688,6 +698,7 @@
"vnm_enterprise_code",
"vnm_person_id_no",
"vut_corp_reg_number",
+ "wcpfc_rfmo_id",
"wipo_intl_ref_no",
"wipo_intl_reg_no",
"xxx_acuris_id",
diff --git a/src/sayari/generated_types/types/measurement_type.py b/src/sayari/generated_types/types/measurement_type.py
index 1d88b454..92fc1dd8 100644
--- a/src/sayari/generated_types/types/measurement_type.py
+++ b/src/sayari/generated_types/types/measurement_type.py
@@ -2,4 +2,6 @@
import typing
-MeasurementType = typing.Union[typing.Literal["gross_weight", "net_weight", "quantity"], typing.Any]
+MeasurementType = typing.Union[
+ typing.Literal["built_area", "gross_weight", "land_area", "net_weight", "quantity"], typing.Any
+]
diff --git a/src/sayari/generated_types/types/monetary_value_context.py b/src/sayari/generated_types/types/monetary_value_context.py
index 92556eed..92f71e18 100644
--- a/src/sayari/generated_types/types/monetary_value_context.py
+++ b/src/sayari/generated_types/types/monetary_value_context.py
@@ -3,5 +3,21 @@
import typing
MonetaryValueContext = typing.Union[
- typing.Literal["assessed_value", "contract_value", "cost_insurance_and_freight", "free_on_board"], typing.Any
+ typing.Literal[
+ "assessed_value",
+ "cadastral_value",
+ "carriage_and_insurance_paid_to",
+ "carriage_paid_to",
+ "contract_value",
+ "cost_and_freight",
+ "cost_insurance_and_freight",
+ "delivered_at_place",
+ "delivered_at_place_unloaded",
+ "delivered_duty_paid",
+ "ex_works",
+ "free_alongside_ship",
+ "free_carrier",
+ "free_on_board",
+ ],
+ typing.Any,
]
diff --git a/src/sayari/generated_types/types/risk.py b/src/sayari/generated_types/types/risk.py
index 7fc8d2f8..46dcb8d2 100644
--- a/src/sayari/generated_types/types/risk.py
+++ b/src/sayari/generated_types/types/risk.py
@@ -27,6 +27,9 @@
"controlled_by_un_sanctioned",
"cpi_score",
"entity_licensed_with_fsb_rf",
+ "esg_score_high",
+ "esg_score_medium",
+ "esg_score_very_high",
"eu_50_percent_rule",
"eu_high_risk_third",
"eu_minority_ownership",
@@ -75,6 +78,7 @@
"exports_to_sanctioned_eu_dg_fisma_ec_entity",
"exports_to_sanctioned_eu_ec_regulation_833_2014_entity",
"exports_to_sanctioned_eu_ec_sanctions_map_entity",
+ "exports_to_sanctioned_eu_sanctions_entity",
"exports_to_sanctioned_fra_dgt_mefids_entity",
"exports_to_sanctioned_gbr_fcdo_entity",
"exports_to_sanctioned_gbr_hmt_ofsi_entity",
@@ -137,6 +141,7 @@
"formerly_sanctioned_eu_dg_fisma_ec",
"formerly_sanctioned_eu_ec_regulation_833_2014",
"formerly_sanctioned_eu_ec_sanctions_map",
+ "formerly_sanctioned_eu_sanctions",
"formerly_sanctioned_fra_dgt_mefids",
"formerly_sanctioned_gbr_fcdo",
"formerly_sanctioned_gbr_hmt_ofsi",
@@ -217,6 +222,7 @@
"owned_by_sanctioned_eu_dg_fisma_ec_entity",
"owned_by_sanctioned_eu_ec_regulation_833_2014_entity",
"owned_by_sanctioned_eu_ec_sanctions_map_entity",
+ "owned_by_sanctioned_eu_sanctions_entity",
"owned_by_sanctioned_fra_dgt_mefids_entity",
"owned_by_sanctioned_gbr_fcdo_entity",
"owned_by_sanctioned_gbr_hmt_ofsi_entity",
@@ -272,6 +278,7 @@
"owner_of_sanctioned_eu_dg_fisma_ec_entity",
"owner_of_sanctioned_eu_ec_regulation_833_2014_entity",
"owner_of_sanctioned_eu_ec_sanctions_map_entity",
+ "owner_of_sanctioned_eu_sanctions_entity",
"owner_of_sanctioned_fra_dgt_mefids_entity",
"owner_of_sanctioned_gbr_fcdo_entity",
"owner_of_sanctioned_gbr_hmt_ofsi_entity",
@@ -348,6 +355,7 @@
"psa_exports_to_sanctioned_eu_dg_fisma_ec_entity",
"psa_exports_to_sanctioned_eu_ec_regulation_833_2014_entity",
"psa_exports_to_sanctioned_eu_ec_sanctions_map_entity",
+ "psa_exports_to_sanctioned_eu_sanctions_entity",
"psa_exports_to_sanctioned_fra_dgt_mefids_entity",
"psa_exports_to_sanctioned_gbr_fcdo_entity",
"psa_exports_to_sanctioned_gbr_hmt_ofsi_entity",
@@ -441,6 +449,7 @@
"psa_owned_by_sanctioned_eu_dg_fisma_ec_entity",
"psa_owned_by_sanctioned_eu_ec_regulation_833_2014_entity",
"psa_owned_by_sanctioned_eu_ec_sanctions_map_entity",
+ "psa_owned_by_sanctioned_eu_sanctions_entity",
"psa_owned_by_sanctioned_fra_dgt_mefids_entity",
"psa_owned_by_sanctioned_gbr_fcdo_entity",
"psa_owned_by_sanctioned_gbr_hmt_ofsi_entity",
@@ -496,6 +505,7 @@
"psa_owner_of_sanctioned_eu_dg_fisma_ec_entity",
"psa_owner_of_sanctioned_eu_ec_regulation_833_2014_entity",
"psa_owner_of_sanctioned_eu_ec_sanctions_map_entity",
+ "psa_owner_of_sanctioned_eu_sanctions_entity",
"psa_owner_of_sanctioned_fra_dgt_mefids_entity",
"psa_owner_of_sanctioned_gbr_fcdo_entity",
"psa_owner_of_sanctioned_gbr_hmt_ofsi_entity",
@@ -537,6 +547,7 @@
"psa_sanctioned_eu_dg_fisma_ec",
"psa_sanctioned_eu_ec_regulation_833_2014",
"psa_sanctioned_eu_ec_sanctions_map",
+ "psa_sanctioned_eu_sanctions",
"psa_sanctioned_fra_dgt_mefids",
"psa_sanctioned_gbr_fcdo",
"psa_sanctioned_gbr_hmt_ofsi",
@@ -568,6 +579,7 @@
"psa_usa_bis_50_percent_rule",
"psa_usa_bis_denied_persons",
"psa_usa_bis_meu",
+ "psa_usa_bis_meu_50_percent_rule",
"psa_usa_bis_unverified",
"psa_usa_isn",
"psa_usa_section_1260h",
@@ -590,8 +602,10 @@
"sanctioned_che_seco",
"sanctioned_cze_mof",
"sanctioned_eu_dg_fisma_ec",
+ "sanctioned_eu_ec_regulation_269_2014",
"sanctioned_eu_ec_regulation_833_2014",
"sanctioned_eu_ec_sanctions_map",
+ "sanctioned_eu_sanctions",
"sanctioned_fra_dgt_mefids",
"sanctioned_gbr_fcdo",
"sanctioned_gbr_hmt_ofsi",
@@ -627,6 +641,7 @@
"usa_bis_50_percent_rule",
"usa_bis_denied_persons",
"usa_bis_meu",
+ "usa_bis_meu_50_percent_rule",
"usa_bis_unverified",
"usa_isn",
"usa_section_1260h",
diff --git a/src/sayari/generated_types/types/tag.py b/src/sayari/generated_types/types/tag.py
index 6cf8e7b7..428a03f2 100644
--- a/src/sayari/generated_types/types/tag.py
+++ b/src/sayari/generated_types/types/tag.py
@@ -9,6 +9,7 @@
"esg_score",
"export_controls",
"export_controls_bis_entity",
+ "financial_risk_score",
"forced_labor_xinjiang_contractors",
"former_soe",
"formerly_sanctioned",
diff --git a/src/sayari/generated_types/types/unit.py b/src/sayari/generated_types/types/unit.py
index 396c2d1e..231a70ea 100644
--- a/src/sayari/generated_types/types/unit.py
+++ b/src/sayari/generated_types/types/unit.py
@@ -2,4 +2,4 @@
import typing
-Unit = typing.Union[typing.Literal["kilogram", "metre", "unit"], typing.Any]
+Unit = typing.Union[typing.Literal["kilogram", "metre", "metres_squared", "unit"], typing.Any]
diff --git a/src/sayari/generated_types/types/weak_identifier_type.py b/src/sayari/generated_types/types/weak_identifier_type.py
index c92deb1d..efdfc676 100644
--- a/src/sayari/generated_types/types/weak_identifier_type.py
+++ b/src/sayari/generated_types/types/weak_identifier_type.py
@@ -28,6 +28,8 @@
"chn_contract_number",
"chn_customs_registration_code",
"chn_project_number",
+ "civ_aeo_code",
+ "cmr_shipment_declaration_number",
"cn_qcc_internal_id",
"cofi_code",
"col_bill_of_lading",
@@ -40,9 +42,11 @@
"deu_registernummer",
"dma_corporate_registry_entity_num",
"gbr_bankruptcy_case_num",
+ "gbr_charity_no",
"gbr_declaration_number",
"gbr_grant_info_number",
"geo_state_registration_number",
+ "gha_shipment_declaration_number",
"habw_id",
"hnd_tegucigalpa_notary",
"hun_opten_id",
@@ -60,13 +64,16 @@
"jpn_declaration_number",
"jpn_permit_no",
"kaz_shipment_declaration_number",
+ "ken_shipment_declaration_number",
"kgz_inn",
"kgz_okpo",
"khm_tin_number",
"kor_declaration_number",
"lbn_family_number",
"lbn_registration_number",
+ "lbr_tin",
"lca_corporate_registry_entity_num",
+ "lso_import_entry_number",
"lva_court_case_id",
"lva_person_id_masked",
"mac_raem_case_number",
@@ -82,9 +89,12 @@
"mex_tm_app_no",
"mex_tm_reg_no",
"mlr_reg_num",
+ "mwi_shipment_reg_no",
"mx_fme",
"mx_partial_rfc_person",
"mys_partial_national_identity_number",
+ "nam_shipment_assessment_no",
+ "nam_shipment_reg_no",
"nga_drivers",
"nga_nin",
"nga_registration_number",
@@ -96,6 +106,7 @@
"pan_folio",
"pan_ibc_ruc",
"partial_ven_cedula",
+ "per_shipment_control_id",
"pol_nip_number",
"pol_regon_number",
"prk_internal_trade_id",
@@ -114,15 +125,19 @@
"rus_contract_internal_id",
"rus_procurement_notice_number",
"sgp_partial_national_identity_number",
+ "slb_foreign_investor_id",
"south_africa_partial_id_number",
"svk_filing_number",
"tokyo_shoko_id",
+ "tur_declaration_number",
"tur_office_registration_number",
"tur_partial_mersis_number",
"tx_bexar_property_geo_id",
"tza_bill_of_lading",
"tza_crn_no",
+ "tza_tansad_number",
"ukr_edrpou",
+ "ukr_registration_document_number",
"ukr_shipment_declaration_number",
"unknown",
"unknown_bra_case_number",
@@ -165,6 +180,7 @@
"ven_colegiado_number",
"ven_manifiesto_number",
"ven_rnc_number",
+ "vnm_shipment_declaration_number",
"malformed mmr_prior_reg_no",
],
typing.Any,
diff --git a/src/sayari/negative_news/client.py b/src/sayari/negative_news/client.py
index 34611058..b4bc9d9a 100644
--- a/src/sayari/negative_news/client.py
+++ b/src/sayari/negative_news/client.py
@@ -49,7 +49,7 @@ def negative_news(
Risk category filter for targeted screening. Each topic represents a distinct risk domain (e.g., `environmental` for environmental violations, `financial` for financial misconduct).
until : typing.Optional[dt.date]
- Date cutoff for article inclusion in `YYYY-MM-DD` format. If provided, only articles published before this date will be included in results.
+ Date cutoff for article inclusion in `YYYY-MM-DD` format. If provided, only articles published after this date will be included in results.
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -70,7 +70,7 @@ def negative_news(
)
client.negative_news.negative_news(
name="Gazprom",
- topic="sanctions",
+ topic="sanctions_and_regulatory",
until=datetime.date.fromisoformat(
"2024-10-01",
),
@@ -178,7 +178,7 @@ async def negative_news(
Risk category filter for targeted screening. Each topic represents a distinct risk domain (e.g., `environmental` for environmental violations, `financial` for financial misconduct).
until : typing.Optional[dt.date]
- Date cutoff for article inclusion in `YYYY-MM-DD` format. If provided, only articles published before this date will be included in results.
+ Date cutoff for article inclusion in `YYYY-MM-DD` format. If provided, only articles published after this date will be included in results.
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -203,7 +203,7 @@ async def negative_news(
async def main() -> None:
await client.negative_news.negative_news(
name="Gazprom",
- topic="sanctions",
+ topic="sanctions_and_regulatory",
until=datetime.date.fromisoformat(
"2024-10-01",
),
diff --git a/src/sayari/negative_news/types/topics.py b/src/sayari/negative_news/types/topics.py
index 2d131562..4df08b18 100644
--- a/src/sayari/negative_news/types/topics.py
+++ b/src/sayari/negative_news/types/topics.py
@@ -4,20 +4,17 @@
Topics = typing.Union[
typing.Literal[
- "basic",
- "environmental",
- "social",
+ "overview",
+ "environmental_and_social",
"cybersecurity",
"disruption",
"criminal",
"reputational",
"financial",
- "regulatory",
+ "sanctions_and_regulatory",
"legal",
- "misconduct",
+ "political",
"terrorism",
- "sanctions",
- "all",
],
typing.Any,
]
diff --git a/src/sayari/project/__init__.py b/src/sayari/project/__init__.py
index b9acab6e..8570e7de 100644
--- a/src/sayari/project/__init__.py
+++ b/src/sayari/project/__init__.py
@@ -14,7 +14,6 @@
ProjectCounts,
ProjectEntitiesAggs,
ProjectEntitiesAggsDefinition,
- ProjectEntitiesFilter,
ProjectEntity,
ProjectEntityUpstream,
ProjectShareOnCreate,
@@ -45,7 +44,6 @@
"ProjectCounts",
"ProjectEntitiesAggs",
"ProjectEntitiesAggsDefinition",
- "ProjectEntitiesFilter",
"ProjectEntity",
"ProjectEntityUpstream",
"ProjectShareOnCreate",
diff --git a/src/sayari/project/types/__init__.py b/src/sayari/project/types/__init__.py
index 069aeaa3..51e53adf 100644
--- a/src/sayari/project/types/__init__.py
+++ b/src/sayari/project/types/__init__.py
@@ -13,7 +13,6 @@
from .project_counts import ProjectCounts
from .project_entities_aggs import ProjectEntitiesAggs
from .project_entities_aggs_definition import ProjectEntitiesAggsDefinition
-from .project_entities_filter import ProjectEntitiesFilter
from .project_entity import ProjectEntity
from .project_entity_upstream import ProjectEntityUpstream
from .project_share_on_create import ProjectShareOnCreate
@@ -43,7 +42,6 @@
"ProjectCounts",
"ProjectEntitiesAggs",
"ProjectEntitiesAggsDefinition",
- "ProjectEntitiesFilter",
"ProjectEntity",
"ProjectEntityUpstream",
"ProjectShareOnCreate",
diff --git a/src/sayari/project_entity/__init__.py b/src/sayari/project_entity/__init__.py
index add92aca..0e652ac8 100644
--- a/src/sayari/project_entity/__init__.py
+++ b/src/sayari/project_entity/__init__.py
@@ -7,26 +7,34 @@
AttributeValues,
AttributesResponse,
BusinessPurpose,
- CaseStatus,
CountType,
CreateResolvedProjectEntityRequest,
FacetBucket,
FacetsResponse,
+ FieldMatchQuality,
GroupedAttribute,
GroupedAttributeValue,
Location,
- MatchCount,
MatchProfileEnum,
- MatchStrengthEnum,
- MatchedAttributes,
ProductBucket,
ProductCount,
ProductMapping,
+ ProjectEntitiesCustomFieldFilter,
+ ProjectEntitiesExactFilter,
+ ProjectEntitiesFilter,
+ ProjectEntitiesFuzzyFilter,
ProjectEntitiesResponse,
ProjectEntityExistsResponseData,
ProjectEntityIdResponse,
+ ProjectEntityMatchExplanation,
ProjectEntityMatchResponse,
ProjectEntityResponse,
+ ProjectEntityRiskSummaryData,
+ ProjectEntityRiskSummaryFilters,
+ ProjectEntityRiskSummaryNetworkPath,
+ ProjectEntityRiskSummaryResponse,
+ ProjectEntityRiskSummaryResponseFilters,
+ ProjectEntityRiskSummaryRiskFactor,
ProjectEntitySupplyChainSummaryResponse,
ProjectEntitySupplyChainSummaryResponseData,
ProjectEntitySupplyChainUpstream,
@@ -36,6 +44,7 @@
ResolutionProfile,
RiskCategoriesSummary,
SaveProjectEntityBody,
+ ShareInformation,
SingleProjectEntityResponse,
SourceField,
SpecialFacetBucket,
@@ -57,26 +66,34 @@
"AttributeValues",
"AttributesResponse",
"BusinessPurpose",
- "CaseStatus",
"CountType",
"CreateResolvedProjectEntityRequest",
"FacetBucket",
"FacetsResponse",
+ "FieldMatchQuality",
"GroupedAttribute",
"GroupedAttributeValue",
"Location",
- "MatchCount",
"MatchProfileEnum",
- "MatchStrengthEnum",
- "MatchedAttributes",
"ProductBucket",
"ProductCount",
"ProductMapping",
+ "ProjectEntitiesCustomFieldFilter",
+ "ProjectEntitiesExactFilter",
+ "ProjectEntitiesFilter",
+ "ProjectEntitiesFuzzyFilter",
"ProjectEntitiesResponse",
"ProjectEntityExistsResponseData",
"ProjectEntityIdResponse",
+ "ProjectEntityMatchExplanation",
"ProjectEntityMatchResponse",
"ProjectEntityResponse",
+ "ProjectEntityRiskSummaryData",
+ "ProjectEntityRiskSummaryFilters",
+ "ProjectEntityRiskSummaryNetworkPath",
+ "ProjectEntityRiskSummaryResponse",
+ "ProjectEntityRiskSummaryResponseFilters",
+ "ProjectEntityRiskSummaryRiskFactor",
"ProjectEntitySupplyChainSummaryResponse",
"ProjectEntitySupplyChainSummaryResponseData",
"ProjectEntitySupplyChainUpstream",
@@ -86,6 +103,7 @@
"ResolutionProfile",
"RiskCategoriesSummary",
"SaveProjectEntityBody",
+ "ShareInformation",
"SingleProjectEntityResponse",
"SourceField",
"SpecialFacetBucket",
diff --git a/src/sayari/project_entity/client.py b/src/sayari/project_entity/client.py
index 83281508..dbb0f37b 100644
--- a/src/sayari/project_entity/client.py
+++ b/src/sayari/project_entity/client.py
@@ -22,17 +22,16 @@
from ..shared_errors.types.internal_server_error_response import InternalServerErrorResponse
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
-from .types.case_status import CaseStatus
-from .types.match_count import MatchCount
-from .types.match_strength_enum import MatchStrengthEnum
-from ..generated_types.types.risk import Risk
-from ..generated_types.types.risk_category import RiskCategory
+from .types.project_entities_filter import ProjectEntitiesFilter
from .types.project_entities_response import ProjectEntitiesResponse
from .types.resolution_attributes import ResolutionAttributes
from .types.project_entity_id_response import ProjectEntityIdResponse
from .types.save_project_entity_body import SaveProjectEntityBody
+from ..generated_types.types.risk import Risk
from ..generated_types.types.country import Country
from ..supply_chain.types.upstream_trade_traversal_response import UpstreamTradeTraversalResponse
+from .types.project_entity_risk_summary_filters import ProjectEntityRiskSummaryFilters
+from .types.project_entity_risk_summary_response import ProjectEntityRiskSummaryResponse
from .types.project_entity_supply_chain_summary_response import ProjectEntitySupplyChainSummaryResponse
from ..core.client_wrapper import AsyncClientWrapper
@@ -49,6 +48,7 @@ def create_project_entity(
project_id: str,
*,
request: CreateResolvedProjectEntityRequest,
+ enable_llm_clean: typing.Optional[bool] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> SingleProjectEntityResponse:
"""
@@ -60,6 +60,9 @@ def create_project_entity(
request : CreateResolvedProjectEntityRequest
+ enable_llm_clean : typing.Optional[bool]
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -90,6 +93,9 @@ def create_project_entity(
_response = self._client_wrapper.httpx_client.request(
f"v1/projects/{jsonable_encoder(project_id)}/entities/create",
method="POST",
+ params={
+ "enable_llm_clean": enable_llm_clean,
+ },
json=convert_and_respect_annotation_metadata(
object_=request, annotation=CreateResolvedProjectEntityRequest, direction="write"
),
@@ -174,94 +180,42 @@ def get_project_entities(
self,
project_id: str,
*,
- entity_id: typing.Optional[typing.Sequence[str]] = None,
- uploads: typing.Optional[typing.Sequence[str]] = None,
- case_status: typing.Optional[typing.Sequence[CaseStatus]] = None,
- tags: typing.Optional[typing.Sequence[str]] = None,
- match_count: typing.Optional[MatchCount] = None,
- match_strength: typing.Optional[typing.Sequence[MatchStrengthEnum]] = None,
- entity_types: typing.Optional[typing.Sequence[str]] = None,
- geo_facets: typing.Optional[bool] = None,
- exact_match: typing.Optional[bool] = None,
- hs_codes: typing.Optional[typing.Sequence[str]] = None,
- received_hs_codes: typing.Optional[typing.Sequence[str]] = None,
- shipped_hs_codes: typing.Optional[typing.Sequence[str]] = None,
- upstream_product: typing.Optional[typing.Sequence[str]] = None,
+ next: typing.Optional[str] = None,
+ prev: typing.Optional[str] = None,
limit: typing.Optional[int] = None,
- token: typing.Optional[str] = None,
- sort: typing.Optional[typing.Sequence[str]] = None,
- aggregations: typing.Optional[typing.Sequence[str]] = None,
- num_aggregation_buckets: typing.Optional[int] = None,
- risk: typing.Optional[typing.Sequence[Risk]] = None,
- risk_category: typing.Optional[typing.Sequence[RiskCategory]] = None,
+ filter: typing.Optional[ProjectEntitiesFilter] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> ProjectEntitiesResponse:
"""
Retrieves a list of entities for a specific project with pagination support.
- Parameters
- ----------
- project_id : str
-
- entity_id : typing.Optional[typing.Sequence[str]]
- Filter by entity IDs
-
- uploads : typing.Optional[typing.Sequence[str]]
- Filter by upload IDs
+ **Response Formats:**
+ - **JSON** (default): Returns structured data with nested objects
+ - **CSV**: Returns tabular data with dynamic columns for attributes and risk categories
- case_status : typing.Optional[typing.Sequence[CaseStatus]]
- Filter by case status
+ **CSV Format:**
+ The CSV response includes dynamic columns based on the data:
+ - `attribute_{field_name}`: Dynamic columns for each attribute field found in the data
+ - `risk_category_{category_id}`: Dynamic columns for each risk category found in the data
+ - Standard columns: project_id, project_entity_id, label, project_entity_url, upload_ids, strength, countries, tags, case_status, created_at, match_count, upstream_products, upstream_risk_factors, upstream_countries
- tags : typing.Optional[typing.Sequence[str]]
- Filter by tag IDs
+ Use the `Accept: text/csv` header to request CSV format.
- match_count : typing.Optional[MatchCount]
- Filter by match count
-
- match_strength : typing.Optional[typing.Sequence[MatchStrengthEnum]]
- Filter by match strength
-
- entity_types : typing.Optional[typing.Sequence[str]]
- Filter by entity types
-
- geo_facets : typing.Optional[bool]
- Include geo facets
-
- exact_match : typing.Optional[bool]
- Use exact matching
-
- hs_codes : typing.Optional[typing.Sequence[str]]
- Filter by HS codes
-
- received_hs_codes : typing.Optional[typing.Sequence[str]]
- Filter by received HS codes
+ Parameters
+ ----------
+ project_id : str
- shipped_hs_codes : typing.Optional[typing.Sequence[str]]
- Filter by shipped HS codes
+ next : typing.Optional[str]
+ The pagination token for the next page of projects.
- upstream_product : typing.Optional[typing.Sequence[str]]
- Filter by upstream product
+ prev : typing.Optional[str]
+ The pagination token for the previous page of projects.
limit : typing.Optional[int]
- Maximum number of results to return
-
- token : typing.Optional[str]
- Pagination token
+ Limit total values returned for projects. Defaults to 100. Max 100.
- sort : typing.Optional[typing.Sequence[str]]
- Sort fields
-
- aggregations : typing.Optional[typing.Sequence[str]]
- Fields to aggregate
-
- num_aggregation_buckets : typing.Optional[int]
- Number of aggregation buckets
-
- risk : typing.Optional[typing.Sequence[Risk]]
- List of risk factors to filter by
-
- risk_category : typing.Optional[typing.Sequence[RiskCategory]]
- List of risk categories to filter by. An entity matches if it has any risk factor belonging to one of the specified categories
+ filter : typing.Optional[ProjectEntitiesFilter]
+ Filter the project entities. Supports both dot notation (e.g., 'filter.attribute.name') and bracket notation (e.g., 'filter[attribute][name]') for nested field filtering.
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -286,26 +240,12 @@ def get_project_entities(
f"v1/projects/{jsonable_encoder(project_id)}/entities",
method="GET",
params={
- "entity_id": entity_id,
- "uploads": uploads,
- "case_status": case_status,
- "tags": tags,
- "match_count": match_count,
- "match_strength": match_strength,
- "entity_types": entity_types,
- "geo_facets": geo_facets,
- "exact_match": exact_match,
- "hs_codes": hs_codes,
- "received_hs_codes": received_hs_codes,
- "shipped_hs_codes": shipped_hs_codes,
- "upstream_product": upstream_product,
+ "next": next,
+ "prev": prev,
"limit": limit,
- "token": token,
- "sort": sort,
- "aggregations": aggregations,
- "num_aggregation_buckets": num_aggregation_buckets,
- "risk": risk,
- "risk_category": risk_category,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ProjectEntitiesFilter, direction="write"
+ ),
},
request_options=request_options,
)
@@ -384,20 +324,7 @@ def get_project_entities(
raise ApiError(status_code=_response.status_code, body=_response_json)
def get_project_entity(
- self,
- project_id: str,
- project_entity_id: str,
- *,
- entity_id: typing.Optional[typing.Sequence[str]] = None,
- uploads: typing.Optional[typing.Sequence[str]] = None,
- case_status: typing.Optional[typing.Sequence[CaseStatus]] = None,
- tags: typing.Optional[typing.Sequence[str]] = None,
- match_count: typing.Optional[MatchCount] = None,
- match_strength: typing.Optional[typing.Sequence[MatchStrengthEnum]] = None,
- entity_types: typing.Optional[typing.Sequence[str]] = None,
- risk: typing.Optional[typing.Sequence[Risk]] = None,
- risk_category: typing.Optional[typing.Sequence[RiskCategory]] = None,
- request_options: typing.Optional[RequestOptions] = None,
+ self, project_id: str, project_entity_id: str, *, request_options: typing.Optional[RequestOptions] = None
) -> SingleProjectEntityResponse:
"""
Retrieves a specific entity in a project.
@@ -408,33 +335,6 @@ def get_project_entity(
project_entity_id : str
- entity_id : typing.Optional[typing.Sequence[str]]
- Filter by entity IDs
-
- uploads : typing.Optional[typing.Sequence[str]]
- Filter by upload IDs
-
- case_status : typing.Optional[typing.Sequence[CaseStatus]]
- Filter by case status
-
- tags : typing.Optional[typing.Sequence[str]]
- Filter by tag IDs
-
- match_count : typing.Optional[MatchCount]
- Filter by match count
-
- match_strength : typing.Optional[typing.Sequence[MatchStrengthEnum]]
- Filter by match strength
-
- entity_types : typing.Optional[typing.Sequence[str]]
- Filter by entity types
-
- risk : typing.Optional[typing.Sequence[Risk]]
- List of risk factors to filter by
-
- risk_category : typing.Optional[typing.Sequence[RiskCategory]]
- List of risk categories to filter by. An entity matches if it has any risk factor belonging to one of the specified categories
-
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -458,17 +358,6 @@ def get_project_entity(
_response = self._client_wrapper.httpx_client.request(
f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}",
method="GET",
- params={
- "entity_id": entity_id,
- "uploads": uploads,
- "case_status": case_status,
- "tags": tags,
- "match_count": match_count,
- "match_strength": match_strength,
- "entity_types": entity_types,
- "risk": risk,
- "risk_category": risk_category,
- },
request_options=request_options,
)
try:
@@ -1225,6 +1114,141 @@ def project_entity_supply_chain(
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
+ def get_project_entity_risk_summary(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ *,
+ filter: ProjectEntityRiskSummaryFilters,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ProjectEntityRiskSummaryResponse:
+ """
+ Retrieves a risk summary for a specific project entity, including risk factors with network paths and risk intelligence data.
+
+ **Response includes:**
+ - Risk factors with their levels (elevated, high, critical)
+ - Network paths showing relationships between entities
+ - Risk intelligence scores and metadata
+ - Risk categories and source entity information
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ filter : ProjectEntityRiskSummaryFilters
+ Filter risk factors by risk factor IDs and risk categories
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ProjectEntityRiskSummaryResponse
+
+ Examples
+ --------
+ from sayari import Sayari
+ from sayari.project_entity import ProjectEntityRiskSummaryFilters
+
+ client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+ client.project_entity.get_project_entity_risk_summary(
+ project_id="YVB88Y",
+ project_entity_id="52z4Wa",
+ filter=ProjectEntityRiskSummaryFilters(
+ risk_factor=["sanctioned", "regulatory_action"],
+ risk_category=["sanctions", "export_controls"],
+ ),
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/risk_summary",
+ method="GET",
+ params={
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ProjectEntityRiskSummaryFilters, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ ProjectEntityRiskSummaryResponse,
+ parse_obj_as(
+ type_=ProjectEntityRiskSummaryResponse, # 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 project_entity_supply_chain_summary(
self,
project_id: str,
@@ -1415,6 +1439,7 @@ async def create_project_entity(
project_id: str,
*,
request: CreateResolvedProjectEntityRequest,
+ enable_llm_clean: typing.Optional[bool] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> SingleProjectEntityResponse:
"""
@@ -1426,6 +1451,9 @@ async def create_project_entity(
request : CreateResolvedProjectEntityRequest
+ enable_llm_clean : typing.Optional[bool]
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -1464,6 +1492,9 @@ async def main() -> None:
_response = await self._client_wrapper.httpx_client.request(
f"v1/projects/{jsonable_encoder(project_id)}/entities/create",
method="POST",
+ params={
+ "enable_llm_clean": enable_llm_clean,
+ },
json=convert_and_respect_annotation_metadata(
object_=request, annotation=CreateResolvedProjectEntityRequest, direction="write"
),
@@ -1548,94 +1579,42 @@ async def get_project_entities(
self,
project_id: str,
*,
- entity_id: typing.Optional[typing.Sequence[str]] = None,
- uploads: typing.Optional[typing.Sequence[str]] = None,
- case_status: typing.Optional[typing.Sequence[CaseStatus]] = None,
- tags: typing.Optional[typing.Sequence[str]] = None,
- match_count: typing.Optional[MatchCount] = None,
- match_strength: typing.Optional[typing.Sequence[MatchStrengthEnum]] = None,
- entity_types: typing.Optional[typing.Sequence[str]] = None,
- geo_facets: typing.Optional[bool] = None,
- exact_match: typing.Optional[bool] = None,
- hs_codes: typing.Optional[typing.Sequence[str]] = None,
- received_hs_codes: typing.Optional[typing.Sequence[str]] = None,
- shipped_hs_codes: typing.Optional[typing.Sequence[str]] = None,
- upstream_product: typing.Optional[typing.Sequence[str]] = None,
+ next: typing.Optional[str] = None,
+ prev: typing.Optional[str] = None,
limit: typing.Optional[int] = None,
- token: typing.Optional[str] = None,
- sort: typing.Optional[typing.Sequence[str]] = None,
- aggregations: typing.Optional[typing.Sequence[str]] = None,
- num_aggregation_buckets: typing.Optional[int] = None,
- risk: typing.Optional[typing.Sequence[Risk]] = None,
- risk_category: typing.Optional[typing.Sequence[RiskCategory]] = None,
+ filter: typing.Optional[ProjectEntitiesFilter] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> ProjectEntitiesResponse:
"""
Retrieves a list of entities for a specific project with pagination support.
- Parameters
- ----------
- project_id : str
-
- entity_id : typing.Optional[typing.Sequence[str]]
- Filter by entity IDs
-
- uploads : typing.Optional[typing.Sequence[str]]
- Filter by upload IDs
-
- case_status : typing.Optional[typing.Sequence[CaseStatus]]
- Filter by case status
-
- tags : typing.Optional[typing.Sequence[str]]
- Filter by tag IDs
-
- match_count : typing.Optional[MatchCount]
- Filter by match count
-
- match_strength : typing.Optional[typing.Sequence[MatchStrengthEnum]]
- Filter by match strength
-
- entity_types : typing.Optional[typing.Sequence[str]]
- Filter by entity types
+ **Response Formats:**
+ - **JSON** (default): Returns structured data with nested objects
+ - **CSV**: Returns tabular data with dynamic columns for attributes and risk categories
- geo_facets : typing.Optional[bool]
- Include geo facets
+ **CSV Format:**
+ The CSV response includes dynamic columns based on the data:
+ - `attribute_{field_name}`: Dynamic columns for each attribute field found in the data
+ - `risk_category_{category_id}`: Dynamic columns for each risk category found in the data
+ - Standard columns: project_id, project_entity_id, label, project_entity_url, upload_ids, strength, countries, tags, case_status, created_at, match_count, upstream_products, upstream_risk_factors, upstream_countries
- exact_match : typing.Optional[bool]
- Use exact matching
+ Use the `Accept: text/csv` header to request CSV format.
- hs_codes : typing.Optional[typing.Sequence[str]]
- Filter by HS codes
-
- received_hs_codes : typing.Optional[typing.Sequence[str]]
- Filter by received HS codes
+ Parameters
+ ----------
+ project_id : str
- shipped_hs_codes : typing.Optional[typing.Sequence[str]]
- Filter by shipped HS codes
+ next : typing.Optional[str]
+ The pagination token for the next page of projects.
- upstream_product : typing.Optional[typing.Sequence[str]]
- Filter by upstream product
+ prev : typing.Optional[str]
+ The pagination token for the previous page of projects.
limit : typing.Optional[int]
- Maximum number of results to return
-
- token : typing.Optional[str]
- Pagination token
-
- sort : typing.Optional[typing.Sequence[str]]
- Sort fields
-
- aggregations : typing.Optional[typing.Sequence[str]]
- Fields to aggregate
-
- num_aggregation_buckets : typing.Optional[int]
- Number of aggregation buckets
-
- risk : typing.Optional[typing.Sequence[Risk]]
- List of risk factors to filter by
+ Limit total values returned for projects. Defaults to 100. Max 100.
- risk_category : typing.Optional[typing.Sequence[RiskCategory]]
- List of risk categories to filter by. An entity matches if it has any risk factor belonging to one of the specified categories
+ filter : typing.Optional[ProjectEntitiesFilter]
+ Filter the project entities. Supports both dot notation (e.g., 'filter.attribute.name') and bracket notation (e.g., 'filter[attribute][name]') for nested field filtering.
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -1668,26 +1647,12 @@ async def main() -> None:
f"v1/projects/{jsonable_encoder(project_id)}/entities",
method="GET",
params={
- "entity_id": entity_id,
- "uploads": uploads,
- "case_status": case_status,
- "tags": tags,
- "match_count": match_count,
- "match_strength": match_strength,
- "entity_types": entity_types,
- "geo_facets": geo_facets,
- "exact_match": exact_match,
- "hs_codes": hs_codes,
- "received_hs_codes": received_hs_codes,
- "shipped_hs_codes": shipped_hs_codes,
- "upstream_product": upstream_product,
+ "next": next,
+ "prev": prev,
"limit": limit,
- "token": token,
- "sort": sort,
- "aggregations": aggregations,
- "num_aggregation_buckets": num_aggregation_buckets,
- "risk": risk,
- "risk_category": risk_category,
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ProjectEntitiesFilter, direction="write"
+ ),
},
request_options=request_options,
)
@@ -1766,20 +1731,7 @@ async def main() -> None:
raise ApiError(status_code=_response.status_code, body=_response_json)
async def get_project_entity(
- self,
- project_id: str,
- project_entity_id: str,
- *,
- entity_id: typing.Optional[typing.Sequence[str]] = None,
- uploads: typing.Optional[typing.Sequence[str]] = None,
- case_status: typing.Optional[typing.Sequence[CaseStatus]] = None,
- tags: typing.Optional[typing.Sequence[str]] = None,
- match_count: typing.Optional[MatchCount] = None,
- match_strength: typing.Optional[typing.Sequence[MatchStrengthEnum]] = None,
- entity_types: typing.Optional[typing.Sequence[str]] = None,
- risk: typing.Optional[typing.Sequence[Risk]] = None,
- risk_category: typing.Optional[typing.Sequence[RiskCategory]] = None,
- request_options: typing.Optional[RequestOptions] = None,
+ self, project_id: str, project_entity_id: str, *, request_options: typing.Optional[RequestOptions] = None
) -> SingleProjectEntityResponse:
"""
Retrieves a specific entity in a project.
@@ -1790,33 +1742,6 @@ async def get_project_entity(
project_entity_id : str
- entity_id : typing.Optional[typing.Sequence[str]]
- Filter by entity IDs
-
- uploads : typing.Optional[typing.Sequence[str]]
- Filter by upload IDs
-
- case_status : typing.Optional[typing.Sequence[CaseStatus]]
- Filter by case status
-
- tags : typing.Optional[typing.Sequence[str]]
- Filter by tag IDs
-
- match_count : typing.Optional[MatchCount]
- Filter by match count
-
- match_strength : typing.Optional[typing.Sequence[MatchStrengthEnum]]
- Filter by match strength
-
- entity_types : typing.Optional[typing.Sequence[str]]
- Filter by entity types
-
- risk : typing.Optional[typing.Sequence[Risk]]
- List of risk factors to filter by
-
- risk_category : typing.Optional[typing.Sequence[RiskCategory]]
- List of risk categories to filter by. An entity matches if it has any risk factor belonging to one of the specified categories
-
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -1848,17 +1773,6 @@ async def main() -> None:
_response = await self._client_wrapper.httpx_client.request(
f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}",
method="GET",
- params={
- "entity_id": entity_id,
- "uploads": uploads,
- "case_status": case_status,
- "tags": tags,
- "match_count": match_count,
- "match_strength": match_strength,
- "entity_types": entity_types,
- "risk": risk,
- "risk_category": risk_category,
- },
request_options=request_options,
)
try:
@@ -2655,6 +2569,149 @@ 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 get_project_entity_risk_summary(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ *,
+ filter: ProjectEntityRiskSummaryFilters,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> ProjectEntityRiskSummaryResponse:
+ """
+ Retrieves a risk summary for a specific project entity, including risk factors with network paths and risk intelligence data.
+
+ **Response includes:**
+ - Risk factors with their levels (elevated, high, critical)
+ - Network paths showing relationships between entities
+ - Risk intelligence scores and metadata
+ - Risk categories and source entity information
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ filter : ProjectEntityRiskSummaryFilters
+ Filter risk factors by risk factor IDs and risk categories
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ProjectEntityRiskSummaryResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from sayari import AsyncSayari
+ from sayari.project_entity import ProjectEntityRiskSummaryFilters
+
+ client = AsyncSayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+
+
+ async def main() -> None:
+ await client.project_entity.get_project_entity_risk_summary(
+ project_id="YVB88Y",
+ project_entity_id="52z4Wa",
+ filter=ProjectEntityRiskSummaryFilters(
+ risk_factor=["sanctioned", "regulatory_action"],
+ risk_category=["sanctions", "export_controls"],
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/risk_summary",
+ method="GET",
+ params={
+ "filter": convert_and_respect_annotation_metadata(
+ object_=filter, annotation=ProjectEntityRiskSummaryFilters, direction="write"
+ ),
+ },
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ ProjectEntityRiskSummaryResponse,
+ parse_obj_as(
+ type_=ProjectEntityRiskSummaryResponse, # 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 project_entity_supply_chain_summary(
self,
project_id: str,
diff --git a/src/sayari/project_entity/types/__init__.py b/src/sayari/project_entity/types/__init__.py
index 02a1fae0..436ffc08 100644
--- a/src/sayari/project_entity/types/__init__.py
+++ b/src/sayari/project_entity/types/__init__.py
@@ -6,26 +6,34 @@
from .attribute_values import AttributeValues
from .attributes_response import AttributesResponse
from .business_purpose import BusinessPurpose
-from .case_status import CaseStatus
from .count_type import CountType
from .create_resolved_project_entity_request import CreateResolvedProjectEntityRequest
from .facet_bucket import FacetBucket
from .facets_response import FacetsResponse
+from .field_match_quality import FieldMatchQuality
from .grouped_attribute import GroupedAttribute
from .grouped_attribute_value import GroupedAttributeValue
from .location import Location
-from .match_count import MatchCount
from .match_profile_enum import MatchProfileEnum
-from .match_strength_enum import MatchStrengthEnum
-from .matched_attributes import MatchedAttributes
from .product_bucket import ProductBucket
from .product_count import ProductCount
from .product_mapping import ProductMapping
+from .project_entities_custom_field_filter import ProjectEntitiesCustomFieldFilter
+from .project_entities_exact_filter import ProjectEntitiesExactFilter
+from .project_entities_filter import ProjectEntitiesFilter
+from .project_entities_fuzzy_filter import ProjectEntitiesFuzzyFilter
from .project_entities_response import ProjectEntitiesResponse
from .project_entity_exists_response_data import ProjectEntityExistsResponseData
from .project_entity_id_response import ProjectEntityIdResponse
+from .project_entity_match_explanation import ProjectEntityMatchExplanation
from .project_entity_match_response import ProjectEntityMatchResponse
from .project_entity_response import ProjectEntityResponse
+from .project_entity_risk_summary_data import ProjectEntityRiskSummaryData
+from .project_entity_risk_summary_filters import ProjectEntityRiskSummaryFilters
+from .project_entity_risk_summary_network_path import ProjectEntityRiskSummaryNetworkPath
+from .project_entity_risk_summary_response import ProjectEntityRiskSummaryResponse
+from .project_entity_risk_summary_response_filters import ProjectEntityRiskSummaryResponseFilters
+from .project_entity_risk_summary_risk_factor import ProjectEntityRiskSummaryRiskFactor
from .project_entity_supply_chain_summary_response import ProjectEntitySupplyChainSummaryResponse
from .project_entity_supply_chain_summary_response_data import ProjectEntitySupplyChainSummaryResponseData
from .project_entity_supply_chain_upstream import ProjectEntitySupplyChainUpstream
@@ -35,6 +43,7 @@
from .resolution_profile import ResolutionProfile
from .risk_categories_summary import RiskCategoriesSummary
from .save_project_entity_body import SaveProjectEntityBody
+from .share_information import ShareInformation
from .single_project_entity_response import SingleProjectEntityResponse
from .source_field import SourceField
from .special_facet_bucket import SpecialFacetBucket
@@ -55,26 +64,34 @@
"AttributeValues",
"AttributesResponse",
"BusinessPurpose",
- "CaseStatus",
"CountType",
"CreateResolvedProjectEntityRequest",
"FacetBucket",
"FacetsResponse",
+ "FieldMatchQuality",
"GroupedAttribute",
"GroupedAttributeValue",
"Location",
- "MatchCount",
"MatchProfileEnum",
- "MatchStrengthEnum",
- "MatchedAttributes",
"ProductBucket",
"ProductCount",
"ProductMapping",
+ "ProjectEntitiesCustomFieldFilter",
+ "ProjectEntitiesExactFilter",
+ "ProjectEntitiesFilter",
+ "ProjectEntitiesFuzzyFilter",
"ProjectEntitiesResponse",
"ProjectEntityExistsResponseData",
"ProjectEntityIdResponse",
+ "ProjectEntityMatchExplanation",
"ProjectEntityMatchResponse",
"ProjectEntityResponse",
+ "ProjectEntityRiskSummaryData",
+ "ProjectEntityRiskSummaryFilters",
+ "ProjectEntityRiskSummaryNetworkPath",
+ "ProjectEntityRiskSummaryResponse",
+ "ProjectEntityRiskSummaryResponseFilters",
+ "ProjectEntityRiskSummaryRiskFactor",
"ProjectEntitySupplyChainSummaryResponse",
"ProjectEntitySupplyChainSummaryResponseData",
"ProjectEntitySupplyChainUpstream",
@@ -84,6 +101,7 @@
"ResolutionProfile",
"RiskCategoriesSummary",
"SaveProjectEntityBody",
+ "ShareInformation",
"SingleProjectEntityResponse",
"SourceField",
"SpecialFacetBucket",
diff --git a/src/sayari/project_entity/types/attribute_type.py b/src/sayari/project_entity/types/attribute_type.py
index 990c6bc1..69b913ec 100644
--- a/src/sayari/project_entity/types/attribute_type.py
+++ b/src/sayari/project_entity/types/attribute_type.py
@@ -7,8 +7,8 @@
class AttributeType(UniversalBaseModel):
- type: str
- resolution: bool
+ field: str
+ match_resolution: bool
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/attribute_values.py b/src/sayari/project_entity/types/attribute_values.py
index 9c55120a..f979d8a8 100644
--- a/src/sayari/project_entity/types/attribute_values.py
+++ b/src/sayari/project_entity/types/attribute_values.py
@@ -7,7 +7,7 @@
class AttributeValues(UniversalBaseModel):
- resolve: bool
+ match_resolution: bool
values: typing.List[str]
if IS_PYDANTIC_V2:
diff --git a/src/sayari/project_entity/types/create_resolved_project_entity_request.py b/src/sayari/project_entity/types/create_resolved_project_entity_request.py
index b166ee5e..e0860fb6 100644
--- a/src/sayari/project_entity/types/create_resolved_project_entity_request.py
+++ b/src/sayari/project_entity/types/create_resolved_project_entity_request.py
@@ -6,8 +6,8 @@
from ...generated_types.types.country import Country
from ...generated_types.types.entities import Entities
from .resolution_profile import ResolutionProfile
-from ...core.pydantic_utilities import IS_PYDANTIC_V2
import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
class CreateResolvedProjectEntityRequest(UniversalBaseModel):
@@ -35,6 +35,10 @@ class CreateResolvedProjectEntityRequest(UniversalBaseModel):
city: typing.Optional[typing.List[str]] = None
state: typing.Optional[typing.List[str]] = None
profile: typing.Optional[ResolutionProfile] = None
+ enable_llm_clean: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+ """
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/field_match_quality.py b/src/sayari/project_entity/types/field_match_quality.py
new file mode 100644
index 00000000..e293538f
--- /dev/null
+++ b/src/sayari/project_entity/types/field_match_quality.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+FieldMatchQuality = typing.Union[typing.Literal["high", "medium", "low", "na"], typing.Any]
diff --git a/src/sayari/project_entity/types/project_entities_custom_field_filter.py b/src/sayari/project_entity/types/project_entities_custom_field_filter.py
new file mode 100644
index 00000000..d0ab1ec6
--- /dev/null
+++ b/src/sayari/project_entity/types/project_entities_custom_field_filter.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing_extensions
+import typing
+from ...base_types.types.custom_field_value import CustomFieldValue
+from ...core.serialization import FieldMetadata
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class ProjectEntitiesCustomFieldFilter(UniversalBaseModel):
+ custom_field_name: typing_extensions.Annotated[
+ typing.Optional[CustomFieldValue], FieldMetadata(alias="custom_{field name}")
+ ] = 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/project_entity/types/matched_attributes.py b/src/sayari/project_entity/types/project_entities_exact_filter.py
similarity index 61%
rename from src/sayari/project_entity/types/matched_attributes.py
rename to src/sayari/project_entity/types/project_entities_exact_filter.py
index 3a8210ed..281e1e1f 100644
--- a/src/sayari/project_entity/types/matched_attributes.py
+++ b/src/sayari/project_entity/types/project_entities_exact_filter.py
@@ -2,16 +2,15 @@
from ...core.pydantic_utilities import UniversalBaseModel
import typing
-from ...core.pydantic_utilities import IS_PYDANTIC_V2
import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
-class MatchedAttributes(UniversalBaseModel):
- name: typing.Optional[typing.List[str]] = None
- address: typing.Optional[typing.List[str]] = None
- contact: typing.Optional[typing.List[str]] = None
- country: typing.Optional[typing.List[str]] = None
- identifier: typing.Optional[typing.List[str]] = None
+class ProjectEntitiesExactFilter(UniversalBaseModel):
+ exact: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Filter with exact matching.
+ """
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_entities_filter.py b/src/sayari/project_entity/types/project_entities_filter.py
similarity index 67%
rename from src/sayari/project/types/project_entities_filter.py
rename to src/sayari/project_entity/types/project_entities_filter.py
index 5fd228a6..63028221 100644
--- a/src/sayari/project/types/project_entities_filter.py
+++ b/src/sayari/project_entity/types/project_entities_filter.py
@@ -4,44 +4,33 @@
import typing
from ...generated_types.types.risk import Risk
import pydantic
-from .upstream_tiers import UpstreamTiers
from ...generated_types.types.country import Country
import typing_extensions
from ...core.serialization import FieldMetadata
+from .project_entities_fuzzy_filter import ProjectEntitiesFuzzyFilter
+from .project_entities_exact_filter import ProjectEntitiesExactFilter
from ...generated_types.types.company_status import CompanyStatus
-from ...base_types.types.custom_field_value import CustomFieldValue
+from ...shared_types.types.case_status import CaseStatus
+from ...shared_types.types.match_strength_enum import MatchStrengthEnum
+from ...shared_types.types.match_count import MatchCount
+from .project_entities_custom_field_filter import ProjectEntitiesCustomFieldFilter
from ...core.pydantic_utilities import IS_PYDANTIC_V2
class ProjectEntitiesFilter(UniversalBaseModel):
- risk: typing.Optional[typing.List[Risk]] = pydantic.Field(default=None)
+ risk_factor: typing.Optional[typing.List[Risk]] = pydantic.Field(default=None)
"""
Filter by [risk factor](/sayari-library/ontology/risk-factors) ID.
"""
- upstream_risk: typing.Optional[typing.List[Risk]] = pydantic.Field(default=None)
- """
- Filter by upstream (supply chain) [risk factor](/sayari-library/ontology/risk-factors) ID.
- """
-
- upstream_risk_tiers: typing.Optional[typing.List[UpstreamTiers]] = pydantic.Field(default=None)
- """
- Filter by upstream (supply chain) tiers that has one or more risks
- """
-
- country: typing.Optional[typing.List[Country]] = pydantic.Field(default=None)
- """
- Filter by [country](/sayari-library/ontology/enumerated-types#country).
- """
-
- upstream_country: typing.Optional[typing.List[Country]] = pydantic.Field(default=None)
+ risk_category: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
"""
- This filter is deprecated. Filter by upstream (supply chain) [country](/sayari-library/ontology/enumerated-types#country).
+ Filter by risk factor `category`, e.g. `sanctions`. At least one risk factor from each provided category must be present.
"""
- upstream_country_tiers: typing.Optional[typing.List[UpstreamTiers]] = pydantic.Field(default=None)
+ upstream_product: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
"""
- This filter is deprecated. Filter by upstream (supply chain) tiers that has one or more countries
+ Filter by upstream (supply chain) product ID.
"""
shipment_country: typing.Optional[typing.List[Country]] = pydantic.Field(default=None)
@@ -84,66 +73,90 @@ class ProjectEntitiesFilter(UniversalBaseModel):
Filter by upstream (supply chain) [country](/sayari-library/ontology/enumerated-types#country) at tier 5.
"""
+ country: typing.Optional[typing.List[Country]] = pydantic.Field(default=None)
+ """
+ Filter by [country](/sayari-library/ontology/enumerated-types#country).
+ """
+
business_purpose: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
"""
Filter by HS code, HS code description, or business description.
"""
- label_fuzzy: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="label.fuzzy")] = (
- pydantic.Field(default=None)
- )
+ label: typing.Optional[ProjectEntitiesFuzzyFilter] = pydantic.Field(default=None)
"""
Filter by entity label with fuzzy matching.
"""
- city_fuzzy: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="city.fuzzy")] = (
- pydantic.Field(default=None)
- )
+ city: typing.Optional[ProjectEntitiesFuzzyFilter] = pydantic.Field(default=None)
"""
Filter by entity city with fuzzy matching.
"""
- state_fuzzy: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="state.fuzzy")] = (
- pydantic.Field(default=None)
- )
+ state: typing.Optional[ProjectEntitiesFuzzyFilter] = pydantic.Field(default=None)
"""
Filter by entity address state with fuzzy matching.
"""
- identifier_fuzzy: typing_extensions.Annotated[
- typing.Optional[typing.List[str]], FieldMetadata(alias="identifier.fuzzy")
- ] = pydantic.Field(default=None)
+ identifier: typing.Optional[ProjectEntitiesFuzzyFilter] = pydantic.Field(default=None)
"""
Filter by entity identifier attributes with fuzzy matching.
"""
- source_exact: typing_extensions.Annotated[
- typing.Optional[typing.List[str]], FieldMetadata(alias="source.exact")
- ] = pydantic.Field(default=None)
+ source: typing.Optional[ProjectEntitiesExactFilter] = pydantic.Field(default=None)
"""
Filter by entity source ID.
"""
- status_exact: typing_extensions.Annotated[
- typing.Optional[typing.List[CompanyStatus]], FieldMetadata(alias="status.exact")
- ] = pydantic.Field(default=None)
+ status: typing.Optional[typing.List[CompanyStatus]] = pydantic.Field(default=None)
"""
Filter by entity [company status](/sayari-library/ontology/enumerated-types#company-status).
"""
- risk_category: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ bounds: typing.Optional[str] = pydantic.Field(default=None)
"""
- Filter by risk factor `category`, e.g. `sanctions`. At least one risk factor from each provided category must be present.
+ Filter by a geographical bounding box. The value is a pipe-delimited set of four values representing the top, left, bottom, and right sides of the bounding box, in that order. The pipes should be URL-encoded as `%7C`. The top coordinate must greater than the bottom coordinate, and the left coordinate must be less than the right coordinate. A sample is `55.680357237879136|-71.53607290158526|41.10876347746233|-40.963927098414736`
"""
- bounds: typing.Optional[str] = pydantic.Field(default=None)
+ match_entity_id: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
"""
- Filter by a geographical bounding box. The value is a pipe-delimited set of four values representing the top, left, bottom, and right sides of the bounding box, in that order. The pipes should be URL-encoded as `%7C`. The top coordinate must greater than the bottom coordinate, and the left coordinate must be less than the right coordinate. A sample is `55.680357237879136|-71.53607290158526|41.10876347746233|-40.963927098414736`
+ Filter by match entity ID.
+ """
+
+ entity_type: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Filter by entity type.
+ """
+
+ tag: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Filter by tag ID.
+ """
+
+ upload: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Filter by upload ID.
"""
- custom_field_name: typing_extensions.Annotated[
- typing.Optional[CustomFieldValue], FieldMetadata(alias="custom_{field name}")
- ] = None
+ case_status: typing.Optional[typing.List[CaseStatus]] = pydantic.Field(default=None)
+ """
+ Filter by case status.
+ """
+
+ match_strength: typing.Optional[typing.List[MatchStrengthEnum]] = pydantic.Field(default=None)
+ """
+ Filter by match strength.
+ """
+
+ match_count: typing.Optional[MatchCount] = pydantic.Field(default=None)
+ """
+ Filter by match count.
+ """
+
+ attribute: typing.Optional[ProjectEntitiesCustomFieldFilter] = pydantic.Field(default=None)
+ """
+ Filter by custom field.
+ """
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/project_entities_fuzzy_filter.py b/src/sayari/project_entity/types/project_entities_fuzzy_filter.py
new file mode 100644
index 00000000..9b80c952
--- /dev/null
+++ b/src/sayari/project_entity/types/project_entities_fuzzy_filter.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 ProjectEntitiesFuzzyFilter(UniversalBaseModel):
+ fuzzy: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ """
+ Filter with fuzzy matching.
+ """
+
+ 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/project_entities_response.py b/src/sayari/project_entity/types/project_entities_response.py
index abbcc145..942590db 100644
--- a/src/sayari/project_entity/types/project_entities_response.py
+++ b/src/sayari/project_entity/types/project_entities_response.py
@@ -17,8 +17,8 @@ class ProjectEntitiesResponse(UniversalBaseModel):
Address,
AttributeValues,
BusinessPurpose,
- MatchedAttributes,
ProjectEntitiesResponse,
+ ProjectEntityMatchExplanation,
ProjectEntityMatchResponse,
ProjectEntityResponse,
ProjectRiskCategory,
@@ -40,19 +40,19 @@ class ProjectEntitiesResponse(UniversalBaseModel):
created_at="2025-04-22 22:54:00.913586+00",
attributes={
"name": AttributeValues(
- resolve=True,
+ match_resolution=True,
values=["VTB Bank"],
),
"country": AttributeValues(
- resolve=True,
+ match_resolution=True,
values=["RUS"],
),
"address": AttributeValues(
- resolve=True,
+ match_resolution=True,
values=["Moscow"],
),
"identifier": AttributeValues(
- resolve=True,
+ match_resolution=True,
values=["253400V1H6ART1UQ0N98"],
),
},
@@ -145,27 +145,40 @@ class ProjectEntitiesResponse(UniversalBaseModel):
sayari_entity_id="dy-rh2g0QtzUN_jC_e9S_A",
type="company",
label='ОТКРЫТОЕ АКЦИОНЕРНОЕ ОБЩЕСТВО "РОССИЙСКИЕ ЖЕЛЕЗНЫЕ ДОРОГИ"',
- matched_attributes=MatchedAttributes(
- name=[
- "БАНК ВТБ (ПАО)",
- "VTB BANK (PJSC)",
- "БАНК ВТБ (ПУБЛИЧНОЕ АКЦИОНЕРНОЕ ОБЩЕСТВО)",
- "VTB BANK (PUBLIC JOINT STOCK COMPANY)",
- "VTB Bank",
- ],
- address=[
- "109147 Moscow, st. Vorontsovskaya, 43 building 1",
- "119121 Moscow, st. Plyushchikha, 37.",
- "Vorontsovskaya Str., 43 Moscow 109044 RUSSIAN FEDERATION",
- "37 Plyushchikha ul., Moscow, 119121, Russia",
- "Bashnya Zapad, Kompleks Federatsiya, 12, nab. Presnenskaya, Moscow, 123317, Russia",
- ],
- country=["RUS"],
- identifier=[
- "253400V1H6ART1UQ0N98",
- "253400V1H6ART1UQ0N98",
- ],
- ),
+ match_explanation=[
+ ProjectEntityMatchExplanation(
+ field="name",
+ quality="high",
+ matches=[
+ "БАНК ВТБ (ПАО)",
+ "VTB BANK (PJSC)",
+ "БАНК ВТБ (ПУБЛИЧНОЕ АКЦИОНЕРНОЕ ОБЩЕСТВО)",
+ "VTB BANK (PUBLIC JOINT STOCK COMPANY)",
+ "VTB Bank",
+ ],
+ ),
+ ProjectEntityMatchExplanation(
+ field="address",
+ quality="medium",
+ matches=[
+ "109147 Moscow, st. Vorontsovskaya, 43 building 1",
+ "119121 Moscow, st. Plyushchikha, 37.",
+ "Vorontsovskaya Str., 43 Moscow 109044 RUSSIAN FEDERATION",
+ "37 Plyushchikha ul., Moscow, 119121, Russia",
+ "Bashnya Zapad, Kompleks Federatsiya, 12, nab. Presnenskaya, Moscow, 123317, Russia",
+ ],
+ ),
+ ProjectEntityMatchExplanation(
+ field="country",
+ quality="high",
+ matches=["RUS"],
+ ),
+ ProjectEntityMatchExplanation(
+ field="identifier",
+ quality="high",
+ matches=["253400V1H6ART1UQ0N98"],
+ ),
+ ],
countries=[
"USA",
"CYP",
diff --git a/src/sayari/project_entity/types/project_entity_match_explanation.py b/src/sayari/project_entity/types/project_entity_match_explanation.py
new file mode 100644
index 00000000..41bd9c15
--- /dev/null
+++ b/src/sayari/project_entity/types/project_entity_match_explanation.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+from .field_match_quality import FieldMatchQuality
+import pydantic
+import typing
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+
+
+class ProjectEntityMatchExplanation(UniversalBaseModel):
+ field: str
+ quality: FieldMatchQuality = pydantic.Field()
+ """
+ Quality of the match
+ """
+
+ description: typing.Optional[typing.List[str]] = None
+ matches: typing.Optional[typing.List[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/project_entity/types/project_entity_match_response.py b/src/sayari/project_entity/types/project_entity_match_response.py
index 2fab5108..904c9126 100644
--- a/src/sayari/project_entity/types/project_entity_match_response.py
+++ b/src/sayari/project_entity/types/project_entity_match_response.py
@@ -1,7 +1,6 @@
# This file was auto-generated by Fern from our API Definition.
from ...core.pydantic_utilities import UniversalBaseModel
-from .matched_attributes import MatchedAttributes
import typing
from .project_risk_category import ProjectRiskCategory
from .project_risk_factor import ProjectRiskFactor
@@ -10,6 +9,7 @@
from .source_field import SourceField
from .address import Address
from .match_profile_enum import MatchProfileEnum
+from .project_entity_match_explanation import ProjectEntityMatchExplanation
from ...core.pydantic_utilities import IS_PYDANTIC_V2
import pydantic
@@ -19,7 +19,6 @@ class ProjectEntityMatchResponse(UniversalBaseModel):
sayari_entity_id: str
type: str
label: str
- matched_attributes: MatchedAttributes
countries: typing.List[str]
risk_categories: typing.List[ProjectRiskCategory]
risk_factors: typing.List[ProjectRiskFactor]
@@ -32,6 +31,7 @@ class ProjectEntityMatchResponse(UniversalBaseModel):
updated_at: typing.Optional[str] = None
match_profile: typing.Optional[MatchProfileEnum] = None
deleted_at: typing.Optional[str] = None
+ match_explanation: typing.Optional[typing.List[ProjectEntityMatchExplanation]] = 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/project_entity_response.py b/src/sayari/project_entity/types/project_entity_response.py
index 11b7dcc5..dbd976cf 100644
--- a/src/sayari/project_entity/types/project_entity_response.py
+++ b/src/sayari/project_entity/types/project_entity_response.py
@@ -2,13 +2,13 @@
from ...core.pydantic_utilities import UniversalBaseModel
import typing
-from .match_strength_enum import MatchStrengthEnum
+from ...shared_types.types.match_strength_enum import MatchStrengthEnum
from .attribute_values import AttributeValues
from .project_risk_category import ProjectRiskCategory
from .project_risk_factor import ProjectRiskFactor
from .upstream_info import UpstreamInfo
from .tag_response import TagResponse
-from .case_status import CaseStatus
+from ...shared_types.types.case_status import CaseStatus
from .project_entity_match_response import ProjectEntityMatchResponse
from ...core.pydantic_utilities import IS_PYDANTIC_V2
import pydantic
diff --git a/src/sayari/project_entity/types/project_entity_risk_summary_data.py b/src/sayari/project_entity/types/project_entity_risk_summary_data.py
new file mode 100644
index 00000000..2ba1682a
--- /dev/null
+++ b/src/sayari/project_entity/types/project_entity_risk_summary_data.py
@@ -0,0 +1,22 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+from .project_entity_risk_summary_risk_factor import ProjectEntityRiskSummaryRiskFactor
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class ProjectEntityRiskSummaryData(UniversalBaseModel):
+ project_entity_id: str
+ project_id: str
+ risk_factors: typing.List[ProjectEntityRiskSummaryRiskFactor]
+
+ 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/source/types/source.py b/src/sayari/project_entity/types/project_entity_risk_summary_filters.py
similarity index 52%
rename from src/sayari/source/types/source.py
rename to src/sayari/project_entity/types/project_entity_risk_summary_filters.py
index 4fb5a822..bd143484 100644
--- a/src/sayari/source/types/source.py
+++ b/src/sayari/project_entity/types/project_entity_risk_summary_filters.py
@@ -1,34 +1,22 @@
# This file was auto-generated by Fern from our API Definition.
from ...core.pydantic_utilities import UniversalBaseModel
-import pydantic
-from ...generated_types.types.country import Country
import typing
+import pydantic
from ...core.pydantic_utilities import IS_PYDANTIC_V2
-class Source(UniversalBaseModel):
- id: str = pydantic.Field()
+class ProjectEntityRiskSummaryFilters(UniversalBaseModel):
+ risk_factor: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
"""
- The unique identifier of the source
+ Filter by risk factor IDs
"""
- label: str
- description: str
- country: Country = pydantic.Field()
+ risk_category: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
"""
- Source [country](/sayari-library/ontology/enumerated-types#country)
+ Filter by risk category IDs
"""
- region: str
- date_added: str
- source_type: str
- record_type: str
- structure: str
- source_url: typing.Optional[str] = None
- pep: bool
- watchlist: bool
-
if IS_PYDANTIC_V2:
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
else:
diff --git a/src/sayari/project_entity/types/project_entity_risk_summary_network_path.py b/src/sayari/project_entity/types/project_entity_risk_summary_network_path.py
new file mode 100644
index 00000000..74060767
--- /dev/null
+++ b/src/sayari/project_entity/types/project_entity_risk_summary_network_path.py
@@ -0,0 +1,28 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+from .share_information import ShareInformation
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class ProjectEntityRiskSummaryNetworkPath(UniversalBaseModel):
+ sayari_entity_id: str
+ sayari_entity_label: str
+ relationship_type: str
+ relationship_status: str
+ former: bool
+ first_observed: str
+ last_observed: str
+ start_date: typing.Optional[str] = None
+ shares: typing.Optional[ShareInformation] = 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/project_entity/types/project_entity_risk_summary_response.py b/src/sayari/project_entity/types/project_entity_risk_summary_response.py
new file mode 100644
index 00000000..f3632509
--- /dev/null
+++ b/src/sayari/project_entity/types/project_entity_risk_summary_response.py
@@ -0,0 +1,264 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+from .project_entity_risk_summary_data import ProjectEntityRiskSummaryData
+from .project_entity_risk_summary_response_filters import ProjectEntityRiskSummaryResponseFilters
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import typing
+import pydantic
+
+
+class ProjectEntityRiskSummaryResponse(UniversalBaseModel):
+ """
+ Examples
+ --------
+ from sayari.project_entity import (
+ ProjectEntityRiskSummaryData,
+ ProjectEntityRiskSummaryNetworkPath,
+ ProjectEntityRiskSummaryResponse,
+ ProjectEntityRiskSummaryResponseFilters,
+ ProjectEntityRiskSummaryRiskFactor,
+ ProjectRiskCategory,
+ ShareInformation,
+ )
+
+ ProjectEntityRiskSummaryResponse(
+ data=ProjectEntityRiskSummaryData(
+ project_entity_id="GleDrP",
+ project_id="8YMJNG",
+ risk_factors=[
+ ProjectEntityRiskSummaryRiskFactor(
+ id="imports_ilab_child_labor",
+ label="Imports Goods with ILAB Child Labor Risk",
+ value="true",
+ level="elevated",
+ source_entity_ids=["FFgmjk4bK6vDn25yMypciw"],
+ metadata=[
+ {
+ "traversal_path": [
+ "FFgmjk4bK6vDn25yMypciw|receiver_of|QB7r598_7sPrCNefvZrAyw"
+ ],
+ "origin_shipment_product": [
+ "640299",
+ "5705",
+ "62",
+ "5702",
+ "64",
+ "42",
+ ],
+ }
+ ],
+ risk_intelligence=[
+ {
+ "type": "financial_risk_score",
+ "score": 36,
+ "Label": "S&P RiskGauge Credit Risk",
+ }
+ ],
+ risk_categories=[
+ ProjectRiskCategory(
+ id="forced_labor",
+ label="Forced labor",
+ risk_factors=["imports_ilab_child_labor"],
+ )
+ ],
+ network_paths=[[]],
+ ),
+ ProjectEntityRiskSummaryRiskFactor(
+ id="forced_labor_xinjiang_origin_subtier",
+ label="Supplier Network with Xinjiang-Based Entity",
+ value=2,
+ level="elevated",
+ source_entity_ids=["FFgmjk4bK6vDn25yMypciw"],
+ metadata=[
+ {
+ "traversal_path": [
+ "FFgmjk4bK6vDn25yMypciw|receives_from|doWJaXqr57DBYPyHcF_BxQ|receives_from|A3YwnnynaDQnlinlbt-UlQ"
+ ]
+ }
+ ],
+ risk_intelligence=[
+ {
+ "type": "financial_risk_score",
+ "score": 36,
+ "Label": "S&P RiskGauge Credit Risk",
+ }
+ ],
+ risk_categories=[
+ ProjectRiskCategory(
+ id="forced_labor",
+ label="Forced labor",
+ risk_factors=["forced_labor_xinjiang_origin_subtier"],
+ )
+ ],
+ network_paths=[
+ [
+ ProjectEntityRiskSummaryNetworkPath(
+ sayari_entity_id="doWJaXqr57DBYPyHcF_BxQ",
+ sayari_entity_label="LIBERTY MILLS LIMITED",
+ relationship_type="receives_from",
+ relationship_status="active",
+ former=False,
+ first_observed="2024-03-08",
+ last_observed="2024-03-14",
+ start_date="2024-03-08",
+ shares=ShareInformation(),
+ ),
+ ProjectEntityRiskSummaryNetworkPath(
+ sayari_entity_id="A3YwnnynaDQnlinlbt-UlQ",
+ sayari_entity_label="XINXIANG CHEMICAL FIBRE CO., LTD",
+ relationship_type="receives_from",
+ relationship_status="active",
+ former=False,
+ first_observed="2024-03-11",
+ last_observed="2024-03-25",
+ start_date="2024-03-11",
+ shares=ShareInformation(),
+ ),
+ ]
+ ],
+ ),
+ ProjectEntityRiskSummaryRiskFactor(
+ id="forced_labor_sheffield_hallam_university_reports_origin_subtier",
+ label="Supplier Network with Entity from Sheffield Hallam University Forced Labor Reports",
+ value=2,
+ level="elevated",
+ source_entity_ids=["FFgmjk4bK6vDn25yMypciw"],
+ metadata=[
+ {
+ "traversal_path": [
+ "FFgmjk4bK6vDn25yMypciw|receives_from|hky4niXTOuJOZ3YJUHBvpw|receives_from|jcG2-gcTVXhH6J2UO7bASg"
+ ]
+ }
+ ],
+ risk_intelligence=[
+ {
+ "type": "financial_risk_score",
+ "score": 36,
+ "Label": "S&P RiskGauge Credit Risk",
+ }
+ ],
+ risk_categories=[
+ ProjectRiskCategory(
+ id="forced_labor",
+ label="Forced labor",
+ risk_factors=[
+ "forced_labor_sheffield_hallam_university_reports_origin_subtier"
+ ],
+ )
+ ],
+ network_paths=[
+ [
+ ProjectEntityRiskSummaryNetworkPath(
+ sayari_entity_id="hky4niXTOuJOZ3YJUHBvpw",
+ sayari_entity_label="KOHINOOR TEXTILE MILLS LIMITED",
+ relationship_type="receives_from",
+ relationship_status="active",
+ former=False,
+ first_observed="2023-09-27",
+ last_observed="2023-09-27",
+ start_date="2023-09-27",
+ shares=ShareInformation(),
+ ),
+ ProjectEntityRiskSummaryNetworkPath(
+ sayari_entity_id="jcG2-gcTVXhH6J2UO7bASg",
+ sayari_entity_label="WEIQIAO TEXTILE COMPANY LIMITED",
+ relationship_type="receives_from",
+ relationship_status="active",
+ former=False,
+ first_observed="2017-03-08",
+ last_observed="2025-04-21",
+ start_date="2017-03-08",
+ shares=ShareInformation(),
+ ),
+ ]
+ ],
+ ),
+ ProjectEntityRiskSummaryRiskFactor(
+ id="forced_labor_uflpa_origin_subtier",
+ label="Supplier Network with UFLPA Entity",
+ value=3,
+ level="elevated",
+ source_entity_ids=["FFgmjk4bK6vDn25yMypciw"],
+ metadata=[
+ {
+ "traversal_path": [
+ "FFgmjk4bK6vDn25yMypciw|receives_from|Lg1BHckRWGrKUT03LUy3iw|receives_from|rmgKmpNeQxhVNnrnemI2yQ|receives_from|CZAZypVNS-jkOGzpRpCXEw"
+ ]
+ }
+ ],
+ risk_intelligence=[
+ {
+ "type": "financial_risk_score",
+ "score": 36,
+ "Label": "S&P RiskGauge Credit Risk",
+ }
+ ],
+ risk_categories=[
+ ProjectRiskCategory(
+ id="forced_labor",
+ label="Forced labor",
+ risk_factors=["forced_labor_uflpa_origin_subtier"],
+ )
+ ],
+ network_paths=[
+ [
+ ProjectEntityRiskSummaryNetworkPath(
+ sayari_entity_id="Lg1BHckRWGrKUT03LUy3iw",
+ sayari_entity_label="KAMAL LIMITED",
+ relationship_type="receives_from",
+ relationship_status="active",
+ former=False,
+ first_observed="2024-04-29",
+ last_observed="2025-04-21",
+ start_date="2024-04-29",
+ shares=ShareInformation(),
+ ),
+ ProjectEntityRiskSummaryNetworkPath(
+ sayari_entity_id="rmgKmpNeQxhVNnrnemI2yQ",
+ sayari_entity_label="CôNG TY TRáCH NHIệM HữU HạN HYOSUNG ĐồNG NAI",
+ relationship_type="receives_from",
+ relationship_status="active",
+ former=False,
+ first_observed="2023-09-28",
+ last_observed="2025-04-13",
+ start_date="2023-09-28",
+ shares=ShareInformation(),
+ ),
+ ProjectEntityRiskSummaryNetworkPath(
+ sayari_entity_id="CZAZypVNS-jkOGzpRpCXEw",
+ sayari_entity_label="HANGZHOU UNION BIOTECHNOLOGY CO., LTD",
+ relationship_type="receives_from",
+ relationship_status="active",
+ former=False,
+ first_observed="2023-03-09",
+ last_observed="2025-02-27",
+ start_date="2023-03-09",
+ shares=ShareInformation(),
+ ),
+ ]
+ ],
+ ),
+ ],
+ ),
+ filters=ProjectEntityRiskSummaryResponseFilters(
+ risk_factor=[
+ "imports_ilab_child_labor",
+ "forced_labor_xinjiang_origin_subtier",
+ ],
+ risk_category=["forced_labor"],
+ ),
+ )
+ """
+
+ data: ProjectEntityRiskSummaryData
+ filters: ProjectEntityRiskSummaryResponseFilters
+
+ 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/project_entity_risk_summary_response_filters.py b/src/sayari/project_entity/types/project_entity_risk_summary_response_filters.py
new file mode 100644
index 00000000..8d443331
--- /dev/null
+++ b/src/sayari/project_entity/types/project_entity_risk_summary_response_filters.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class ProjectEntityRiskSummaryResponseFilters(UniversalBaseModel):
+ risk_factor: typing.Optional[typing.List[str]] = None
+ risk_category: typing.Optional[typing.List[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/project_entity/types/project_entity_risk_summary_risk_factor.py b/src/sayari/project_entity/types/project_entity_risk_summary_risk_factor.py
new file mode 100644
index 00000000..a3d577f8
--- /dev/null
+++ b/src/sayari/project_entity/types/project_entity_risk_summary_risk_factor.py
@@ -0,0 +1,31 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+from .string_or_number import StringOrNumber
+from ...shared_types.types.risk_level import RiskLevel
+import typing
+from .project_risk_category import ProjectRiskCategory
+from .project_entity_risk_summary_network_path import ProjectEntityRiskSummaryNetworkPath
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class ProjectEntityRiskSummaryRiskFactor(UniversalBaseModel):
+ id: str
+ label: str
+ value: StringOrNumber
+ level: RiskLevel
+ risk_categories: typing.List[ProjectRiskCategory]
+ source_entity_ids: typing.List[str]
+ network_paths: typing.List[typing.List[ProjectEntityRiskSummaryNetworkPath]]
+ metadata: typing.List[typing.Dict[str, typing.List[StringOrNumber]]]
+ risk_intelligence: typing.List[typing.Dict[str, StringOrNumber]]
+
+ 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/share_information.py b/src/sayari/project_entity/types/share_information.py
new file mode 100644
index 00000000..e1b93a3d
--- /dev/null
+++ b/src/sayari/project_entity/types/share_information.py
@@ -0,0 +1,21 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class ShareInformation(UniversalBaseModel):
+ percentage: typing.Optional[float] = None
+ num_shares: typing.Optional[int] = None
+ monetary_value: typing.Optional[int] = 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/project_entity/types/single_project_entity_response.py b/src/sayari/project_entity/types/single_project_entity_response.py
index f8319bb0..1f9373e5 100644
--- a/src/sayari/project_entity/types/single_project_entity_response.py
+++ b/src/sayari/project_entity/types/single_project_entity_response.py
@@ -15,7 +15,7 @@ class SingleProjectEntityResponse(UniversalBaseModel):
Address,
AttributeValues,
BusinessPurpose,
- MatchedAttributes,
+ ProjectEntityMatchExplanation,
ProjectEntityMatchResponse,
ProjectEntityResponse,
ProjectRiskCategory,
@@ -36,19 +36,19 @@ class SingleProjectEntityResponse(UniversalBaseModel):
created_at="2025-04-22 22:54:00.913586+00",
attributes={
"name": AttributeValues(
- resolve=True,
+ match_resolution=True,
values=["VTB Bank"],
),
"country": AttributeValues(
- resolve=True,
+ match_resolution=True,
values=["RUS"],
),
"address": AttributeValues(
- resolve=True,
+ match_resolution=True,
values=["Moscow"],
),
"identifier": AttributeValues(
- resolve=True,
+ match_resolution=True,
values=["253400V1H6ART1UQ0N98"],
),
},
@@ -141,27 +141,40 @@ class SingleProjectEntityResponse(UniversalBaseModel):
sayari_entity_id="dy-rh2g0QtzUN_jC_e9S_A",
type="company",
label='ОТКРЫТОЕ АКЦИОНЕРНОЕ ОБЩЕСТВО "РОССИЙСКИЕ ЖЕЛЕЗНЫЕ ДОРОГИ"',
- matched_attributes=MatchedAttributes(
- name=[
- "БАНК ВТБ (ПАО)",
- "VTB BANK (PJSC)",
- "БАНК ВТБ (ПУБЛИЧНОЕ АКЦИОНЕРНОЕ ОБЩЕСТВО)",
- "VTB BANK (PUBLIC JOINT STOCK COMPANY)",
- "VTB Bank",
- ],
- address=[
- "109147 Moscow, st. Vorontsovskaya, 43 building 1",
- "119121 Moscow, st. Plyushchikha, 37.",
- "Vorontsovskaya Str., 43 Moscow 109044 RUSSIAN FEDERATION",
- "37 Plyushchikha ul., Moscow, 119121, Russia",
- "Bashnya Zapad, Kompleks Federatsiya, 12, nab. Presnenskaya, Moscow, 123317, Russia",
- ],
- country=["RUS"],
- identifier=[
- "253400V1H6ART1UQ0N98",
- "253400V1H6ART1UQ0N98",
- ],
- ),
+ match_explanation=[
+ ProjectEntityMatchExplanation(
+ field="name",
+ quality="high",
+ matches=[
+ "БАНК ВТБ (ПАО)",
+ "VTB BANK (PJSC)",
+ "БАНК ВТБ (ПУБЛИЧНОЕ АКЦИОНЕРНОЕ ОБЩЕСТВО)",
+ "VTB BANK (PUBLIC JOINT STOCK COMPANY)",
+ "VTB Bank",
+ ],
+ ),
+ ProjectEntityMatchExplanation(
+ field="address",
+ quality="medium",
+ matches=[
+ "109147 Moscow, st. Vorontsovskaya, 43 building 1",
+ "119121 Moscow, st. Plyushchikha, 37.",
+ "Vorontsovskaya Str., 43 Moscow 109044 RUSSIAN FEDERATION",
+ "37 Plyushchikha ul., Moscow, 119121, Russia",
+ "Bashnya Zapad, Kompleks Federatsiya, 12, nab. Presnenskaya, Moscow, 123317, Russia",
+ ],
+ ),
+ ProjectEntityMatchExplanation(
+ field="country",
+ quality="high",
+ matches=["RUS"],
+ ),
+ ProjectEntityMatchExplanation(
+ field="identifier",
+ quality="high",
+ matches=["253400V1H6ART1UQ0N98"],
+ ),
+ ],
countries=[
"USA",
"CYP",
diff --git a/src/sayari/project_entity_attributes/__init__.py b/src/sayari/project_entity_attributes/__init__.py
index 7ba8a944..334bba5a 100644
--- a/src/sayari/project_entity_attributes/__init__.py
+++ b/src/sayari/project_entity_attributes/__init__.py
@@ -1,12 +1,24 @@
# This file was auto-generated by Fern from our API Definition.
from .types import (
+ CreateProjectEntityAttributeRequest,
+ CreateProjectEntityAttributeResponse,
+ CreateProjectEntityAttributeResponseData,
+ ProjectEntityAttribute,
+ ProjectEntityAttributeValue,
+ ProjectEntityAttributesResponse,
UpdateProjectEntityAttributeRequest,
UpdateProjectEntityAttributeResponse,
UpdateProjectEntityAttributeResponseData,
)
__all__ = [
+ "CreateProjectEntityAttributeRequest",
+ "CreateProjectEntityAttributeResponse",
+ "CreateProjectEntityAttributeResponseData",
+ "ProjectEntityAttribute",
+ "ProjectEntityAttributeValue",
+ "ProjectEntityAttributesResponse",
"UpdateProjectEntityAttributeRequest",
"UpdateProjectEntityAttributeResponse",
"UpdateProjectEntityAttributeResponseData",
diff --git a/src/sayari/project_entity_attributes/client.py b/src/sayari/project_entity_attributes/client.py
index 7bb2d741..855c2b9f 100644
--- a/src/sayari/project_entity_attributes/client.py
+++ b/src/sayari/project_entity_attributes/client.py
@@ -2,11 +2,9 @@
import typing
from ..core.client_wrapper import SyncClientWrapper
-from .types.update_project_entity_attribute_request import UpdateProjectEntityAttributeRequest
from ..core.request_options import RequestOptions
-from .types.update_project_entity_attribute_response import UpdateProjectEntityAttributeResponse
+from .types.project_entity_attributes_response import ProjectEntityAttributesResponse
from ..core.jsonable_encoder import jsonable_encoder
-from ..core.serialization import convert_and_respect_annotation_metadata
from ..core.pydantic_utilities import parse_obj_as
from ..shared_errors.errors.bad_request import BadRequest
from ..shared_errors.types.bad_request_response import BadRequestResponse
@@ -22,6 +20,11 @@
from ..shared_errors.types.internal_server_error_response import InternalServerErrorResponse
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
+from .types.create_project_entity_attribute_request import CreateProjectEntityAttributeRequest
+from .types.create_project_entity_attribute_response import CreateProjectEntityAttributeResponse
+from ..core.serialization import convert_and_respect_annotation_metadata
+from .types.update_project_entity_attribute_request import UpdateProjectEntityAttributeRequest
+from .types.update_project_entity_attribute_response import UpdateProjectEntityAttributeResponse
from ..core.client_wrapper import AsyncClientWrapper
# this is used as the default value for optional parameters
@@ -32,17 +35,127 @@ class ProjectEntityAttributesClient:
def __init__(self, *, client_wrapper: SyncClientWrapper):
self._client_wrapper = client_wrapper
- def update_project_entity_attribute(
+ def get_project_entity_attributes(
+ self, project_id: str, project_entity_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ProjectEntityAttributesResponse:
+ """
+ Retrieves all attributes for a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ProjectEntityAttributesResponse
+
+ Examples
+ --------
+ from sayari import Sayari
+
+ client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+ client.project_entity_attributes.get_project_entity_attributes(
+ project_id="V03eYM",
+ project_entity_id="BG72YW",
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ ProjectEntityAttributesResponse,
+ parse_obj_as(
+ type_=ProjectEntityAttributesResponse, # 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 create_project_entity_attribute(
self,
project_id: str,
project_entity_id: str,
- attribute_id: str,
*,
- request: UpdateProjectEntityAttributeRequest,
+ request: CreateProjectEntityAttributeRequest,
request_options: typing.Optional[RequestOptions] = None,
- ) -> UpdateProjectEntityAttributeResponse:
+ ) -> CreateProjectEntityAttributeResponse:
"""
- Updates a specific attribute for a project entity.
+ Creates a new attribute for a project entity.
Parameters
----------
@@ -50,42 +163,39 @@ def update_project_entity_attribute(
project_entity_id : str
- attribute_id : str
-
- request : UpdateProjectEntityAttributeRequest
+ request : CreateProjectEntityAttributeRequest
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
Returns
-------
- UpdateProjectEntityAttributeResponse
+ CreateProjectEntityAttributeResponse
Examples
--------
from sayari import Sayari
- from sayari.project_entity_attributes import UpdateProjectEntityAttributeRequest
+ from sayari.project_entity_attributes import CreateProjectEntityAttributeRequest
client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
- client.project_entity_attributes.update_project_entity_attribute(
+ client.project_entity_attributes.create_project_entity_attribute(
project_id="V03eYM",
project_entity_id="BG72YW",
- attribute_id="xG8wYP",
- request=UpdateProjectEntityAttributeRequest(
- field="name",
- value="updated name",
- match_resolution=True,
+ request=CreateProjectEntityAttributeRequest(
+ field="custom_phone",
+ value="+1-555-123-4567",
+ match_resolution=False,
),
)
"""
_response = self._client_wrapper.httpx_client.request(
- f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes/{jsonable_encoder(attribute_id)}",
- method="PUT",
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes",
+ method="POST",
json=convert_and_respect_annotation_metadata(
- object_=request, annotation=UpdateProjectEntityAttributeRequest, direction="write"
+ object_=request, annotation=CreateProjectEntityAttributeRequest, direction="write"
),
request_options=request_options,
omit=OMIT,
@@ -93,9 +203,9 @@ def update_project_entity_attribute(
try:
if 200 <= _response.status_code < 300:
return typing.cast(
- UpdateProjectEntityAttributeResponse,
+ CreateProjectEntityAttributeResponse,
parse_obj_as(
- type_=UpdateProjectEntityAttributeResponse, # type: ignore
+ type_=CreateProjectEntityAttributeResponse, # type: ignore
object_=_response.json(),
),
)
@@ -164,12 +274,7 @@ def update_project_entity_attribute(
raise ApiError(status_code=_response.status_code, body=_response.text)
raise ApiError(status_code=_response.status_code, body=_response_json)
-
-class AsyncProjectEntityAttributesClient:
- def __init__(self, *, client_wrapper: AsyncClientWrapper):
- self._client_wrapper = client_wrapper
-
- async def update_project_entity_attribute(
+ def update_project_entity_attribute(
self,
project_id: str,
project_entity_id: str,
@@ -200,33 +305,25 @@ async def update_project_entity_attribute(
Examples
--------
- import asyncio
-
- from sayari import AsyncSayari
+ from sayari import Sayari
from sayari.project_entity_attributes import UpdateProjectEntityAttributeRequest
- client = AsyncSayari(
+ client = Sayari(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
)
-
-
- async def main() -> None:
- await client.project_entity_attributes.update_project_entity_attribute(
- project_id="V03eYM",
- project_entity_id="BG72YW",
- attribute_id="xG8wYP",
- request=UpdateProjectEntityAttributeRequest(
- field="name",
- value="updated name",
- match_resolution=True,
- ),
- )
-
-
- asyncio.run(main())
+ client.project_entity_attributes.update_project_entity_attribute(
+ project_id="V03eYM",
+ project_entity_id="BG72YW",
+ attribute_id="xG8wYP",
+ request=UpdateProjectEntityAttributeRequest(
+ field="name",
+ value="updated name",
+ match_resolution=True,
+ ),
+ )
"""
- _response = await self._client_wrapper.httpx_client.request(
+ _response = self._client_wrapper.httpx_client.request(
f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes/{jsonable_encoder(attribute_id)}",
method="PUT",
json=convert_and_respect_annotation_metadata(
@@ -308,3 +405,637 @@ async def main() -> None:
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_attribute(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ attribute_id: str,
+ *,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> None:
+ """
+ Deletes a specific attribute for a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ attribute_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ from sayari import Sayari
+
+ client = Sayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+ client.project_entity_attributes.delete_project_entity_attribute(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ attribute_id="attribute_id",
+ )
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes/{jsonable_encoder(attribute_id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return
+ 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)
+
+
+class AsyncProjectEntityAttributesClient:
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
+ self._client_wrapper = client_wrapper
+
+ async def get_project_entity_attributes(
+ self, project_id: str, project_entity_id: str, *, request_options: typing.Optional[RequestOptions] = None
+ ) -> ProjectEntityAttributesResponse:
+ """
+ Retrieves all attributes for a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ ProjectEntityAttributesResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from sayari import AsyncSayari
+
+ client = AsyncSayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+
+
+ async def main() -> None:
+ await client.project_entity_attributes.get_project_entity_attributes(
+ project_id="V03eYM",
+ project_entity_id="BG72YW",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes",
+ method="GET",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ ProjectEntityAttributesResponse,
+ parse_obj_as(
+ type_=ProjectEntityAttributesResponse, # 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 create_project_entity_attribute(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ *,
+ request: CreateProjectEntityAttributeRequest,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> CreateProjectEntityAttributeResponse:
+ """
+ Creates a new attribute for a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ request : CreateProjectEntityAttributeRequest
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ CreateProjectEntityAttributeResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from sayari import AsyncSayari
+ from sayari.project_entity_attributes import CreateProjectEntityAttributeRequest
+
+ client = AsyncSayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+
+
+ async def main() -> None:
+ await client.project_entity_attributes.create_project_entity_attribute(
+ project_id="V03eYM",
+ project_entity_id="BG72YW",
+ request=CreateProjectEntityAttributeRequest(
+ field="custom_phone",
+ value="+1-555-123-4567",
+ match_resolution=False,
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes",
+ method="POST",
+ json=convert_and_respect_annotation_metadata(
+ object_=request, annotation=CreateProjectEntityAttributeRequest, direction="write"
+ ),
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ CreateProjectEntityAttributeResponse,
+ parse_obj_as(
+ type_=CreateProjectEntityAttributeResponse, # 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 update_project_entity_attribute(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ attribute_id: str,
+ *,
+ request: UpdateProjectEntityAttributeRequest,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateProjectEntityAttributeResponse:
+ """
+ Updates a specific attribute for a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ attribute_id : str
+
+ request : UpdateProjectEntityAttributeRequest
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateProjectEntityAttributeResponse
+
+ Examples
+ --------
+ import asyncio
+
+ from sayari import AsyncSayari
+ from sayari.project_entity_attributes import UpdateProjectEntityAttributeRequest
+
+ client = AsyncSayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+
+
+ async def main() -> None:
+ await client.project_entity_attributes.update_project_entity_attribute(
+ project_id="V03eYM",
+ project_entity_id="BG72YW",
+ attribute_id="xG8wYP",
+ request=UpdateProjectEntityAttributeRequest(
+ field="name",
+ value="updated name",
+ match_resolution=True,
+ ),
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes/{jsonable_encoder(attribute_id)}",
+ method="PUT",
+ json=convert_and_respect_annotation_metadata(
+ object_=request, annotation=UpdateProjectEntityAttributeRequest, direction="write"
+ ),
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return typing.cast(
+ UpdateProjectEntityAttributeResponse,
+ parse_obj_as(
+ type_=UpdateProjectEntityAttributeResponse, # 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_attribute(
+ self,
+ project_id: str,
+ project_entity_id: str,
+ attribute_id: str,
+ *,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> None:
+ """
+ Deletes a specific attribute for a project entity.
+
+ Parameters
+ ----------
+ project_id : str
+
+ project_entity_id : str
+
+ attribute_id : str
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ None
+
+ Examples
+ --------
+ import asyncio
+
+ from sayari import AsyncSayari
+
+ client = AsyncSayari(
+ client_id="YOUR_CLIENT_ID",
+ client_secret="YOUR_CLIENT_SECRET",
+ )
+
+
+ async def main() -> None:
+ await client.project_entity_attributes.delete_project_entity_attribute(
+ project_id="project_id",
+ project_entity_id="project_entity_id",
+ attribute_id="attribute_id",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"v1/projects/{jsonable_encoder(project_id)}/entities/{jsonable_encoder(project_entity_id)}/attributes/{jsonable_encoder(attribute_id)}",
+ method="DELETE",
+ request_options=request_options,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ return
+ 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)
diff --git a/src/sayari/project_entity_attributes/types/__init__.py b/src/sayari/project_entity_attributes/types/__init__.py
index d9b20917..a0329b1c 100644
--- a/src/sayari/project_entity_attributes/types/__init__.py
+++ b/src/sayari/project_entity_attributes/types/__init__.py
@@ -1,10 +1,22 @@
# This file was auto-generated by Fern from our API Definition.
+from .create_project_entity_attribute_request import CreateProjectEntityAttributeRequest
+from .create_project_entity_attribute_response import CreateProjectEntityAttributeResponse
+from .create_project_entity_attribute_response_data import CreateProjectEntityAttributeResponseData
+from .project_entity_attribute import ProjectEntityAttribute
+from .project_entity_attribute_value import ProjectEntityAttributeValue
+from .project_entity_attributes_response import ProjectEntityAttributesResponse
from .update_project_entity_attribute_request import UpdateProjectEntityAttributeRequest
from .update_project_entity_attribute_response import UpdateProjectEntityAttributeResponse
from .update_project_entity_attribute_response_data import UpdateProjectEntityAttributeResponseData
__all__ = [
+ "CreateProjectEntityAttributeRequest",
+ "CreateProjectEntityAttributeResponse",
+ "CreateProjectEntityAttributeResponseData",
+ "ProjectEntityAttribute",
+ "ProjectEntityAttributeValue",
+ "ProjectEntityAttributesResponse",
"UpdateProjectEntityAttributeRequest",
"UpdateProjectEntityAttributeResponse",
"UpdateProjectEntityAttributeResponseData",
diff --git a/src/sayari/project_entity_attributes/types/create_project_entity_attribute_request.py b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_request.py
new file mode 100644
index 00000000..9b03897c
--- /dev/null
+++ b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_request.py
@@ -0,0 +1,33 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import typing
+import pydantic
+
+
+class CreateProjectEntityAttributeRequest(UniversalBaseModel):
+ """
+ Examples
+ --------
+ from sayari.project_entity_attributes import CreateProjectEntityAttributeRequest
+
+ CreateProjectEntityAttributeRequest(
+ field="custom_phone",
+ value="+1-555-123-4567",
+ match_resolution=False,
+ )
+ """
+
+ field: str
+ value: str
+ match_resolution: bool
+
+ 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_attributes/types/create_project_entity_attribute_response.py b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_response.py
new file mode 100644
index 00000000..2b0b4445
--- /dev/null
+++ b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_response.py
@@ -0,0 +1,38 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+from .create_project_entity_attribute_response_data import CreateProjectEntityAttributeResponseData
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import typing
+import pydantic
+
+
+class CreateProjectEntityAttributeResponse(UniversalBaseModel):
+ """
+ Examples
+ --------
+ from sayari.project_entity_attributes import (
+ CreateProjectEntityAttributeResponse,
+ CreateProjectEntityAttributeResponseData,
+ )
+
+ CreateProjectEntityAttributeResponse(
+ data=CreateProjectEntityAttributeResponseData(
+ id="nK9mP2",
+ field="custom_phone",
+ value="+1-555-123-4567",
+ match_resolution=False,
+ ),
+ )
+ """
+
+ data: CreateProjectEntityAttributeResponseData
+
+ 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_attributes/types/create_project_entity_attribute_response_data.py b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_response_data.py
new file mode 100644
index 00000000..ef60e44b
--- /dev/null
+++ b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_response_data.py
@@ -0,0 +1,22 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import typing
+import pydantic
+
+
+class CreateProjectEntityAttributeResponseData(UniversalBaseModel):
+ id: str
+ field: str
+ value: str
+ match_resolution: bool
+
+ 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_attributes/types/project_entity_attribute.py b/src/sayari/project_entity_attributes/types/project_entity_attribute.py
new file mode 100644
index 00000000..8ff11b38
--- /dev/null
+++ b/src/sayari/project_entity_attributes/types/project_entity_attribute.py
@@ -0,0 +1,22 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+from .project_entity_attribute_value import ProjectEntityAttributeValue
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class ProjectEntityAttribute(UniversalBaseModel):
+ field: str
+ match_resolution: bool
+ values: typing.List[ProjectEntityAttributeValue]
+
+ 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_attributes/types/project_entity_attribute_value.py b/src/sayari/project_entity_attributes/types/project_entity_attribute_value.py
new file mode 100644
index 00000000..f04be680
--- /dev/null
+++ b/src/sayari/project_entity_attributes/types/project_entity_attribute_value.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import typing
+import pydantic
+
+
+class ProjectEntityAttributeValue(UniversalBaseModel):
+ id: int
+ value: str
+
+ 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_attributes/types/project_entity_attributes_response.py b/src/sayari/project_entity_attributes/types/project_entity_attributes_response.py
new file mode 100644
index 00000000..a903d91e
--- /dev/null
+++ b/src/sayari/project_entity_attributes/types/project_entity_attributes_response.py
@@ -0,0 +1,63 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+from .project_entity_attribute import ProjectEntityAttribute
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class ProjectEntityAttributesResponse(UniversalBaseModel):
+ """
+ Examples
+ --------
+ from sayari.project_entity_attributes import (
+ ProjectEntityAttribute,
+ ProjectEntityAttributesResponse,
+ ProjectEntityAttributeValue,
+ )
+
+ ProjectEntityAttributesResponse(
+ data=[
+ ProjectEntityAttribute(
+ field="name",
+ match_resolution=True,
+ values=[
+ ProjectEntityAttributeValue(
+ id=1,
+ value="Example Company",
+ ),
+ ProjectEntityAttributeValue(
+ id=2,
+ value="Updated Company Name",
+ ),
+ ],
+ ),
+ ProjectEntityAttribute(
+ field="custom_address",
+ match_resolution=False,
+ values=[
+ ProjectEntityAttributeValue(
+ id=3,
+ value="123 Main Street",
+ ),
+ ProjectEntityAttributeValue(
+ id=4,
+ value="456 Oak Avenue",
+ ),
+ ],
+ ),
+ ],
+ )
+ """
+
+ data: typing.List[ProjectEntityAttribute]
+
+ 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/resolution/client.py b/src/sayari/resolution/client.py
index b5a75aca..5c8b6acf 100644
--- a/src/sayari/resolution/client.py
+++ b/src/sayari/resolution/client.py
@@ -61,6 +61,7 @@ def resolution(
cutoff_threshold: typing.Optional[int] = None,
candidate_pool_size: typing.Optional[int] = None,
skip_post_process: typing.Optional[bool] = None,
+ enable_llm_clean: typing.Optional[bool] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> ResolutionResponse:
"""
@@ -125,6 +126,9 @@ def resolution(
skip_post_process : typing.Optional[bool]
Bypasses the post-processing setps and re-ranking. Useful for debugging. By default set to false, set to true to enable.
+ enable_llm_clean : typing.Optional[bool]
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -169,6 +173,7 @@ def resolution(
"cutoff_threshold": cutoff_threshold,
"candidate_pool_size": candidate_pool_size,
"skip_post_process": skip_post_process,
+ "enable_llm_clean": enable_llm_clean,
},
request_options=request_options,
)
@@ -252,6 +257,7 @@ def resolution_post(
request: ResolutionBody,
limit: typing.Optional[int] = None,
offset: typing.Optional[int] = None,
+ enable_llm_clean: typing.Optional[bool] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> ResolutionResponse:
"""
@@ -267,6 +273,9 @@ def resolution_post(
offset : typing.Optional[int]
Number of results to skip before returning response. Defaults to 0.
+ enable_llm_clean : typing.Optional[bool]
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -298,6 +307,7 @@ def resolution_post(
params={
"limit": limit,
"offset": offset,
+ "enable_llm_clean": enable_llm_clean,
},
json=convert_and_respect_annotation_metadata(object_=request, annotation=ResolutionBody, direction="write"),
request_options=request_options,
@@ -663,6 +673,7 @@ async def resolution(
cutoff_threshold: typing.Optional[int] = None,
candidate_pool_size: typing.Optional[int] = None,
skip_post_process: typing.Optional[bool] = None,
+ enable_llm_clean: typing.Optional[bool] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> ResolutionResponse:
"""
@@ -727,6 +738,9 @@ async def resolution(
skip_post_process : typing.Optional[bool]
Bypasses the post-processing setps and re-ranking. Useful for debugging. By default set to false, set to true to enable.
+ enable_llm_clean : typing.Optional[bool]
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -779,6 +793,7 @@ async def main() -> None:
"cutoff_threshold": cutoff_threshold,
"candidate_pool_size": candidate_pool_size,
"skip_post_process": skip_post_process,
+ "enable_llm_clean": enable_llm_clean,
},
request_options=request_options,
)
@@ -862,6 +877,7 @@ async def resolution_post(
request: ResolutionBody,
limit: typing.Optional[int] = None,
offset: typing.Optional[int] = None,
+ enable_llm_clean: typing.Optional[bool] = None,
request_options: typing.Optional[RequestOptions] = None,
) -> ResolutionResponse:
"""
@@ -877,6 +893,9 @@ async def resolution_post(
offset : typing.Optional[int]
Number of results to skip before returning response. Defaults to 0.
+ enable_llm_clean : typing.Optional[bool]
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+
request_options : typing.Optional[RequestOptions]
Request-specific configuration.
@@ -916,6 +935,7 @@ async def main() -> None:
params={
"limit": limit,
"offset": offset,
+ "enable_llm_clean": enable_llm_clean,
},
json=convert_and_respect_annotation_metadata(object_=request, annotation=ResolutionBody, direction="write"),
request_options=request_options,
diff --git a/src/sayari/resolution/types/resolution_body.py b/src/sayari/resolution/types/resolution_body.py
index 1eb74796..28065dc8 100644
--- a/src/sayari/resolution/types/resolution_body.py
+++ b/src/sayari/resolution/types/resolution_body.py
@@ -101,6 +101,11 @@ class ResolutionBody(UniversalBaseModel):
Bypasses the post-processing setps and re-ranking. Useful for debugging. By default set to false, set to true to enable.
"""
+ enable_llm_clean: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+ """
+
if IS_PYDANTIC_V2:
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
else:
diff --git a/src/sayari/resolution/types/resolution_upload_body.py b/src/sayari/resolution/types/resolution_upload_body.py
index ef902bed..0c926c1f 100644
--- a/src/sayari/resolution/types/resolution_upload_body.py
+++ b/src/sayari/resolution/types/resolution_upload_body.py
@@ -2,13 +2,18 @@
from ...core.pydantic_utilities import UniversalBaseModel
import typing
+import pydantic
from .resolution_body import ResolutionBody
from ...core.pydantic_utilities import IS_PYDANTIC_V2
-import pydantic
class ResolutionUploadBody(UniversalBaseModel):
filename: str
+ enable_llm_clean: typing.Optional[bool] = pydantic.Field(default=None)
+ """
+ Whether to enable LLM-based data cleaning to remove noise and standardize entity attributes. Defaults to true if not supplied. Set to false to disable LLM cleaning.
+ """
+
data: typing.List[ResolutionBody]
if IS_PYDANTIC_V2:
diff --git a/src/sayari/shared_errors/__init__.py b/src/sayari/shared_errors/__init__.py
index 310de7ba..ca889f62 100644
--- a/src/sayari/shared_errors/__init__.py
+++ b/src/sayari/shared_errors/__init__.py
@@ -10,6 +10,7 @@
NotFoundResponse,
RateLimitResponse,
UnauthorizedResponse,
+ UnprocessableContentResponse,
)
from .errors import (
BadGateway,
@@ -21,6 +22,7 @@
NotFound,
RateLimitExceeded,
Unauthorized,
+ UnprocessableContent,
)
__all__ = [
@@ -42,4 +44,6 @@
"RateLimitResponse",
"Unauthorized",
"UnauthorizedResponse",
+ "UnprocessableContent",
+ "UnprocessableContentResponse",
]
diff --git a/src/sayari/shared_errors/errors/__init__.py b/src/sayari/shared_errors/errors/__init__.py
index ba318ef4..fd0c66cb 100644
--- a/src/sayari/shared_errors/errors/__init__.py
+++ b/src/sayari/shared_errors/errors/__init__.py
@@ -9,6 +9,7 @@
from .not_found import NotFound
from .rate_limit_exceeded import RateLimitExceeded
from .unauthorized import Unauthorized
+from .unprocessable_content import UnprocessableContent
__all__ = [
"BadGateway",
@@ -20,4 +21,5 @@
"NotFound",
"RateLimitExceeded",
"Unauthorized",
+ "UnprocessableContent",
]
diff --git a/src/sayari/shared_errors/errors/unprocessable_content.py b/src/sayari/shared_errors/errors/unprocessable_content.py
new file mode 100644
index 00000000..be24d344
--- /dev/null
+++ b/src/sayari/shared_errors/errors/unprocessable_content.py
@@ -0,0 +1,9 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.api_error import ApiError
+from ..types.unprocessable_content_response import UnprocessableContentResponse
+
+
+class UnprocessableContent(ApiError):
+ def __init__(self, body: UnprocessableContentResponse):
+ super().__init__(status_code=422, body=body)
diff --git a/src/sayari/shared_errors/types/__init__.py b/src/sayari/shared_errors/types/__init__.py
index 3e32c428..c0934f97 100644
--- a/src/sayari/shared_errors/types/__init__.py
+++ b/src/sayari/shared_errors/types/__init__.py
@@ -9,6 +9,7 @@
from .not_found_response import NotFoundResponse
from .rate_limit_response import RateLimitResponse
from .unauthorized_response import UnauthorizedResponse
+from .unprocessable_content_response import UnprocessableContentResponse
__all__ = [
"BadGatewayResponse",
@@ -20,4 +21,5 @@
"NotFoundResponse",
"RateLimitResponse",
"UnauthorizedResponse",
+ "UnprocessableContentResponse",
]
diff --git a/src/sayari/shared_errors/types/not_acceptable_response.py b/src/sayari/shared_errors/types/not_acceptable_response.py
index 9ab699e1..df3f90eb 100644
--- a/src/sayari/shared_errors/types/not_acceptable_response.py
+++ b/src/sayari/shared_errors/types/not_acceptable_response.py
@@ -8,7 +8,7 @@
class NotAcceptableResponse(UniversalBaseModel):
"""
- Request made in an unacceptable state. This is most commonly due to parameter validation errors.
+ Request made in an unacceptable state due to an invalid Accept header.
"""
status: int
diff --git a/src/sayari/shared_errors/types/unprocessable_content_response.py b/src/sayari/shared_errors/types/unprocessable_content_response.py
new file mode 100644
index 00000000..14d0232a
--- /dev/null
+++ b/src/sayari/shared_errors/types/unprocessable_content_response.py
@@ -0,0 +1,25 @@
+# This file was auto-generated by Fern from our API Definition.
+
+from ...core.pydantic_utilities import UniversalBaseModel
+import typing
+from ...core.pydantic_utilities import IS_PYDANTIC_V2
+import pydantic
+
+
+class UnprocessableContentResponse(UniversalBaseModel):
+ """
+ Request made with an invalid body. This is most commonly due to parameter validation errors.
+ """
+
+ status: int
+ message: typing.List[str]
+ success: bool
+
+ 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 0e6e7ec2..1a2063e3 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 (
+ CaseStatus,
ClientName,
CompanyType,
Coordinate,
@@ -15,6 +16,8 @@
EntitySummary,
EntityTranslatedLabel,
Identifier,
+ MatchCount,
+ MatchStrengthEnum,
PossiblySameAs,
PossiblySameAsData,
PossiblySameAsMatch,
@@ -39,6 +42,7 @@
)
__all__ = [
+ "CaseStatus",
"ClientName",
"CompanyType",
"Coordinate",
@@ -53,6 +57,8 @@
"EntitySummary",
"EntityTranslatedLabel",
"Identifier",
+ "MatchCount",
+ "MatchStrengthEnum",
"PossiblySameAs",
"PossiblySameAsData",
"PossiblySameAsMatch",
diff --git a/src/sayari/shared_types/types/__init__.py b/src/sayari/shared_types/types/__init__.py
index be46eeed..f93f2ae6 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_status import CaseStatus
from .client_name import ClientName
from .company_type import CompanyType
from .coordinate import Coordinate
@@ -14,6 +15,8 @@
from .entity_summary import EntitySummary
from .entity_translated_label import EntityTranslatedLabel
from .identifier import Identifier
+from .match_count import MatchCount
+from .match_strength_enum import MatchStrengthEnum
from .possibly_same_as import PossiblySameAs
from .possibly_same_as_data import PossiblySameAsData
from .possibly_same_as_match import PossiblySameAsMatch
@@ -37,6 +40,7 @@
from .status import Status
__all__ = [
+ "CaseStatus",
"ClientName",
"CompanyType",
"Coordinate",
@@ -51,6 +55,8 @@
"EntitySummary",
"EntityTranslatedLabel",
"Identifier",
+ "MatchCount",
+ "MatchStrengthEnum",
"PossiblySameAs",
"PossiblySameAsData",
"PossiblySameAsMatch",
diff --git a/src/sayari/project_entity/types/case_status.py b/src/sayari/shared_types/types/case_status.py
similarity index 100%
rename from src/sayari/project_entity/types/case_status.py
rename to src/sayari/shared_types/types/case_status.py
diff --git a/src/sayari/project_entity/types/match_count.py b/src/sayari/shared_types/types/match_count.py
similarity index 100%
rename from src/sayari/project_entity/types/match_count.py
rename to src/sayari/shared_types/types/match_count.py
diff --git a/src/sayari/project_entity/types/match_strength_enum.py b/src/sayari/shared_types/types/match_strength_enum.py
similarity index 100%
rename from src/sayari/project_entity/types/match_strength_enum.py
rename to src/sayari/shared_types/types/match_strength_enum.py
diff --git a/src/sayari/source/__init__.py b/src/sayari/source/__init__.py
deleted file mode 100644
index 9574a002..00000000
--- a/src/sayari/source/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# This file was auto-generated by Fern from our API Definition.
-
-from .types import GetSourceResponse, ListSourcesResponse, Source
-
-__all__ = ["GetSourceResponse", "ListSourcesResponse", "Source"]
diff --git a/src/sayari/source/client.py b/src/sayari/source/client.py
deleted file mode 100644
index 98142e80..00000000
--- a/src/sayari/source/client.py
+++ /dev/null
@@ -1,486 +0,0 @@
-# This file was auto-generated by Fern from our API Definition.
-
-from ..core.client_wrapper import SyncClientWrapper
-import typing
-from ..core.request_options import RequestOptions
-from .types.list_sources_response import ListSourcesResponse
-from ..core.pydantic_utilities import parse_obj_as
-from ..shared_errors.errors.bad_request import BadRequest
-from ..shared_errors.types.bad_request_response import BadRequestResponse
-from ..shared_errors.errors.unauthorized import Unauthorized
-from ..shared_errors.types.unauthorized_response import UnauthorizedResponse
-from ..shared_errors.errors.method_not_allowed import MethodNotAllowed
-from ..shared_errors.types.method_not_allowed_response import MethodNotAllowedResponse
-from ..shared_errors.errors.rate_limit_exceeded import RateLimitExceeded
-from ..shared_errors.types.rate_limit_response import RateLimitResponse
-from ..shared_errors.errors.internal_server_error import InternalServerError
-from ..shared_errors.types.internal_server_error_response import InternalServerErrorResponse
-from json.decoder import JSONDecodeError
-from ..core.api_error import ApiError
-from .types.get_source_response import GetSourceResponse
-from ..core.jsonable_encoder import jsonable_encoder
-from ..shared_errors.errors.not_found import NotFound
-from ..shared_errors.types.not_found_response import NotFoundResponse
-from ..core.client_wrapper import AsyncClientWrapper
-
-
-class SourceClient:
- def __init__(self, *, client_wrapper: SyncClientWrapper):
- self._client_wrapper = client_wrapper
-
- def list_sources(
- self,
- *,
- limit: typing.Optional[int] = None,
- offset: typing.Optional[int] = None,
- request_options: typing.Optional[RequestOptions] = None,
- ) -> ListSourcesResponse:
- """
- This endpoint is deprecated. Use /v1/ontology/sources instead. Returns metadata for all sources that Sayari collects data from
-
- Parameters
- ----------
- limit : typing.Optional[int]
- A limit on the number of objects to be returned with a range between 1 and 100. Defaults to 100.
-
- offset : typing.Optional[int]
- Number of results to skip before returning response. Defaults to 0.
-
- request_options : typing.Optional[RequestOptions]
- Request-specific configuration.
-
- Returns
- -------
- ListSourcesResponse
-
- Examples
- --------
- from sayari import Sayari
-
- client = Sayari(
- client_id="YOUR_CLIENT_ID",
- client_secret="YOUR_CLIENT_SECRET",
- )
- client.source.list_sources(
- limit=2,
- )
- """
- _response = self._client_wrapper.httpx_client.request(
- "v1/sources",
- method="GET",
- params={
- "limit": limit,
- "offset": offset,
- },
- request_options=request_options,
- )
- try:
- if 200 <= _response.status_code < 300:
- return typing.cast(
- ListSourcesResponse,
- parse_obj_as(
- type_=ListSourcesResponse, # 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 == 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 get_source(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetSourceResponse:
- """
- This endpoint is deprecated. Use /v1/ontology/sources instead. Returns metadata for a source that Sayari collects data from
-
- Parameters
- ----------
- id : str
- The unique identifier for a source in the database
-
- request_options : typing.Optional[RequestOptions]
- Request-specific configuration.
-
- Returns
- -------
- GetSourceResponse
-
- Examples
- --------
- from sayari import Sayari
-
- client = Sayari(
- client_id="YOUR_CLIENT_ID",
- client_secret="YOUR_CLIENT_SECRET",
- )
- client.source.get_source(
- id="f4396e4b8a41d1fd9f09ea94d2ebedb9",
- )
- """
- _response = self._client_wrapper.httpx_client.request(
- f"v1/source/{jsonable_encoder(id)}",
- method="GET",
- request_options=request_options,
- )
- try:
- if 200 <= _response.status_code < 300:
- return typing.cast(
- GetSourceResponse,
- parse_obj_as(
- type_=GetSourceResponse, # 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)
-
-
-class AsyncSourceClient:
- def __init__(self, *, client_wrapper: AsyncClientWrapper):
- self._client_wrapper = client_wrapper
-
- async def list_sources(
- self,
- *,
- limit: typing.Optional[int] = None,
- offset: typing.Optional[int] = None,
- request_options: typing.Optional[RequestOptions] = None,
- ) -> ListSourcesResponse:
- """
- This endpoint is deprecated. Use /v1/ontology/sources instead. Returns metadata for all sources that Sayari collects data from
-
- Parameters
- ----------
- limit : typing.Optional[int]
- A limit on the number of objects to be returned with a range between 1 and 100. Defaults to 100.
-
- offset : typing.Optional[int]
- Number of results to skip before returning response. Defaults to 0.
-
- request_options : typing.Optional[RequestOptions]
- Request-specific configuration.
-
- Returns
- -------
- ListSourcesResponse
-
- Examples
- --------
- import asyncio
-
- from sayari import AsyncSayari
-
- client = AsyncSayari(
- client_id="YOUR_CLIENT_ID",
- client_secret="YOUR_CLIENT_SECRET",
- )
-
-
- async def main() -> None:
- await client.source.list_sources(
- limit=2,
- )
-
-
- asyncio.run(main())
- """
- _response = await self._client_wrapper.httpx_client.request(
- "v1/sources",
- method="GET",
- params={
- "limit": limit,
- "offset": offset,
- },
- request_options=request_options,
- )
- try:
- if 200 <= _response.status_code < 300:
- return typing.cast(
- ListSourcesResponse,
- parse_obj_as(
- type_=ListSourcesResponse, # 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 == 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 get_source(
- self, id: str, *, request_options: typing.Optional[RequestOptions] = None
- ) -> GetSourceResponse:
- """
- This endpoint is deprecated. Use /v1/ontology/sources instead. Returns metadata for a source that Sayari collects data from
-
- Parameters
- ----------
- id : str
- The unique identifier for a source in the database
-
- request_options : typing.Optional[RequestOptions]
- Request-specific configuration.
-
- Returns
- -------
- GetSourceResponse
-
- Examples
- --------
- import asyncio
-
- from sayari import AsyncSayari
-
- client = AsyncSayari(
- client_id="YOUR_CLIENT_ID",
- client_secret="YOUR_CLIENT_SECRET",
- )
-
-
- async def main() -> None:
- await client.source.get_source(
- id="f4396e4b8a41d1fd9f09ea94d2ebedb9",
- )
-
-
- asyncio.run(main())
- """
- _response = await self._client_wrapper.httpx_client.request(
- f"v1/source/{jsonable_encoder(id)}",
- method="GET",
- request_options=request_options,
- )
- try:
- if 200 <= _response.status_code < 300:
- return typing.cast(
- GetSourceResponse,
- parse_obj_as(
- type_=GetSourceResponse, # 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)
diff --git a/src/sayari/source/types/__init__.py b/src/sayari/source/types/__init__.py
deleted file mode 100644
index e3b8d430..00000000
--- a/src/sayari/source/types/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# This file was auto-generated by Fern from our API Definition.
-
-from .get_source_response import GetSourceResponse
-from .list_sources_response import ListSourcesResponse
-from .source import Source
-
-__all__ = ["GetSourceResponse", "ListSourcesResponse", "Source"]
diff --git a/src/sayari/source/types/get_source_response.py b/src/sayari/source/types/get_source_response.py
deleted file mode 100644
index c6db7080..00000000
--- a/src/sayari/source/types/get_source_response.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# This file was auto-generated by Fern from our API Definition.
-
-from .source import Source
-from ...core.pydantic_utilities import IS_PYDANTIC_V2
-import typing
-import pydantic
-
-
-class GetSourceResponse(Source):
- """
- OK
-
- Examples
- --------
- from sayari.source import GetSourceResponse
-
- GetSourceResponse(
- id="f4396e4b8a41d1fd9f09ea94d2ebedb9",
- label="UAE Abu Dhabi Global Market Corporate Registry",
- description="Contains profiles of registered companies. Provides standard company information including name, tax ID, status, address, and business purpose as well as current and former shareholders and directors.",
- country="ARE",
- region="middle_east_&_africa",
- date_added="2022-07-25",
- source_type="company_data",
- record_type="company_record",
- structure="structured",
- source_url="https://www.adgm.com/public-registers",
- pep=False,
- watchlist=False,
- )
- """
-
- 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/source/types/list_sources_response.py b/src/sayari/source/types/list_sources_response.py
deleted file mode 100644
index ae84ad88..00000000
--- a/src/sayari/source/types/list_sources_response.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# This file was auto-generated by Fern from our API Definition.
-
-from ...base_types.types.paginated_response import PaginatedResponse
-import typing
-from .source import Source
-from ...core.pydantic_utilities import IS_PYDANTIC_V2
-import pydantic
-
-
-class ListSourcesResponse(PaginatedResponse):
- """
- OK
-
- Examples
- --------
- from sayari.base_types import QualifiedCount
- from sayari.source import ListSourcesResponse, Source
-
- ListSourcesResponse(
- offset=0,
- limit=2,
- size=QualifiedCount(
- count=547,
- qualifier="eq",
- ),
- next=True,
- data=[
- Source(
- id="e85d865943ee6d8369307569d2ad9de0",
- label="Acuris Risk Intelligence Adverse Media Data",
- description="Contains PDFs and URLs to adverse media reporting for PEPs, SOEs, sanctioned entities, and entities linked to financial regulatory and law enforcement actions. Available for millions of entities from 'Acuris Risk Intelligence KYC6 (3rd Party Data)' in 'Records' section.",
- country="XXX",
- region="international_(multi-region_coverage)",
- date_added="2022-04-11",
- source_type="adverse_media_/_negative_news_data",
- record_type="adverse_media_record",
- structure="unstructured",
- source_url="https://www.acurisriskintelligence.com/",
- pep=False,
- watchlist=False,
- ),
- Source(
- id="a8c6ee1cd4dfc952105ee8c0e4836f08",
- label="Acuris Risk Intelligence KYC6 (3rd Party Data)",
- description="Contains profiles of PEPs, sanctioned entities, SOEs, and entities linked to financial regulatory and law enforcement actions from hundreds of international watchlists. Provides identifying information on individuals and companies as available.",
- country="XXX",
- region="international_(multi-region_coverage)",
- date_added="2022-02-09",
- source_type="risk_intelligence_data",
- record_type="risk_intelligence_record",
- structure="unstructured",
- source_url="https://www.acurisriskintelligence.com/",
- pep=False,
- watchlist=False,
- ),
- ],
- )
- """
-
- offset: int
- next: bool
- data: typing.List[Source]
-
- 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/trade/client.py b/src/sayari/trade/client.py
index bd42a15c..82213ab5 100644
--- a/src/sayari/trade/client.py
+++ b/src/sayari/trade/client.py
@@ -47,7 +47,7 @@ def search_shipments(
Parameters
----------
limit : typing.Optional[int]
- A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+ A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
offset : typing.Optional[int]
Number of results to skip before returning response. Defaults to 0.
@@ -83,7 +83,7 @@ def search_shipments(
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
"""
@@ -184,7 +184,7 @@ def search_suppliers(
Parameters
----------
limit : typing.Optional[int]
- A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+ A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
offset : typing.Optional[int]
Number of results to skip before returning response. Defaults to 0.
@@ -220,7 +220,7 @@ def search_suppliers(
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
"""
@@ -321,7 +321,7 @@ def search_buyers(
Parameters
----------
limit : typing.Optional[int]
- A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+ A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
offset : typing.Optional[int]
Number of results to skip before returning response. Defaults to 0.
@@ -357,7 +357,7 @@ def search_buyers(
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
"""
@@ -463,7 +463,7 @@ async def search_shipments(
Parameters
----------
limit : typing.Optional[int]
- A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+ A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
offset : typing.Optional[int]
Number of results to skip before returning response. Defaults to 0.
@@ -504,7 +504,7 @@ async def main() -> None:
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
@@ -608,7 +608,7 @@ async def search_suppliers(
Parameters
----------
limit : typing.Optional[int]
- A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+ A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
offset : typing.Optional[int]
Number of results to skip before returning response. Defaults to 0.
@@ -649,7 +649,7 @@ async def main() -> None:
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
@@ -753,7 +753,7 @@ async def search_buyers(
Parameters
----------
limit : typing.Optional[int]
- A limit on the number of objects to be returned with a range between 1 and 10000. Defaults to 100.
+ A limit on the number of objects to be returned with a range between 1 and 3000. Defaults to 100.
offset : typing.Optional[int]
Number of results to skip before returning response. Defaults to 0.
@@ -794,7 +794,7 @@ async def main() -> None:
departure_country=["DEU"],
arrival_country=["RUS"],
hs_code=["854231"],
- arrival_date=["2024-01 TO 2024-10"],
+ arrival_date="2024-01|2024-10",
),
)
diff --git a/src/sayari/trade/types/trade_filter_list.py b/src/sayari/trade/types/trade_filter_list.py
index fc4e225b..64a6d5f7 100644
--- a/src/sayari/trade/types/trade_filter_list.py
+++ b/src/sayari/trade/types/trade_filter_list.py
@@ -128,16 +128,18 @@ class TradeFilterList(UniversalBaseModel):
The buyer purpose contains the provided string.
"""
- arrival_date: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ arrival_date: typing.Optional[str] = pydantic.Field(default=None)
"""
The arrival date is within the provided range. Supports exact dates (YYYY-MM-DD)
- or date ranges (YYYY-MM TO YYYY-MM). Example: ["2024-01 TO 2024-10"] or ["2024-01-30"].
+ or date ranges (YYYY-MM | YYYY-MM). If an exact date is used it will be treated as the minimum date, with no maximum date specified.
+ Example: "2024-01|2024-10" or "2024-01-30".
"""
- departure_date: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
+ departure_date: typing.Optional[str] = pydantic.Field(default=None)
"""
The departure date is within the provided range. Supports exact dates (YYYY-MM-DD)
- or date ranges (YYYY-MM TO YYYY-MM). Example: ["2024-01 TO 2024-10"] or ["2024-01-30"].
+ If an exact date is used it will be treated as the minimum date, with no maximum date specified.
+ or date ranges (YYYY-MM | YYYY-MM). Example: "2024-01|2024-10" or "2024-01-30".
"""
shipment_identifier: typing.Optional[typing.List[str]] = pydantic.Field(default=None)