diff --git a/reference.md b/reference.md index a76be864..325b8ea5 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,6 +2648,180 @@ client.ontology.get_source_types( ## ProjectEntityAttributes +
client.project_entity_attributes.get_project_entity_attributes(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves all attributes for a project entity. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +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", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**project_id:** `str` + +
+
+ +
+
+ +**project_entity_id:** `str` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.project_entity_attributes.create_project_entity_attribute(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Creates a new attribute for a project entity. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```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_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, + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**project_id:** `str` + +
+
+ +
+
+ +**project_entity_id:** `str` + +
+
+ +
+
+ +**request:** `CreateProjectEntityAttributeRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+
client.project_entity_attributes.update_project_entity_attribute(...)
@@ -2747,6 +2921,95 @@ client.project_entity_attributes.update_project_entity_attribute(
+ + +
+ +
client.project_entity_attributes.delete_project_entity_attribute(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deletes a specific attribute for a project entity. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +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", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**project_id:** `str` + +
+
+ +
+
+ +**project_entity_id:** `str` + +
+
+ +
+
+ +**attribute_id:** `str` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -5789,157 +6052,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 +6324,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 +6342,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 +6434,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 +6452,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 +6544,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 +6562,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..f38080aa 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 @@ -230,19 +229,20 @@ CreateResolvedProjectEntityRequest, FacetBucket, FacetsResponse, + FieldMatchQuality, GroupedAttribute, GroupedAttributeValue, Location, MatchCount, MatchProfileEnum, MatchStrengthEnum, - MatchedAttributes, ProductBucket, ProductCount, ProductMapping, ProjectEntitiesResponse, ProjectEntityExistsResponseData, ProjectEntityIdResponse, + ProjectEntityMatchExplanation, ProjectEntityMatchResponse, ProjectEntityResponse, ProjectEntitySupplyChainSummaryResponse, @@ -268,6 +268,12 @@ UpstreamInfo, ) from .project_entity_attributes import ( + CreateProjectEntityAttributeRequest, + CreateProjectEntityAttributeResponse, + CreateProjectEntityAttributeResponseData, + ProjectEntityAttribute, + ProjectEntityAttributeValue, + ProjectEntityAttributesResponse, UpdateProjectEntityAttributeRequest, UpdateProjectEntityAttributeResponse, UpdateProjectEntityAttributeResponseData, @@ -327,6 +333,8 @@ RateLimitResponse, Unauthorized, UnauthorizedResponse, + UnprocessableContent, + UnprocessableContentResponse, ) from .shared_types import ( ClientName, @@ -365,7 +373,6 @@ SourceCountInfo, Status, ) -from .source import GetSourceResponse, ListSourcesResponse, Source from .supply_chain import ( TradeTraversalComponent, TradeTraversalData, @@ -427,6 +434,7 @@ "AttributeValues", "Attributes", "AttributesResponse", + "Audience", "AuthResponse", "BadGateway", "BadGatewayResponse", @@ -463,6 +471,9 @@ "CountryData", "CountryInfo", "CountryProperties", + "CreateProjectEntityAttributeRequest", + "CreateProjectEntityAttributeResponse", + "CreateProjectEntityAttributeResponseData", "CreateProjectEntitySupplyChainSnapshotRequest", "CreateProjectEntitySupplyChainSnapshotResponse", "CreateProjectRequest", @@ -493,6 +504,7 @@ "EventInfo", "FacetBucket", "FacetsResponse", + "FieldMatchQuality", "FilterList", "FinanceType", "FinancesData", @@ -528,7 +540,6 @@ "GetProjectEntitiesResponse", "GetProjectsResponse", "GetRecordResponse", - "GetSourceResponse", "GroupedAttribute", "GroupedAttributeValue", "HistoryInfo", @@ -544,7 +555,6 @@ "InternalServerError", "InternalServerErrorResponse", "Language", - "ListSourcesResponse", "Location", "MatchCount", "MatchExplanation", @@ -552,7 +562,6 @@ "MatchQuality", "MatchStrength", "MatchStrengthEnum", - "MatchedAttributes", "MeasurementData", "MeasurementInfo", "MeasurementProperties", @@ -628,8 +637,12 @@ "ProjectEntitiesFilter", "ProjectEntitiesResponse", "ProjectEntity", + "ProjectEntityAttribute", + "ProjectEntityAttributeValue", + "ProjectEntityAttributesResponse", "ProjectEntityExistsResponseData", "ProjectEntityIdResponse", + "ProjectEntityMatchExplanation", "ProjectEntityMatchResponse", "ProjectEntityResponse", "ProjectEntitySupplyChainSnapshotByIdResponse", @@ -714,7 +727,6 @@ "ShortestPathResponse", "SingleProjectEntityResponse", "SortField", - "Source", "SourceCountInfo", "SourceField", "SourceId", @@ -760,6 +772,8 @@ "Unauthorized", "UnauthorizedResponse", "Unit", + "UnprocessableContent", + "UnprocessableContentResponse", "UpdateAttribute", "UpdateEntityTagsResponse", "UpdateProjectEntityAttributeRequest", @@ -799,7 +813,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/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_entity/__init__.py b/src/sayari/project_entity/__init__.py index add92aca..e8a63098 100644 --- a/src/sayari/project_entity/__init__.py +++ b/src/sayari/project_entity/__init__.py @@ -12,19 +12,20 @@ CreateResolvedProjectEntityRequest, FacetBucket, FacetsResponse, + FieldMatchQuality, GroupedAttribute, GroupedAttributeValue, Location, MatchCount, MatchProfileEnum, MatchStrengthEnum, - MatchedAttributes, ProductBucket, ProductCount, ProductMapping, ProjectEntitiesResponse, ProjectEntityExistsResponseData, ProjectEntityIdResponse, + ProjectEntityMatchExplanation, ProjectEntityMatchResponse, ProjectEntityResponse, ProjectEntitySupplyChainSummaryResponse, @@ -62,19 +63,20 @@ "CreateResolvedProjectEntityRequest", "FacetBucket", "FacetsResponse", + "FieldMatchQuality", "GroupedAttribute", "GroupedAttributeValue", "Location", "MatchCount", "MatchProfileEnum", "MatchStrengthEnum", - "MatchedAttributes", "ProductBucket", "ProductCount", "ProductMapping", "ProjectEntitiesResponse", "ProjectEntityExistsResponseData", "ProjectEntityIdResponse", + "ProjectEntityMatchExplanation", "ProjectEntityMatchResponse", "ProjectEntityResponse", "ProjectEntitySupplyChainSummaryResponse", diff --git a/src/sayari/project_entity/types/__init__.py b/src/sayari/project_entity/types/__init__.py index 02a1fae0..ec4937ed 100644 --- a/src/sayari/project_entity/types/__init__.py +++ b/src/sayari/project_entity/types/__init__.py @@ -11,19 +11,20 @@ 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_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_supply_chain_summary_response import ProjectEntitySupplyChainSummaryResponse @@ -60,19 +61,20 @@ "CreateResolvedProjectEntityRequest", "FacetBucket", "FacetsResponse", + "FieldMatchQuality", "GroupedAttribute", "GroupedAttributeValue", "Location", "MatchCount", "MatchProfileEnum", "MatchStrengthEnum", - "MatchedAttributes", "ProductBucket", "ProductCount", "ProductMapping", "ProjectEntitiesResponse", "ProjectEntityExistsResponseData", "ProjectEntityIdResponse", + "ProjectEntityMatchExplanation", "ProjectEntityMatchResponse", "ProjectEntityResponse", "ProjectEntitySupplyChainSummaryResponse", 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/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_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/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/source/types/source.py b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_request.py similarity index 51% rename from src/sayari/source/types/source.py rename to src/sayari/project_entity_attributes/types/create_project_entity_attribute_request.py index 4fb5a822..9b03897c 100644 --- a/src/sayari/source/types/source.py +++ b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_request.py @@ -1,33 +1,27 @@ # 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 from ...core.pydantic_utilities import IS_PYDANTIC_V2 +import typing +import pydantic -class Source(UniversalBaseModel): - id: str = pydantic.Field() - """ - The unique identifier of the source +class CreateProjectEntityAttributeRequest(UniversalBaseModel): """ + Examples + -------- + from sayari.project_entity_attributes import CreateProjectEntityAttributeRequest - label: str - description: str - country: Country = pydantic.Field() - """ - Source [country](/sayari-library/ontology/enumerated-types#country) + CreateProjectEntityAttributeRequest( + field="custom_phone", + value="+1-555-123-4567", + match_resolution=False, + ) """ - region: str - date_added: str - source_type: str - record_type: str - structure: str - source_url: typing.Optional[str] = None - pep: bool - watchlist: bool + 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 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/types/matched_attributes.py b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_response_data.py similarity index 61% rename from src/sayari/project_entity/types/matched_attributes.py rename to src/sayari/project_entity_attributes/types/create_project_entity_attribute_response_data.py index 3a8210ed..ef60e44b 100644 --- a/src/sayari/project_entity/types/matched_attributes.py +++ b/src/sayari/project_entity_attributes/types/create_project_entity_attribute_response_data.py @@ -1,17 +1,16 @@ # 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 typing import pydantic -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 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 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/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/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)