diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index fe9e7dbb..9a68cc36 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -8,11 +8,15 @@ docs/BotResult.md docs/BrowserDetails.md docs/Canvas.md docs/DecryptionKey.md +docs/EdgeRequest.md +docs/EdgeRequestHeadersInner.md docs/Emoji.md docs/Error.md docs/ErrorCode.md docs/ErrorResponse.md docs/Event.md +docs/EventDevice.md +docs/EventEdge.md docs/EventRuleAction.md docs/EventRuleActionAllow.md docs/EventRuleActionBlock.md @@ -79,11 +83,15 @@ fingerprint_server_sdk/models/bot_info_identity.py fingerprint_server_sdk/models/bot_result.py fingerprint_server_sdk/models/browser_details.py fingerprint_server_sdk/models/canvas.py +fingerprint_server_sdk/models/edge_request.py +fingerprint_server_sdk/models/edge_request_headers_inner.py fingerprint_server_sdk/models/emoji.py fingerprint_server_sdk/models/error.py fingerprint_server_sdk/models/error_code.py fingerprint_server_sdk/models/error_response.py fingerprint_server_sdk/models/event.py +fingerprint_server_sdk/models/event_device.py +fingerprint_server_sdk/models/event_edge.py fingerprint_server_sdk/models/event_rule_action.py fingerprint_server_sdk/models/event_rule_action_allow.py fingerprint_server_sdk/models/event_rule_action_block.py diff --git a/README.md b/README.md index 3b60ff26..aa7f4665 100644 --- a/README.md +++ b/README.md @@ -303,6 +303,7 @@ All URIs are relative to *https://api.fpjs.io/v4* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- +*FingerprintApi* | [**analyze_request_for_automation_intelligence**](docs/FingerprintApi.md#analyze_request_for_automation_intelligence) | **POST** /edge | Collect Automation Intelligence. *FingerprintApi* | [**delete_visitor_data**](docs/FingerprintApi.md#delete_visitor_data) | **DELETE** /visitors/{visitor_id} | Delete a visitor ID *FingerprintApi* | [**get_event**](docs/FingerprintApi.md#get_event) | **GET** /events/{event_id} | Get an event by event ID *FingerprintApi* | [**search_events**](docs/FingerprintApi.md#search_events) | **GET** /events | Search events @@ -318,11 +319,15 @@ Class | Method | HTTP request | Description - [BotResult](docs/BotResult.md) - [BrowserDetails](docs/BrowserDetails.md) - [Canvas](docs/Canvas.md) + - [EdgeRequest](docs/EdgeRequest.md) + - [EdgeRequestHeadersInner](docs/EdgeRequestHeadersInner.md) - [Emoji](docs/Emoji.md) - [Error](docs/Error.md) - [ErrorCode](docs/ErrorCode.md) - [ErrorResponse](docs/ErrorResponse.md) - [Event](docs/Event.md) + - [EventDevice](docs/EventDevice.md) + - [EventEdge](docs/EventEdge.md) - [EventRuleAction](docs/EventRuleAction.md) - [EventRuleActionAllow](docs/EventRuleActionAllow.md) - [EventRuleActionBlock](docs/EventRuleActionBlock.md) diff --git a/README.pypi.md b/README.pypi.md index ea4c29f9..2657495c 100644 --- a/README.pypi.md +++ b/README.pypi.md @@ -299,6 +299,7 @@ All URIs are relative to *https://api.fpjs.io/v4* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- +*FingerprintApi* | [**analyze_request_for_automation_intelligence**](https://github.com/fingerprintjs/python-sdk/blob/main/docs/FingerprintApi.md#analyze_request_for_automation_intelligence) | **POST** /edge | Collect Automation Intelligence. *FingerprintApi* | [**delete_visitor_data**](https://github.com/fingerprintjs/python-sdk/blob/main/docs/FingerprintApi.md#delete_visitor_data) | **DELETE** /visitors/{visitor_id} | Delete a visitor ID *FingerprintApi* | [**get_event**](https://github.com/fingerprintjs/python-sdk/blob/main/docs/FingerprintApi.md#get_event) | **GET** /events/{event_id} | Get an event by event ID *FingerprintApi* | [**search_events**](https://github.com/fingerprintjs/python-sdk/blob/main/docs/FingerprintApi.md#search_events) | **GET** /events | Search events @@ -314,11 +315,15 @@ Class | Method | HTTP request | Description - [BotResult](https://github.com/fingerprintjs/python-sdk/blob/main/docs/BotResult.md) - [BrowserDetails](https://github.com/fingerprintjs/python-sdk/blob/main/docs/BrowserDetails.md) - [Canvas](https://github.com/fingerprintjs/python-sdk/blob/main/docs/Canvas.md) + - [EdgeRequest](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EdgeRequest.md) + - [EdgeRequestHeadersInner](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EdgeRequestHeadersInner.md) - [Emoji](https://github.com/fingerprintjs/python-sdk/blob/main/docs/Emoji.md) - [Error](https://github.com/fingerprintjs/python-sdk/blob/main/docs/Error.md) - [ErrorCode](https://github.com/fingerprintjs/python-sdk/blob/main/docs/ErrorCode.md) - [ErrorResponse](https://github.com/fingerprintjs/python-sdk/blob/main/docs/ErrorResponse.md) - [Event](https://github.com/fingerprintjs/python-sdk/blob/main/docs/Event.md) + - [EventDevice](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventDevice.md) + - [EventEdge](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventEdge.md) - [EventRuleAction](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventRuleAction.md) - [EventRuleActionAllow](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventRuleActionAllow.md) - [EventRuleActionBlock](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventRuleActionBlock.md) diff --git a/docs/EdgeRequest.md b/docs/EdgeRequest.md new file mode 100644 index 00000000..aa326c94 --- /dev/null +++ b/docs/EdgeRequest.md @@ -0,0 +1,17 @@ +# EdgeRequest +HTTP request metadata (including the HTTP method, headers and IP address) sent by you (your server) to the Fingerprint API for IP and bot analysis. To improve accuracy, retain as much of the original semantics of the HTTP request as possible. For example, preserve the order of the request headers and their capitalization. +At least one of `ipv4_address` or `ipv6_address` must be provided; a request with neither is rejected with a `400` error. If both IPv4 and IPv6 are provided, IP intelligence will be provided for each address. If an IPv4-mapped IPv6 address is provided in the `ipv6_address` request property, the IP intelligence will be provided in the `ipv4_address` property of the response. + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**headers** | [**List[EdgeRequestHeadersInner]**](EdgeRequestHeadersInner.md) | Ordered header entries from the request made to your server. Each entry represents one header line. If one header name appears as multiple lines, send each as a separate item in the array. Headers that contain authentication or session data must still be included, but with with their value set to an empty string. This includes headers like `Authorization` and `Cookie`, but may contain more depending on your specific project, for instance `Proxy-Authenticate` or `X-Api-Key`. Omitting the headers entirely changes the shape of the request and can affect detection. Never forward the real secret values. Whenever possible, we recommend preserving header order and capitalization to provide the best accuracy, however it’s not a strict requirement if your runtime does not maintain http header order or canonicalizes header names. | +**method** | **str** | The original HTTP method of the request. If supported in your runtime, preserve the original casing. | +**url** | **str** | Absolute URL of the request, without a \\#fragment suffix. Only HTTP and HTTPS schemes are supported. | +**ipv4_address** | **str** | Client IPv4 address observed by your server. | [optional] +**ipv6_address** | **str** | Client IPv6 address observed by your server. | [optional] +**linked_id** | **str** | A customer-provided id that was sent with the request. | [optional] +**tags** | **Dict[str, object]** | A customer-provided value or an object that was sent with the identification request or updated later. | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/docs/EdgeRequestHeadersInner.md b/docs/EdgeRequestHeadersInner.md new file mode 100644 index 00000000..0fc3f1f8 --- /dev/null +++ b/docs/EdgeRequestHeadersInner.md @@ -0,0 +1,9 @@ +# EdgeRequestHeadersInner +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **str** | Header name as forwarded by your server. Headers must be valid according to RFC 7230 and will be canonicalized according to RFC 9112. | +**value** | **str** | Value of a single forwarded header entry. Be careful to preserve the original encoding and escaping. For example, do not double escape quotes. | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/docs/Event.md b/docs/Event.md index 93434207..21ee7401 100644 --- a/docs/Event.md +++ b/docs/Event.md @@ -1,22 +1,35 @@ # Event -Contains results from Fingerprint Identification and all active Smart Signals. Some Smart Signals are only supported for certain device types, these fields will be omitted for events not generated from the supported devices. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. +An identification event (`source: device`) or an Automation Intelligence event (`source: edge`). + +Use `source` to tell them apart. Device events include Identification and device-derived Smart Signals. Edge events do not. + +Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. + ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **event_id** | **str** | Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. | **timestamp** | **int** | Timestamp of the event with millisecond precision in Unix time. | -**source** | [**EventSource**](EventSource.md) | | [optional] -**incremental_identification_status** | [**IncrementalIdentificationStatus**](IncrementalIdentificationStatus.md) | | [optional] **linked_id** | **str** | A customer-provided id that was sent with the request. | [optional] +**tags** | **Dict[str, object]** | A customer-provided value or an object that was sent with the identification request or updated later. | [optional] +**url** | **str** | Page URL from which the request was sent. | [optional] +**bot_info** | [**BotInfo**](BotInfo.md) | | [optional] +**ip_info** | [**IPInfo**](IPInfo.md) | | +**proxy** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy | [optional] +**proxy_confidence** | [**ProxyConfidence**](ProxyConfidence.md) | | [optional] +**proxy_details** | [**ProxyDetails**](ProxyDetails.md) | | [optional] +**vpn** | **bool** | VPN or other anonymizing service has been used when sending the request. | [optional] +**vpn_confidence** | [**VpnConfidence**](VpnConfidence.md) | | [optional] +**vpn_methods** | [**VpnMethods**](VpnMethods.md) | | [optional] +**source** | [**EventSource**](EventSource.md) | | +**incremental_identification_status** | [**IncrementalIdentificationStatus**](IncrementalIdentificationStatus.md) | | [optional] **environment_id** | **str** | Environment Id of the event. | [optional] -**suspect** | **bool** | Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-v4-update-event). | [optional] +**suspect** | **bool** | Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-update-event). | [optional] **sdk** | [**SDK**](SDK.md) | | [optional] **replayed** | **bool** | `true` if we determined that this payload was replayed, `false` otherwise. | [optional] **identification** | [**Identification**](Identification.md) | | [optional] **supplementary_id_high_recall** | [**SupplementaryIDHighRecall**](SupplementaryIDHighRecall.md) | | [optional] -**tags** | **Dict[str, object]** | A customer-provided value or an object that was sent with the identification request or updated later. | [optional] -**url** | **str** | Page URL from which the request was sent. | [optional] **bundle_id** | **str** | Bundle Id of the iOS application integrated with the Fingerprint SDK for the event. | [optional] **package_name** | **str** | Package name of the Android application integrated with the Fingerprint SDK for the event. | [optional] **ip_address** | **str** | IP address of the requesting browser or bot. | [optional] @@ -30,17 +43,12 @@ Name | Type | Description | Notes **active_call** | **bool** | Indicates whether the mobile device had an active call (cellular or VoIP) at the time of the request. Available from SDK 2.16.0+ on iOS and Android. | [optional] **bot** | [**BotResult**](BotResult.md) | | [optional] **bot_type** | **str** | Additional classification of the bot type if detected. | [optional] -**bot_info** | [**BotInfo**](BotInfo.md) | | [optional] **cloned_app** | **bool** | Android specific cloned application detection. There are 2 values: * `true` - Presence of app cloners work detected (e.g. fully cloned application found or launch of it inside of a not main working profile detected). * `false` - No signs of cloned application detected or the client is not Android. | [optional] **developer_tools** | **bool** | `true` if the browser has DevTools open (Chrome, Firefox) or the Android/iOS device has Developer Tools enabled, `false` otherwise. | [optional] **emulator** | **bool** | Android specific emulator detection. There are 2 values: * `true` - Emulated environment detected (e.g. launch inside of AVD). * `false` - No signs of emulated environment detected or the client is not Android. | [optional] **factory_reset_timestamp** | **int** | The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. When a factory reset cannot be detected on the mobile device or when the request is initiated from a browser, this field will correspond to the *epoch* time (i.e 1 Jan 1970 UTC) as a value of 0. See [Factory Reset Detection](https://docs.fingerprint.com/docs/smart-signals-reference#factory-reset-detection) to learn more about this Smart Signal. | [optional] **frida** | **bool** | [Frida](https://frida.re/docs/) detection for Android and iOS devices. There are 2 values: * `true` - Frida detected * `false` - No signs of Frida or the client is not a mobile device. | [optional] **ip_blocklist** | [**IPBlockList**](IPBlockList.md) | | [optional] -**ip_info** | [**IPInfo**](IPInfo.md) | | [optional] -**proxy** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy | [optional] -**proxy_confidence** | [**ProxyConfidence**](ProxyConfidence.md) | | [optional] -**proxy_details** | [**ProxyDetails**](ProxyDetails.md) | | [optional] **proxy_ml_score** | **float** | Machine learning–based proxy score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `proxy` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] **incognito** | **bool** | `true` if we detected incognito mode used in the browser, `false` otherwise. | [optional] **jailbroken** | **bool** | iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. | [optional] @@ -58,12 +66,9 @@ Name | Type | Description | Notes **velocity** | [**Velocity**](Velocity.md) | | [optional] **virtual_machine** | **bool** | `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. | [optional] **virtual_machine_ml_score** | **float** | Machine learning–based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] -**vpn** | **bool** | VPN or other anonymizing service has been used when sending the request. | [optional] -**vpn_confidence** | [**VpnConfidence**](VpnConfidence.md) | | [optional] **vpn_ml_score** | **float** | Machine learning–based VPN score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `vpn` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] **vpn_origin_timezone** | **str** | Local timezone which is used in timezone_mismatch method. | [optional] **vpn_origin_country** | **str** | Country of the request (Android SDK version >= 2.4.0, iOS SDK version >= 2.9.0, JS agent >= 3.12.9 / 4.0.2), ISO 3166 format or unknown. | [optional] -**vpn_methods** | [**VpnMethods**](VpnMethods.md) | | [optional] **high_activity_device** | **bool** | Flag indicating if the request came from a high-activity visitor. | [optional] **rare_device** | **bool** | `true` if the device is considered rare based on its combination of hardware and software attributes. A device is classified as rare if it falls within the top 99.9 percentile (lowest-frequency segment) of observed traffic, or if its configuration has not been previously seen (`not_seen`). > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] **rare_device_percentile_bucket** | [**RareDevicePercentileBucket**](RareDevicePercentileBucket.md) | | [optional] diff --git a/docs/EventDevice.md b/docs/EventDevice.md new file mode 100644 index 00000000..70d07386 --- /dev/null +++ b/docs/EventDevice.md @@ -0,0 +1,75 @@ +# EventDevice +Contains results from Fingerprint Identification and Smart Signals derived from client-side device telemetry. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**event_id** | **str** | Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. | +**timestamp** | **int** | Timestamp of the event with millisecond precision in Unix time. | +**linked_id** | **str** | A customer-provided id that was sent with the request. | [optional] +**tags** | **Dict[str, object]** | A customer-provided value or an object that was sent with the identification request or updated later. | [optional] +**url** | **str** | Page URL from which the request was sent. | [optional] +**bot_info** | [**BotInfo**](BotInfo.md) | | [optional] +**ip_info** | [**IPInfo**](IPInfo.md) | | [optional] +**proxy** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy | [optional] +**proxy_confidence** | [**ProxyConfidence**](ProxyConfidence.md) | | [optional] +**proxy_details** | [**ProxyDetails**](ProxyDetails.md) | | [optional] +**vpn** | **bool** | VPN or other anonymizing service has been used when sending the request. | [optional] +**vpn_confidence** | [**VpnConfidence**](VpnConfidence.md) | | [optional] +**vpn_methods** | [**VpnMethods**](VpnMethods.md) | | [optional] +**source** | [**EventSource**](EventSource.md) | | +**incremental_identification_status** | [**IncrementalIdentificationStatus**](IncrementalIdentificationStatus.md) | | [optional] +**environment_id** | **str** | Environment Id of the event. | [optional] +**suspect** | **bool** | Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-update-event). | [optional] +**sdk** | [**SDK**](SDK.md) | | [optional] +**replayed** | **bool** | `true` if we determined that this payload was replayed, `false` otherwise. | [optional] +**identification** | [**Identification**](Identification.md) | | [optional] +**supplementary_id_high_recall** | [**SupplementaryIDHighRecall**](SupplementaryIDHighRecall.md) | | [optional] +**bundle_id** | **str** | Bundle Id of the iOS application integrated with the Fingerprint SDK for the event. | [optional] +**package_name** | **str** | Package name of the Android application integrated with the Fingerprint SDK for the event. | [optional] +**ip_address** | **str** | IP address of the requesting browser or bot. | [optional] +**user_agent** | **str** | User Agent of the client. | [optional] +**device** | **str** | Device model or family extracted from the user agent string. On web, this field is also present inside `browser_details`. | [optional] +**os** | **str** | Operating system family extracted from the user agent string. On web, this field is also present inside `browser_details`. | [optional] +**os_version** | **str** | Operating system version string extracted from the user agent string. On web, this field is also present inside `browser_details`. | [optional] +**client_referrer** | **str** | Client Referrer field corresponds to the `document.referrer` field gathered during an identification request. The value is an empty string if the user navigated to the page directly (not through a link, but, for example, by using a bookmark). | [optional] +**browser_details** | [**BrowserDetails**](BrowserDetails.md) | | [optional] +**proximity** | [**Proximity**](Proximity.md) | | [optional] +**active_call** | **bool** | Indicates whether the mobile device had an active call (cellular or VoIP) at the time of the request. Available from SDK 2.16.0+ on iOS and Android. | [optional] +**bot** | [**BotResult**](BotResult.md) | | [optional] +**bot_type** | **str** | Additional classification of the bot type if detected. | [optional] +**cloned_app** | **bool** | Android specific cloned application detection. There are 2 values: * `true` - Presence of app cloners work detected (e.g. fully cloned application found or launch of it inside of a not main working profile detected). * `false` - No signs of cloned application detected or the client is not Android. | [optional] +**developer_tools** | **bool** | `true` if the browser has DevTools open (Chrome, Firefox) or the Android/iOS device has Developer Tools enabled, `false` otherwise. | [optional] +**emulator** | **bool** | Android specific emulator detection. There are 2 values: * `true` - Emulated environment detected (e.g. launch inside of AVD). * `false` - No signs of emulated environment detected or the client is not Android. | [optional] +**factory_reset_timestamp** | **int** | The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. When a factory reset cannot be detected on the mobile device or when the request is initiated from a browser, this field will correspond to the *epoch* time (i.e 1 Jan 1970 UTC) as a value of 0. See [Factory Reset Detection](https://docs.fingerprint.com/docs/smart-signals-reference#factory-reset-detection) to learn more about this Smart Signal. | [optional] +**frida** | **bool** | [Frida](https://frida.re/docs/) detection for Android and iOS devices. There are 2 values: * `true` - Frida detected * `false` - No signs of Frida or the client is not a mobile device. | [optional] +**ip_blocklist** | [**IPBlockList**](IPBlockList.md) | | [optional] +**proxy_ml_score** | **float** | Machine learning–based proxy score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `proxy` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] +**incognito** | **bool** | `true` if we detected incognito mode used in the browser, `false` otherwise. | [optional] +**jailbroken** | **bool** | iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. | [optional] +**location_spoofing** | **bool** | Flag indicating whether the request came from a mobile device with location spoofing enabled. | [optional] +**mitm_attack** | **bool** | * `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://docs.fingerprint.com/docs/smart-signals-reference#mitm-attack-detection) to learn more about this Smart Signal. | [optional] +**privacy_settings** | **bool** | `true` if the request is from a privacy aware browser (e.g. Tor) or from a browser in which fingerprinting is blocked. Otherwise `false`. | [optional] +**root_apps** | **bool** | Android specific root management apps detection. There are 2 values: * `true` - Root Management Apps detected (e.g. Magisk). * `false` - No Root Management Apps detected or the client isn't Android. | [optional] +**rule_action** | [**EventRuleAction**](EventRuleAction.md) | | [optional] +**simulator** | **bool** | iOS specific simulator detection. There are 2 values: * `true` - Simulator environment detected. * `false` - No signs of simulator or the client is not iOS. | [optional] +**suspect_score** | **int** | Suspect Score is an easy way to integrate Smart Signals into your fraud protection work flow. It is a weighted representation of all Smart Signals present in the payload that helps identify suspicious activity. The value range is [0; S] where S is sum of all Smart Signals weights. See more details here: https://docs.fingerprint.com/docs/suspect-score | [optional] +**tampering** | **bool** | The field can be used as a standalone flag for tampering detection. Alternatively, the more granular fields documented below can be used for workflows that require more context. * `true` if tampering is detected through an anomalous browser signature, anti-detect browser detection, or other tampering-related methods * `false` if none of the tampering checks return a positive result | [optional] +**tampering_confidence** | [**TamperingConfidence**](TamperingConfidence.md) | | [optional] +**tampering_ml_score** | **float** | The output of this model is captured as tampering_ml_score, a number indicating how likely an event is coming from an anti detect browser. Values close to 1 signify higher confidence and we consider anything above the threshold of 0.8 to be actionable (the result and anti_detect_browser fields conveniently captures that fact) | [optional] +**tampering_details** | [**TamperingDetails**](TamperingDetails.md) | | [optional] +**velocity** | [**Velocity**](Velocity.md) | | [optional] +**virtual_machine** | **bool** | `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. | [optional] +**virtual_machine_ml_score** | **float** | Machine learning–based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] +**vpn_ml_score** | **float** | Machine learning–based VPN score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `vpn` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] +**vpn_origin_timezone** | **str** | Local timezone which is used in timezone_mismatch method. | [optional] +**vpn_origin_country** | **str** | Country of the request (Android SDK version >= 2.4.0, iOS SDK version >= 2.9.0, JS agent >= 3.12.9 / 4.0.2), ISO 3166 format or unknown. | [optional] +**high_activity_device** | **bool** | Flag indicating if the request came from a high-activity visitor. | [optional] +**rare_device** | **bool** | `true` if the device is considered rare based on its combination of hardware and software attributes. A device is classified as rare if it falls within the top 99.9 percentile (lowest-frequency segment) of observed traffic, or if its configuration has not been previously seen (`not_seen`). > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] +**rare_device_percentile_bucket** | [**RareDevicePercentileBucket**](RareDevicePercentileBucket.md) | | [optional] +**raw_device_attributes** | [**RawDeviceAttributes**](RawDeviceAttributes.md) | | [optional] +**labels** | [**List[LabelsInner]**](LabelsInner.md) | Each label returns a prediction (true or false) for a specific use case (label field) based on a machine learning score. The machine learning score is determined by a model trained on customer data for that use case. This field is in the beta phase and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/docs/EventEdge.md b/docs/EventEdge.md new file mode 100644 index 00000000..87e12dcd --- /dev/null +++ b/docs/EventEdge.md @@ -0,0 +1,24 @@ +# EventEdge +IP and bot analysis for an event generated by the Automation Intelligence API (`/edge` endpoint). No client-side collection agent is involved, so Identification (`visitor_id`) and device-telemetry-derived Smart Signals are not available. + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**event_id** | **str** | Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. | +**timestamp** | **int** | Timestamp of the event with millisecond precision in Unix time. | +**linked_id** | **str** | A customer-provided id that was sent with the request. | [optional] +**tags** | **Dict[str, object]** | A customer-provided value or an object that was sent with the identification request or updated later. | [optional] +**url** | **str** | Page URL from which the request was sent. | [optional] +**bot_info** | [**BotInfo**](BotInfo.md) | | [optional] +**ip_info** | [**IPInfo**](IPInfo.md) | | +**proxy** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy | [optional] +**proxy_confidence** | [**ProxyConfidence**](ProxyConfidence.md) | | [optional] +**proxy_details** | [**ProxyDetails**](ProxyDetails.md) | | [optional] +**vpn** | **bool** | VPN or other anonymizing service has been used when sending the request. | [optional] +**vpn_confidence** | [**VpnConfidence**](VpnConfidence.md) | | [optional] +**vpn_methods** | [**VpnMethods**](VpnMethods.md) | | [optional] +**source** | [**EventSource**](EventSource.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/docs/FingerprintApi.md b/docs/FingerprintApi.md index 785d4333..f7eeb673 100644 --- a/docs/FingerprintApi.md +++ b/docs/FingerprintApi.md @@ -4,12 +4,105 @@ All URIs are relative to *https://api.fpjs.io/v4* Method | HTTP request | Description ------------- | ------------- | ------------- +[**analyze_request_for_automation_intelligence**](FingerprintApi.md#analyze_request_for_automation_intelligence) | **POST** /edge | Collect Automation Intelligence. [**delete_visitor_data**](FingerprintApi.md#delete_visitor_data) | **DELETE** /visitors/{visitor_id} | Delete a visitor ID [**get_event**](FingerprintApi.md#get_event) | **GET** /events/{event_id} | Get an event by event ID [**search_events**](FingerprintApi.md#search_events) | **GET** /events | Search events [**update_event**](FingerprintApi.md#update_event) | **PATCH** /events/{event_id} | Update an event +# **analyze_request_for_automation_intelligence** +> EventEdge analyze_request_for_automation_intelligence(edge_request) + +Collect Automation Intelligence. + +The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. + +This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). + +The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. + +Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. + +The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. + +Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. + +### Event Retrieval + +Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. + +Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + + +### Example + +```python +import os + +import fingerprint_server_sdk +from fingerprint_server_sdk.models.edge_request import EdgeRequest +from fingerprint_server_sdk.models.event_edge import EventEdge +from fingerprint_server_sdk import ApiException, ErrorResponse +from fingerprint_server_sdk.configuration import Region +from pprint import pprint + +# Configure API key authorization and region +configuration = fingerprint_server_sdk.Configuration( + api_key = os.environ["SECRET_API_KEY"], + region = Region.US +) + +# Create an instance of the API class +api_instance = fingerprint_server_sdk.FingerprintApi(configuration) + +edge_request: EdgeRequest = fingerprint_server_sdk.EdgeRequest() # + +try: + # Collect Automation Intelligence. + api_response = api_instance.analyze_request_for_automation_intelligence(edge_request) + print("The response of FingerprintApi->analyze_request_for_automation_intelligence:\n") + pprint(api_response) +except ApiException as e: + if e.body is not None: + error_response = ErrorResponse.from_json(e.body) + if error_response is not None: + message = f"API request failed: {error_response.error.code} {error_response.error.message}" + else: + message = f"API request failed with unexpected error format: {e}" + else: + message = f'Exception when calling FingerprintApi->analyze_request_for_automation_intelligence: {e}' + print(message) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **edge_request** | [**EdgeRequest**](EdgeRequest.md)| | + +### Return type + +[**EventEdge**](EventEdge.md) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | OK. | - | +**400** | Bad request. The request payload is not valid. | - | +**403** | Forbidden. Access to this API is denied. | - | +**413** | Bad request. The request payload is too large. | - | +**429** | Too Many Requests. The request is throttled. | - | +**500** | Workspace error. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **delete_visitor_data** > delete_visitor_data(visitor_id) @@ -63,7 +156,7 @@ configuration = fingerprint_server_sdk.Configuration( # Create an instance of the API class api_instance = fingerprint_server_sdk.FingerprintApi(configuration) -visitor_id: str = 'Ibk1527CUFmcnjLwIs4A9' # The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. +visitor_id: str = 'Ibk1527CUFmcnjLwIs4A9' # The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. try: # Delete a visitor ID @@ -84,7 +177,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **visitor_id** | **str**| The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. | + **visitor_id** | **str**| The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. | ### Return type @@ -112,10 +205,12 @@ void (empty response body) Get an event by event ID -Get a detailed analysis of an individual identification event, including Smart Signals. +Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. +Returns `EventDevice` when `source` is `device`, and `EventEdge` when `source` is `edge`. + ### Example @@ -137,7 +232,7 @@ configuration = fingerprint_server_sdk.Configuration( # Create an instance of the API class api_instance = fingerprint_server_sdk.FingerprintApi(configuration) -event_id: str = '1708102555327.NLOjmg' # The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). +event_id: str = '1708102555327.NLOjmg' # The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). ruleset_id: str = 'D6N9Kbk9HRWrIWGz' # The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. (optional) try: @@ -161,7 +256,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **event_id** | **str**| The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). | + **event_id** | **str**| The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). | **ruleset_id** | **str**| The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. | [optional] ### Return type @@ -188,7 +283,7 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **search_events** -> EventSearch search_events(limit=limit, pagination_key=pagination_key, visitor_id=visitor_id, high_recall_id=high_recall_id, bot=bot, bot_info=bot_info, bot_info_category=bot_info_category, bot_info_identity=bot_info_identity, bot_info_confidence=bot_info_confidence, bot_info_provider=bot_info_provider, bot_info_name=bot_info_name, ip_address=ip_address, asn=asn, linked_id=linked_id, url=url, bundle_id=bundle_id, package_name=package_name, origin=origin, start=start, end=end, reverse=reverse, suspect=suspect, vpn=vpn, virtual_machine=virtual_machine, tampering=tampering, anti_detect_browser=anti_detect_browser, incognito=incognito, privacy_settings=privacy_settings, jailbroken=jailbroken, frida=frida, factory_reset=factory_reset, cloned_app=cloned_app, emulator=emulator, root_apps=root_apps, vpn_confidence=vpn_confidence, min_suspect_score=min_suspect_score, developer_tools=developer_tools, location_spoofing=location_spoofing, mitm_attack=mitm_attack, rare_device=rare_device, rare_device_percentile_bucket=rare_device_percentile_bucket, proxy=proxy, sdk_version=sdk_version, sdk_platform=sdk_platform, environment=environment, proximity_id=proximity_id, total_hits=total_hits, tor_node=tor_node, incremental_identification_status=incremental_identification_status, simulator=simulator, source=source, active_call=active_call) +> EventSearch search_events(limit=limit, pagination_key=pagination_key, visitor_id=visitor_id, high_recall_id=high_recall_id, bot=bot, bot_info=bot_info, bot_info_category=bot_info_category, bot_info_identity=bot_info_identity, bot_info_confidence=bot_info_confidence, bot_info_provider=bot_info_provider, bot_info_name=bot_info_name, ip_address=ip_address, asn=asn, linked_id=linked_id, url=url, bundle_id=bundle_id, package_name=package_name, origin=origin, start=start, end=end, reverse=reverse, suspect=suspect, vpn=vpn, virtual_machine=virtual_machine, tampering=tampering, anti_detect_browser=anti_detect_browser, incognito=incognito, privacy_settings=privacy_settings, jailbroken=jailbroken, frida=frida, factory_reset=factory_reset, cloned_app=cloned_app, emulator=emulator, root_apps=root_apps, vpn_confidence=vpn_confidence, min_suspect_score=min_suspect_score, developer_tools=developer_tools, location_spoofing=location_spoofing, mitm_attack=mitm_attack, rare_device=rare_device, rare_device_percentile_bucket=rare_device_percentile_bucket, proxy=proxy, sdk_version=sdk_version, sdk_platform=sdk_platform, environment=environment, proximity_id=proximity_id, total_hits=total_hits, tor_node=tor_node, incremental_identification_status=incremental_identification_status, simulator=simulator, active_call=active_call, source=source) Search events @@ -252,7 +347,7 @@ api_instance = fingerprint_server_sdk.FingerprintApi(configuration) limit: int = 10 # Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. (optional) pagination_key: str = 'S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q' # Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` (optional) -visitor_id: str = 'Ibk1527CUFmcnjLwIs4A9' # Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). (optional) +visitor_id: str = 'Ibk1527CUFmcnjLwIs4A9' # Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). (optional) high_recall_id: str = 'Ibk1527CUFmcnjLwIs4A9' # The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). (optional) bot: SearchEventsBot = fingerprint_server_sdk.SearchEventsBot() # Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. (optional) bot_info: SearchEventsBotInfo = fingerprint_server_sdk.SearchEventsBotInfo() # Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. (optional) @@ -263,7 +358,7 @@ bot_info_provider: List[str] = ['bot_info_provider_example'] # Filter events by bot_info_name: List[str] = ['bot_info_name_example'] # Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. (optional) ip_address: str = '61.127.217.15' # Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 (optional) asn: str = '12876' # Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. (optional) -linked_id: str = 'somelinkedId' # Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. (optional) +linked_id: str = 'somelinkedId' # Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. (optional) url: str = 'https://example.com/login' # Filter events by the URL (`url` property) associated with the event. (optional) bundle_id: str = 'com.example.app' # Filter events by the Bundle ID (iOS) associated with the event. (optional) package_name: str = 'com.example.app' # Filter events by the Package Name (Android) associated with the event. (optional) @@ -300,12 +395,12 @@ total_hits: int = 100 # When set, the response will include a `total_hits` prope tor_node: bool = True # Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. (optional) incremental_identification_status: SearchEventsIncrementalIdentificationStatus = fingerprint_server_sdk.SearchEventsIncrementalIdentificationStatus() # Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. (optional) simulator: bool = True # Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. (optional) -source: List[SearchEventsSource] = [fingerprint_server_sdk.SearchEventsSource()] # Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. (optional) active_call: bool = True # Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. (optional) +source: List[SearchEventsSource] = [fingerprint_server_sdk.SearchEventsSource()] # Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. (optional) try: # Search events - api_response = api_instance.search_events(limit=limit, pagination_key=pagination_key, visitor_id=visitor_id, high_recall_id=high_recall_id, bot=bot, bot_info=bot_info, bot_info_category=bot_info_category, bot_info_identity=bot_info_identity, bot_info_confidence=bot_info_confidence, bot_info_provider=bot_info_provider, bot_info_name=bot_info_name, ip_address=ip_address, asn=asn, linked_id=linked_id, url=url, bundle_id=bundle_id, package_name=package_name, origin=origin, start=start, end=end, reverse=reverse, suspect=suspect, vpn=vpn, virtual_machine=virtual_machine, tampering=tampering, anti_detect_browser=anti_detect_browser, incognito=incognito, privacy_settings=privacy_settings, jailbroken=jailbroken, frida=frida, factory_reset=factory_reset, cloned_app=cloned_app, emulator=emulator, root_apps=root_apps, vpn_confidence=vpn_confidence, min_suspect_score=min_suspect_score, developer_tools=developer_tools, location_spoofing=location_spoofing, mitm_attack=mitm_attack, rare_device=rare_device, rare_device_percentile_bucket=rare_device_percentile_bucket, proxy=proxy, sdk_version=sdk_version, sdk_platform=sdk_platform, environment=environment, proximity_id=proximity_id, total_hits=total_hits, tor_node=tor_node, incremental_identification_status=incremental_identification_status, simulator=simulator, source=source, active_call=active_call) + api_response = api_instance.search_events(limit=limit, pagination_key=pagination_key, visitor_id=visitor_id, high_recall_id=high_recall_id, bot=bot, bot_info=bot_info, bot_info_category=bot_info_category, bot_info_identity=bot_info_identity, bot_info_confidence=bot_info_confidence, bot_info_provider=bot_info_provider, bot_info_name=bot_info_name, ip_address=ip_address, asn=asn, linked_id=linked_id, url=url, bundle_id=bundle_id, package_name=package_name, origin=origin, start=start, end=end, reverse=reverse, suspect=suspect, vpn=vpn, virtual_machine=virtual_machine, tampering=tampering, anti_detect_browser=anti_detect_browser, incognito=incognito, privacy_settings=privacy_settings, jailbroken=jailbroken, frida=frida, factory_reset=factory_reset, cloned_app=cloned_app, emulator=emulator, root_apps=root_apps, vpn_confidence=vpn_confidence, min_suspect_score=min_suspect_score, developer_tools=developer_tools, location_spoofing=location_spoofing, mitm_attack=mitm_attack, rare_device=rare_device, rare_device_percentile_bucket=rare_device_percentile_bucket, proxy=proxy, sdk_version=sdk_version, sdk_platform=sdk_platform, environment=environment, proximity_id=proximity_id, total_hits=total_hits, tor_node=tor_node, incremental_identification_status=incremental_identification_status, simulator=simulator, active_call=active_call, source=source) print("The response of FingerprintApi->search_events:\n") pprint(api_response) except ApiException as e: @@ -326,7 +421,7 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **limit** | **int**| Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. | [optional] **pagination_key** | **str**| Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` | [optional] - **visitor_id** | **str**| Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). | [optional] + **visitor_id** | **str**| Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). | [optional] **high_recall_id** | **str**| The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). | [optional] **bot** | [**SearchEventsBot**](.md)| Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. | [optional] **bot_info** | [**SearchEventsBotInfo**](.md)| Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. | [optional] @@ -337,7 +432,7 @@ Name | Type | Description | Notes **bot_info_name** | [**List[str]**](str.md)| Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. | [optional] **ip_address** | **str**| Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 | [optional] **asn** | **str**| Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. | [optional] - **linked_id** | **str**| Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. | [optional] + **linked_id** | **str**| Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. | [optional] **url** | **str**| Filter events by the URL (`url` property) associated with the event. | [optional] **bundle_id** | **str**| Filter events by the Bundle ID (iOS) associated with the event. | [optional] **package_name** | **str**| Filter events by the Package Name (Android) associated with the event. | [optional] @@ -374,8 +469,8 @@ Name | Type | Description | Notes **tor_node** | **bool**| Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. | [optional] **incremental_identification_status** | [**SearchEventsIncrementalIdentificationStatus**](.md)| Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. | [optional] **simulator** | **bool**| Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. | [optional] - **source** | [**List[SearchEventsSource]**](SearchEventsSource.md)| Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. | [optional] **active_call** | **bool**| Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. | [optional] + **source** | [**List[SearchEventsSource]**](SearchEventsSource.md)| Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. | [optional] ### Return type @@ -436,7 +531,7 @@ configuration = fingerprint_server_sdk.Configuration( # Create an instance of the API class api_instance = fingerprint_server_sdk.FingerprintApi(configuration) -event_id: str = '1708102555327.NLOjmg' # The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). +event_id: str = '1708102555327.NLOjmg' # The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). event_update: EventUpdate = fingerprint_server_sdk.EventUpdate() # try: @@ -458,7 +553,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **event_id** | **str**| The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). | + **event_id** | **str**| The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). | **event_update** | [**EventUpdate**](EventUpdate.md)| | ### Return type diff --git a/examples/get_event_example.py b/examples/get_event_example.py index f308d752..7c90b47e 100644 --- a/examples/get_event_example.py +++ b/examples/get_event_example.py @@ -33,6 +33,8 @@ event = api_instance.get_event(event_id, ruleset_id) print(f'Event ID: {event.event_id}') print(f'Timestamp: {event.timestamp}') + # SPIKE INTER-2457 — RUNTIME BREAK. Event has no `identification` or `event_id`. + # Those live on event.actual_instance (EventDevice | EventEdge). if event.identification: print(f'Visitor ID: {event.identification.visitor_id}') if event.identification.confidence is not None: diff --git a/examples/search_events_example.py b/examples/search_events_example.py index 181587b4..809dc884 100644 --- a/examples/search_events_example.py +++ b/examples/search_events_example.py @@ -30,6 +30,8 @@ print(f'Found {len(response.events)} events') for event in response.events: + # SPIKE INTER-2457 — RUNTIME BREAK. Search hits are Event oneOf wrappers. + # `event.identification` raises AttributeError. event_visitor_id = event.identification.visitor_id if event.identification else '-' print(f'Event ID: {event.event_id}, Visitor ID: {event_visitor_id}') diff --git a/fingerprint_server_sdk/__init__.py b/fingerprint_server_sdk/__init__.py index afa630bd..4de023d5 100644 --- a/fingerprint_server_sdk/__init__.py +++ b/fingerprint_server_sdk/__init__.py @@ -12,98 +12,101 @@ Do not edit the class manually. """ # noqa: E501 - __version__ = '9.7.1' # Define package exports __all__ = [ - '__version__', - 'FingerprintApi', - 'ApiResponse', - 'ApiClient', - 'Configuration', - 'OpenApiException', - 'ApiTypeError', - 'ApiValueError', - 'ApiKeyError', - 'ApiAttributeError', - 'ApiException', - 'BadRequestException', - 'UnauthorizedException', - 'ForbiddenException', - 'NotFoundException', - 'ConflictException', - 'UnprocessableEntityException', - 'TooManyRequestsException', - 'ServiceException', - 'GatewayTimeoutException', - 'WebhookValidation', - 'DecryptionKey', - 'DecryptionAlgorithm', - 'UnsealError', - 'UnsealAggregateError', - 'unseal_event_response', - 'BotInfo', - 'BotInfoCategory', - 'BotInfoConfidence', - 'BotInfoIdentity', - 'BotResult', - 'BrowserDetails', - 'Canvas', - 'Emoji', - 'Error', - 'ErrorCode', - 'ErrorResponse', - 'Event', - 'EventRuleAction', - 'EventRuleActionAllow', - 'EventRuleActionBlock', - 'EventSearch', - 'EventSource', - 'EventUpdate', - 'FontPreferences', - 'Geolocation', - 'GeolocationSubdivisionsInner', - 'IPBlockList', - 'IPInfo', - 'IPInfoV4', - 'IPInfoV6', - 'Identification', - 'IdentificationConfidence', - 'IncrementalIdentificationStatus', - 'Integration', - 'IntegrationSubintegration', - 'LabelsInner', - 'PluginsInner', - 'PluginsInnerMimeTypesInner', - 'Proximity', - 'ProxyConfidence', - 'ProxyDetails', - 'RareDevicePercentileBucket', - 'RawDeviceAttributes', - 'RequestHeaderModifications', - 'RuleActionHeaderField', - 'RuleActionType', - 'SDK', - 'SearchEventsBot', - 'SearchEventsBotInfo', - 'SearchEventsEndParameter', - 'SearchEventsIncrementalIdentificationStatus', - 'SearchEventsRareDevicePercentileBucket', - 'SearchEventsSdkPlatform', - 'SearchEventsSource', - 'SearchEventsStartParameter', - 'SearchEventsVpnConfidence', - 'SupplementaryIDHighRecall', - 'TamperingConfidence', - 'TamperingDetails', - 'TouchSupport', - 'Velocity', - 'VelocityData', - 'VpnConfidence', - 'VpnMethods', - 'WebGlBasics', - 'WebGlExtensions', + "__version__", + "FingerprintApi", + "ApiResponse", + "ApiClient", + "Configuration", + "OpenApiException", + "ApiTypeError", + "ApiValueError", + "ApiKeyError", + "ApiAttributeError", + "ApiException", + "BadRequestException", + "UnauthorizedException", + "ForbiddenException", + "NotFoundException", + "ConflictException", + "UnprocessableEntityException", + "TooManyRequestsException", + "ServiceException", + "GatewayTimeoutException", + "WebhookValidation", + "DecryptionKey", + "DecryptionAlgorithm", + "UnsealError", + "UnsealAggregateError", + "unseal_event_response", + "BotInfo", + "BotInfoCategory", + "BotInfoConfidence", + "BotInfoIdentity", + "BotResult", + "BrowserDetails", + "Canvas", + "EdgeRequest", + "EdgeRequestHeadersInner", + "Emoji", + "Error", + "ErrorCode", + "ErrorResponse", + "Event", + "EventDevice", + "EventEdge", + "EventRuleAction", + "EventRuleActionAllow", + "EventRuleActionBlock", + "EventSearch", + "EventSource", + "EventUpdate", + "FontPreferences", + "Geolocation", + "GeolocationSubdivisionsInner", + "IPBlockList", + "IPInfo", + "IPInfoV4", + "IPInfoV6", + "Identification", + "IdentificationConfidence", + "IncrementalIdentificationStatus", + "Integration", + "IntegrationSubintegration", + "LabelsInner", + "PluginsInner", + "PluginsInnerMimeTypesInner", + "Proximity", + "ProxyConfidence", + "ProxyDetails", + "RareDevicePercentileBucket", + "RawDeviceAttributes", + "RequestHeaderModifications", + "RuleActionHeaderField", + "RuleActionType", + "SDK", + "SearchEventsBot", + "SearchEventsBotInfo", + "SearchEventsEndParameter", + "SearchEventsIncrementalIdentificationStatus", + "SearchEventsRareDevicePercentileBucket", + "SearchEventsSdkPlatform", + "SearchEventsSource", + "SearchEventsStartParameter", + "SearchEventsVpnConfidence", + "SupplementaryIDHighRecall", + "TamperingConfidence", + "TamperingDetails", + "TouchSupport", + "Velocity", + "VelocityData", + "VpnConfidence", + "VpnMethods", + "WebGlBasics", + "WebGlExtensions", ] # import apis into sdk package @@ -137,11 +140,15 @@ from fingerprint_server_sdk.models.bot_result import BotResult from fingerprint_server_sdk.models.browser_details import BrowserDetails from fingerprint_server_sdk.models.canvas import Canvas +from fingerprint_server_sdk.models.edge_request import EdgeRequest +from fingerprint_server_sdk.models.edge_request_headers_inner import EdgeRequestHeadersInner from fingerprint_server_sdk.models.emoji import Emoji from fingerprint_server_sdk.models.error import Error from fingerprint_server_sdk.models.error_code import ErrorCode from fingerprint_server_sdk.models.error_response import ErrorResponse from fingerprint_server_sdk.models.event import Event +from fingerprint_server_sdk.models.event_device import EventDevice +from fingerprint_server_sdk.models.event_edge import EventEdge from fingerprint_server_sdk.models.event_rule_action import EventRuleAction from fingerprint_server_sdk.models.event_rule_action_allow import EventRuleActionAllow from fingerprint_server_sdk.models.event_rule_action_block import EventRuleActionBlock @@ -150,18 +157,14 @@ from fingerprint_server_sdk.models.event_update import EventUpdate from fingerprint_server_sdk.models.font_preferences import FontPreferences from fingerprint_server_sdk.models.geolocation import Geolocation -from fingerprint_server_sdk.models.geolocation_subdivisions_inner import ( - GeolocationSubdivisionsInner, -) +from fingerprint_server_sdk.models.geolocation_subdivisions_inner import GeolocationSubdivisionsInner from fingerprint_server_sdk.models.ip_block_list import IPBlockList from fingerprint_server_sdk.models.ip_info import IPInfo from fingerprint_server_sdk.models.ip_info_v4 import IPInfoV4 from fingerprint_server_sdk.models.ip_info_v6 import IPInfoV6 from fingerprint_server_sdk.models.identification import Identification from fingerprint_server_sdk.models.identification_confidence import IdentificationConfidence -from fingerprint_server_sdk.models.incremental_identification_status import ( - IncrementalIdentificationStatus, -) +from fingerprint_server_sdk.models.incremental_identification_status import IncrementalIdentificationStatus from fingerprint_server_sdk.models.integration import Integration from fingerprint_server_sdk.models.integration_subintegration import IntegrationSubintegration from fingerprint_server_sdk.models.labels_inner import LabelsInner @@ -179,12 +182,8 @@ from fingerprint_server_sdk.models.search_events_bot import SearchEventsBot from fingerprint_server_sdk.models.search_events_bot_info import SearchEventsBotInfo from fingerprint_server_sdk.models.search_events_end_parameter import SearchEventsEndParameter -from fingerprint_server_sdk.models.search_events_incremental_identification_status import ( - SearchEventsIncrementalIdentificationStatus, -) -from fingerprint_server_sdk.models.search_events_rare_device_percentile_bucket import ( - SearchEventsRareDevicePercentileBucket, -) +from fingerprint_server_sdk.models.search_events_incremental_identification_status import SearchEventsIncrementalIdentificationStatus +from fingerprint_server_sdk.models.search_events_rare_device_percentile_bucket import SearchEventsRareDevicePercentileBucket from fingerprint_server_sdk.models.search_events_sdk_platform import SearchEventsSdkPlatform from fingerprint_server_sdk.models.search_events_source import SearchEventsSource from fingerprint_server_sdk.models.search_events_start_parameter import SearchEventsStartParameter @@ -199,7 +198,6 @@ from fingerprint_server_sdk.models.vpn_methods import VpnMethods from fingerprint_server_sdk.models.web_gl_basics import WebGlBasics from fingerprint_server_sdk.models.web_gl_extensions import WebGlExtensions - # import custom methods into sdk package from fingerprint_server_sdk.sealed import ( DecryptionAlgorithm, diff --git a/fingerprint_server_sdk/api/fingerprint_api.py b/fingerprint_server_sdk/api/fingerprint_api.py index eb22c9f2..8a3ebf31 100644 --- a/fingerprint_server_sdk/api/fingerprint_api.py +++ b/fingerprint_server_sdk/api/fingerprint_api.py @@ -11,47 +11,40 @@ Do not edit the class manually. """ # noqa: E501 -from datetime import date, datetime -from typing import Annotated, Any, Optional, Union # noqa: UP035 +from typing import Any, Optional, Union # noqa: UP035 from pydantic import Field, StrictBool, StrictFloat, StrictInt, StrictStr, validate_call +from typing_extensions import Annotated -from fingerprint_server_sdk.api_client import ApiClient, RequestSerialized -from fingerprint_server_sdk.api_response import ApiResponse -from fingerprint_server_sdk.configuration import Configuration +from pydantic import Field, StrictBool, StrictFloat, StrictInt, StrictStr +from typing import Any, List, Optional, Union +from typing_extensions import Annotated from fingerprint_server_sdk.models.bot_info_category import BotInfoCategory from fingerprint_server_sdk.models.bot_info_confidence import BotInfoConfidence from fingerprint_server_sdk.models.bot_info_identity import BotInfoIdentity +from fingerprint_server_sdk.models.edge_request import EdgeRequest from fingerprint_server_sdk.models.event import Event +from fingerprint_server_sdk.models.event_edge import EventEdge from fingerprint_server_sdk.models.event_search import EventSearch from fingerprint_server_sdk.models.event_update import EventUpdate from fingerprint_server_sdk.models.search_events_bot import SearchEventsBot from fingerprint_server_sdk.models.search_events_bot_info import SearchEventsBotInfo -from fingerprint_server_sdk.models.search_events_end_parameter import SearchEventsEndParameter -from fingerprint_server_sdk.models.search_events_incremental_identification_status import ( - SearchEventsIncrementalIdentificationStatus, -) -from fingerprint_server_sdk.models.search_events_rare_device_percentile_bucket import ( - SearchEventsRareDevicePercentileBucket, -) +from fingerprint_server_sdk.models.search_events_incremental_identification_status import SearchEventsIncrementalIdentificationStatus +from fingerprint_server_sdk.models.search_events_rare_device_percentile_bucket import SearchEventsRareDevicePercentileBucket from fingerprint_server_sdk.models.search_events_sdk_platform import SearchEventsSdkPlatform from fingerprint_server_sdk.models.search_events_source import SearchEventsSource -from fingerprint_server_sdk.models.search_events_start_parameter import SearchEventsStartParameter from fingerprint_server_sdk.models.search_events_vpn_confidence import SearchEventsVpnConfidence +from fingerprint_server_sdk.models.search_events_start_parameter import SearchEventsStartParameter +from datetime import datetime, date, timezone +from fingerprint_server_sdk.models.search_events_end_parameter import SearchEventsEndParameter +from datetime import datetime, date, timezone +from fingerprint_server_sdk.api_client import ApiClient, RequestSerialized +from fingerprint_server_sdk.api_response import ApiResponse +from fingerprint_server_sdk.configuration import Configuration from fingerprint_server_sdk.rest import RESTResponseType # Type alias for query and form parameter values -ParamValue = Union[ - list[BotInfoCategory], - list[BotInfoIdentity], - list[BotInfoConfidence], - list[SearchEventsSource], - str, - int, - float, - bool, - list[str], -] +ParamValue = Union[list[BotInfoCategory], list[BotInfoIdentity], list[BotInfoConfidence], list[SearchEventsSource], str, int, float, bool, list[str]] class FingerprintApi: @@ -65,19 +58,289 @@ class FingerprintApi: def __init__(self, configuration: Configuration) -> None: self.api_client = ApiClient(configuration) + + @validate_call + def analyze_request_for_automation_intelligence( + self, + edge_request: EdgeRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[dict[StrictStr, Any]] = None, + ) -> EventEdge: + """Collect Automation Intelligence. + + The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. ### Event Retrieval Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + + :param edge_request: (required) + :type edge_request: EdgeRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._analyze_request_for_automation_intelligence_serialize( + edge_request=edge_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + ) + + _response_types_map: dict[str, Optional[str]] = { + '200': "EventEdge", + '400': "ErrorResponse", + '403': "ErrorResponse", + '413': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + } + + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def analyze_request_for_automation_intelligence_with_http_info( + self, + edge_request: EdgeRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[dict[StrictStr, Any]] = None, + ) -> ApiResponse[EventEdge]: + """Collect Automation Intelligence. + + The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. ### Event Retrieval Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + + :param edge_request: (required) + :type edge_request: EdgeRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._analyze_request_for_automation_intelligence_serialize( + edge_request=edge_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + ) + + _response_types_map: dict[str, Optional[str]] = { + '200': "EventEdge", + '400': "ErrorResponse", + '403': "ErrorResponse", + '413': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + } + + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def analyze_request_for_automation_intelligence_without_preload_content( + self, + edge_request: EdgeRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[dict[StrictStr, Any]] = None, + ) -> RESTResponseType: + """Collect Automation Intelligence. + + The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. ### Event Retrieval Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + + :param edge_request: (required) + :type edge_request: EdgeRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._analyze_request_for_automation_intelligence_serialize( + edge_request=edge_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + ) + + _response_types_map: dict[str, Optional[str]] = { + '200': "EventEdge", + '400': "ErrorResponse", + '403': "ErrorResponse", + '413': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + } + + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _analyze_request_for_automation_intelligence_serialize( + self, + edge_request: EdgeRequest, + _request_auth: Optional[dict[StrictStr, Any]], + _content_type: Optional[StrictStr], + _headers: Optional[dict[StrictStr, Any]], + ) -> RequestSerialized: + + _collection_formats: dict[str, str] = { + } + + _path_params: dict[str, str] = {} + _query_params: list[tuple[str, ParamValue]] = [] + _header_params: dict[str, Optional[str]] = _headers or {} + _form_params: list[tuple[str, ParamValue]] = [] + _files: dict[ + str, + Union[str, bytes, list[str], list[bytes], tuple[str, bytes], list[tuple[str, bytes]]], + ] = {} + _body_params: Optional[Any] = None + + + + + + # process the body parameter + if edge_request is not None: + _body_params = edge_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: list[str] = [ + 'bearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/edge', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _request_auth=_request_auth, + ) + + + + @validate_call def delete_visitor_data( self, - visitor_id: Annotated[ - StrictStr, - Field( - description='The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete.' - ), - ], + visitor_id: Annotated[StrictStr, Field(description="The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete.")], _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -85,9 +348,9 @@ def delete_visitor_data( ) -> None: """Delete a visitor ID - Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). + Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). - :param visitor_id: The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. (required) + :param visitor_id: The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. (required) :type visitor_id: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -105,7 +368,7 @@ def delete_visitor_data( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._delete_visitor_data_serialize( visitor_id=visitor_id, @@ -116,32 +379,34 @@ def delete_visitor_data( _response_types_map: dict[str, Optional[str]] = { '200': None, - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) response_data.read() self.api_client.response_deserialize( response_data=response_data, response_types_map=_response_types_map, ) + @validate_call def delete_visitor_data_with_http_info( self, - visitor_id: Annotated[ - StrictStr, - Field( - description='The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete.' - ), - ], + visitor_id: Annotated[StrictStr, Field(description="The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete.")], _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -149,9 +414,9 @@ def delete_visitor_data_with_http_info( ) -> ApiResponse[None]: """Delete a visitor ID - Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). + Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). - :param visitor_id: The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. (required) + :param visitor_id: The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. (required) :type visitor_id: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -169,7 +434,7 @@ def delete_visitor_data_with_http_info( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._delete_visitor_data_serialize( visitor_id=visitor_id, @@ -180,32 +445,34 @@ def delete_visitor_data_with_http_info( _response_types_map: dict[str, Optional[str]] = { '200': None, - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) response_data.read() return self.api_client.response_deserialize( response_data=response_data, response_types_map=_response_types_map, ) + @validate_call def delete_visitor_data_without_preload_content( self, - visitor_id: Annotated[ - StrictStr, - Field( - description='The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete.' - ), - ], + visitor_id: Annotated[StrictStr, Field(description="The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete.")], _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -213,9 +480,9 @@ def delete_visitor_data_without_preload_content( ) -> RESTResponseType: """Delete a visitor ID - Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). + Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). - :param visitor_id: The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. (required) + :param visitor_id: The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. (required) :type visitor_id: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -233,7 +500,7 @@ def delete_visitor_data_without_preload_content( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._delete_visitor_data_serialize( visitor_id=visitor_id, @@ -244,15 +511,19 @@ def delete_visitor_data_without_preload_content( _response_types_map: dict[str, Optional[str]] = { '200': None, - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) return response_data.response + def _delete_visitor_data_serialize( self, visitor_id: str, @@ -261,7 +532,8 @@ def _delete_visitor_data_serialize( _headers: Optional[dict[StrictStr, Any]], ) -> RequestSerialized: - _collection_formats: dict[str, str] = {} + _collection_formats: dict[str, str] = { + } _path_params: dict[str, str] = {} _query_params: list[tuple[str, ParamValue]] = [] @@ -277,12 +549,24 @@ def _delete_visitor_data_serialize( if visitor_id is not None: _path_params['visitor_id'] = visitor_id + + + + + # set the HTTP header `Accept` if 'Accept' not in _header_params: - _header_params['Accept'] = self.api_client.select_header_accept(['application/json']) + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + # authentication setting - _auth_settings: list[str] = ['bearerAuth'] + _auth_settings: list[str] = [ + 'bearerAuth' + ] return self.api_client.param_serialize( method='DELETE', @@ -298,25 +582,24 @@ def _delete_visitor_data_serialize( _request_auth=_request_auth, ) + + + @validate_call + # SPIKE INTER-2457 — BREAKING CHANGE. DO NOT SHIP. + # Return type is still named Event, but Event is now a oneOf wrapper. + # `api.get_event(id).identification` raises AttributeError. def get_event( self, - event_id: Annotated[ - StrictStr, - Field( - description='The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place).' - ), - ], - ruleset_id: Annotated[ - Optional[StrictStr], - Field( - description='The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. ' - ), - ] = None, + event_id: Annotated[StrictStr, Field(description="The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place).")], + ruleset_id: Annotated[Optional[StrictStr], Field(description="The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -324,11 +607,11 @@ def get_event( ) -> Event: """Get an event by event ID - Get a detailed analysis of an individual identification event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. Returns `EventDevice` when `source` is `device`, and `EventEdge` when `source` is `edge`. - :param event_id: The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). (required) + :param event_id: The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). (required) :type event_id: str - :param ruleset_id: The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. + :param ruleset_id: The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. :type ruleset_id: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -346,7 +629,7 @@ def get_event( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_event_serialize( event_id=event_id, @@ -357,41 +640,38 @@ def get_event( ) _response_types_map: dict[str, Optional[str]] = { - '200': 'Event', - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', - '500': 'ErrorResponse', - '504': 'ErrorResponse', + '200': "Event", + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + '504': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) response_data.read() return self.api_client.response_deserialize( response_data=response_data, response_types_map=_response_types_map, ).data + @validate_call def get_event_with_http_info( self, - event_id: Annotated[ - StrictStr, - Field( - description='The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place).' - ), - ], - ruleset_id: Annotated[ - Optional[StrictStr], - Field( - description='The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. ' - ), - ] = None, + event_id: Annotated[StrictStr, Field(description="The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place).")], + ruleset_id: Annotated[Optional[StrictStr], Field(description="The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -399,11 +679,11 @@ def get_event_with_http_info( ) -> ApiResponse[Event]: """Get an event by event ID - Get a detailed analysis of an individual identification event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. Returns `EventDevice` when `source` is `device`, and `EventEdge` when `source` is `edge`. - :param event_id: The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). (required) + :param event_id: The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). (required) :type event_id: str - :param ruleset_id: The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. + :param ruleset_id: The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. :type ruleset_id: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -421,7 +701,7 @@ def get_event_with_http_info( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_event_serialize( event_id=event_id, @@ -432,41 +712,38 @@ def get_event_with_http_info( ) _response_types_map: dict[str, Optional[str]] = { - '200': 'Event', - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', - '500': 'ErrorResponse', - '504': 'ErrorResponse', + '200': "Event", + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + '504': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) response_data.read() return self.api_client.response_deserialize( response_data=response_data, response_types_map=_response_types_map, ) + @validate_call def get_event_without_preload_content( self, - event_id: Annotated[ - StrictStr, - Field( - description='The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place).' - ), - ], - ruleset_id: Annotated[ - Optional[StrictStr], - Field( - description='The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. ' - ), - ] = None, + event_id: Annotated[StrictStr, Field(description="The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place).")], + ruleset_id: Annotated[Optional[StrictStr], Field(description="The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -474,11 +751,11 @@ def get_event_without_preload_content( ) -> RESTResponseType: """Get an event by event ID - Get a detailed analysis of an individual identification event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. Returns `EventDevice` when `source` is `device`, and `EventEdge` when `source` is `edge`. - :param event_id: The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). (required) + :param event_id: The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). (required) :type event_id: str - :param ruleset_id: The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. + :param ruleset_id: The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. :type ruleset_id: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -496,7 +773,7 @@ def get_event_without_preload_content( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._get_event_serialize( event_id=event_id, @@ -507,18 +784,22 @@ def get_event_without_preload_content( ) _response_types_map: dict[str, Optional[str]] = { - '200': 'Event', - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', - '500': 'ErrorResponse', - '504': 'ErrorResponse', + '200': "Event", + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + '504': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) return response_data.response + def _get_event_serialize( self, event_id: str, @@ -528,7 +809,8 @@ def _get_event_serialize( _headers: Optional[dict[StrictStr, Any]], ) -> RequestSerialized: - _collection_formats: dict[str, str] = {} + _collection_formats: dict[str, str] = { + } _path_params: dict[str, str] = {} _query_params: list[tuple[str, ParamValue]] = [] @@ -546,14 +828,27 @@ def _get_event_serialize( # process the query parameters if ruleset_id is not None: + _query_params.append(('ruleset_id', ruleset_id)) + + + + + # set the HTTP header `Accept` if 'Accept' not in _header_params: - _header_params['Accept'] = self.api_client.select_header_accept(['application/json']) + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + # authentication setting - _auth_settings: list[str] = ['bearerAuth'] + _auth_settings: list[str] = [ + 'bearerAuth' + ] return self.api_client.param_serialize( method='GET', @@ -569,323 +864,71 @@ def _get_event_serialize( _request_auth=_request_auth, ) + + + @validate_call def search_events( self, - limit: Annotated[ - Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], - Field( - description='Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. ' - ), - ] = None, - pagination_key: Annotated[ - Optional[StrictStr], - Field( - description='Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` ' - ), - ] = None, - visitor_id: Annotated[ - Optional[StrictStr], - Field( - description='Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). ' - ), - ] = None, - high_recall_id: Annotated[ - Optional[StrictStr], - Field( - description='The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). ' - ), - ] = None, - bot: Annotated[ - Optional[SearchEventsBot], - Field( - description='Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. ' - ), - ] = None, - bot_info: Annotated[ - Optional[SearchEventsBotInfo], - Field( - description='Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. ' - ), - ] = None, - bot_info_category: Annotated[ - Optional[list[BotInfoCategory]], - Field( - description='Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_identity: Annotated[ - Optional[list[BotInfoIdentity]], - Field( - description='Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_confidence: Annotated[ - Optional[list[BotInfoConfidence]], - Field( - description='Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_provider: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_name: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - ip_address: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 ' - ), - ] = None, - asn: Annotated[ - Optional[StrictStr], - Field( - description="Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. " - ), - ] = None, - linked_id: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. ' - ), - ] = None, - url: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the URL (`url` property) associated with the event. ' - ), - ] = None, - bundle_id: Annotated[ - Optional[StrictStr], - Field(description='Filter events by the Bundle ID (iOS) associated with the event. '), - ] = None, - package_name: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the Package Name (Android) associated with the event. ' - ), - ] = None, - origin: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) ' - ), - ] = None, - start: Annotated[ - Optional[SearchEventsStartParameter], - Field( - description='Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. ', - ), - ] = None, - end: Annotated[ - Optional[SearchEventsEndParameter], - Field( - description='Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. ', - ), - ] = None, - reverse: Annotated[ - Optional[StrictBool], - Field( - description='When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). ' - ), - ] = None, - suspect: Annotated[ - Optional[StrictBool], - Field( - description='Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. ' - ), - ] = None, - vpn: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. ' - ), - ] = None, - virtual_machine: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. ' - ), - ] = None, - tampering: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ' - ), - ] = None, - anti_detect_browser: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ' - ), - ] = None, - incognito: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. ' - ), - ] = None, - privacy_settings: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. ' - ), - ] = None, - jailbroken: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. ' - ), - ] = None, - frida: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. ' - ), - ] = None, - factory_reset: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. ' - ), - ] = None, - cloned_app: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. ' - ), - ] = None, - emulator: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. ' - ), - ] = None, - root_apps: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. ' - ), - ] = None, - vpn_confidence: Annotated[ - Optional[SearchEventsVpnConfidence], - Field( - description='Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. ' - ), - ] = None, - min_suspect_score: Annotated[ - Optional[Union[StrictFloat, StrictInt]], - Field( - description='Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. ' - ), - ] = None, - developer_tools: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. ' - ), - ] = None, - location_spoofing: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. ' - ), - ] = None, - mitm_attack: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. ' - ), - ] = None, - rare_device: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ' - ), - ] = None, - rare_device_percentile_bucket: Annotated[ - Optional[SearchEventsRareDevicePercentileBucket], - Field( - description='Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ' - ), - ] = None, - proxy: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. ' - ), - ] = None, - sdk_version: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` ' - ), - ] = None, - sdk_platform: Annotated[ - Optional[SearchEventsSdkPlatform], - Field( - description='Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. ' - ), - ] = None, - environment: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. ' - ), - ] = None, - proximity_id: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. ' - ), - ] = None, - total_hits: Annotated[ - Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], - Field( - description='When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. ' - ), - ] = None, - tor_node: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. ' - ), - ] = None, - incremental_identification_status: Annotated[ - Optional[SearchEventsIncrementalIdentificationStatus], - Field( - description='Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. ' - ), - ] = None, - simulator: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. ' - ), - ] = None, - source: Annotated[ - Optional[Annotated[list[SearchEventsSource], Field(max_length=1)]], - Field( - description='Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. ' - ), - ] = None, - active_call: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. ' - ), - ] = None, + limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. ")] = None, + pagination_key: Annotated[Optional[StrictStr], Field(description="Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` ")] = None, + visitor_id: Annotated[Optional[StrictStr], Field(description="Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). ")] = None, + high_recall_id: Annotated[Optional[StrictStr], Field(description="The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). ")] = None, + bot: Annotated[Optional[SearchEventsBot], Field(description="Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. ")] = None, + bot_info: Annotated[Optional[SearchEventsBotInfo], Field(description="Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. ")] = None, + bot_info_category: Annotated[Optional[List[BotInfoCategory]], Field(description="Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_identity: Annotated[Optional[List[BotInfoIdentity]], Field(description="Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_confidence: Annotated[Optional[List[BotInfoConfidence]], Field(description="Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_provider: Annotated[Optional[List[StrictStr]], Field(description="Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_name: Annotated[Optional[List[StrictStr]], Field(description="Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + ip_address: Annotated[Optional[StrictStr], Field(description="Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 ")] = None, + asn: Annotated[Optional[StrictStr], Field(description="Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. ")] = None, + linked_id: Annotated[Optional[StrictStr], Field(description="Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. ")] = None, + url: Annotated[Optional[StrictStr], Field(description="Filter events by the URL (`url` property) associated with the event. ")] = None, + bundle_id: Annotated[Optional[StrictStr], Field(description="Filter events by the Bundle ID (iOS) associated with the event. ")] = None, + package_name: Annotated[Optional[StrictStr], Field(description="Filter events by the Package Name (Android) associated with the event. ")] = None, + origin: Annotated[Optional[StrictStr], Field(description="Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) ")] = None, + start: Annotated[Optional[SearchEventsStartParameter],Field(description="Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. ",)] = None, + end: Annotated[Optional[SearchEventsEndParameter],Field(description="Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. ",)] = None, + reverse: Annotated[Optional[StrictBool], Field(description="When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). ")] = None, + suspect: Annotated[Optional[StrictBool], Field(description="Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. ")] = None, + vpn: Annotated[Optional[StrictBool], Field(description="Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. ")] = None, + virtual_machine: Annotated[Optional[StrictBool], Field(description="Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. ")] = None, + tampering: Annotated[Optional[StrictBool], Field(description="Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ")] = None, + anti_detect_browser: Annotated[Optional[StrictBool], Field(description="Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ")] = None, + incognito: Annotated[Optional[StrictBool], Field(description="Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. ")] = None, + privacy_settings: Annotated[Optional[StrictBool], Field(description="Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. ")] = None, + jailbroken: Annotated[Optional[StrictBool], Field(description="Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. ")] = None, + frida: Annotated[Optional[StrictBool], Field(description="Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. ")] = None, + factory_reset: Annotated[Optional[StrictBool], Field(description="Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. ")] = None, + cloned_app: Annotated[Optional[StrictBool], Field(description="Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. ")] = None, + emulator: Annotated[Optional[StrictBool], Field(description="Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. ")] = None, + root_apps: Annotated[Optional[StrictBool], Field(description="Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. ")] = None, + vpn_confidence: Annotated[Optional[SearchEventsVpnConfidence], Field(description="Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. ")] = None, + min_suspect_score: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description="Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. ")] = None, + developer_tools: Annotated[Optional[StrictBool], Field(description="Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. ")] = None, + location_spoofing: Annotated[Optional[StrictBool], Field(description="Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. ")] = None, + mitm_attack: Annotated[Optional[StrictBool], Field(description="Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. ")] = None, + rare_device: Annotated[Optional[StrictBool], Field(description="Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ")] = None, + rare_device_percentile_bucket: Annotated[Optional[SearchEventsRareDevicePercentileBucket], Field(description="Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ")] = None, + proxy: Annotated[Optional[StrictBool], Field(description="Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. ")] = None, + sdk_version: Annotated[Optional[StrictStr], Field(description="Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` ")] = None, + sdk_platform: Annotated[Optional[SearchEventsSdkPlatform], Field(description="Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. ")] = None, + environment: Annotated[Optional[List[StrictStr]], Field(description="Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. ")] = None, + proximity_id: Annotated[Optional[StrictStr], Field(description="Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. ")] = None, + total_hits: Annotated[Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], Field(description="When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. ")] = None, + tor_node: Annotated[Optional[StrictBool], Field(description="Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. ")] = None, + incremental_identification_status: Annotated[Optional[SearchEventsIncrementalIdentificationStatus], Field(description="Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. ")] = None, + simulator: Annotated[Optional[StrictBool], Field(description="Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. ")] = None, + active_call: Annotated[Optional[StrictBool], Field(description="Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. ")] = None, + source: Annotated[Optional[Annotated[List[SearchEventsSource], Field(max_length=1)]], Field(description="Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -893,112 +936,112 @@ def search_events( ) -> EventSearch: """Search events - ## Search The `/v4/events` endpoint provides a convenient way to search for past events based on specific parameters. Typical use cases and queries include: - Searching for events associated with a single `visitor_id` within a time range to get historical behavior of a visitor. - Searching for events associated with a single `linked_id` within a time range to get all events associated with your internal account identifier. - Excluding all bot traffic from the query (`good` and `bad` bots) By default, the API searches events from the last 7 days, sorts them by newest first and returns the last 10 events. - Use `start` and `end` to specify the time range of the search. - Use `reverse=true` to sort the results oldest first. - Use `limit` to specify the number of events to return. - Use `pagination_key` to get the next page of results if there are more than `limit` events. ### Filtering events with the `suspect` flag The `/v4/events` endpoint unlocks a powerful method for fraud protection analytics. The `suspect` flag is exposed in all events where it was previously set by the update API. You can also apply the `suspect` query parameter as a filter to find all potentially fraudulent activity that you previously marked as `suspect`. This helps identify patterns of fraudulent behavior. ### Environment scoping If you use a secret key that is scoped to an environment, you will only get events associated with the same environment. With a workspace-scoped environment, you will get events from all environments. Smart Signals not activated for your workspace or are not included in the response. + ## Search The `/v4/events` endpoint provides a convenient way to search for past events based on specific parameters. Typical use cases and queries include: - Searching for events associated with a single `visitor_id` within a time range to get historical behavior of a visitor. - Searching for events associated with a single `linked_id` within a time range to get all events associated with your internal account identifier. - Excluding all bot traffic from the query (`good` and `bad` bots) By default, the API searches events from the last 7 days, sorts them by newest first and returns the last 10 events. - Use `start` and `end` to specify the time range of the search. - Use `reverse=true` to sort the results oldest first. - Use `limit` to specify the number of events to return. - Use `pagination_key` to get the next page of results if there are more than `limit` events. ### Filtering events with the `suspect` flag The `/v4/events` endpoint unlocks a powerful method for fraud protection analytics. The `suspect` flag is exposed in all events where it was previously set by the update API. You can also apply the `suspect` query parameter as a filter to find all potentially fraudulent activity that you previously marked as `suspect`. This helps identify patterns of fraudulent behavior. ### Environment scoping If you use a secret key that is scoped to an environment, you will only get events associated with the same environment. With a workspace-scoped environment, you will get events from all environments. Smart Signals not activated for your workspace or are not included in the response. - :param limit: Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. + :param limit: Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. :type limit: int - :param pagination_key: Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` + :param pagination_key: Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` :type pagination_key: str - :param visitor_id: Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). + :param visitor_id: Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). :type visitor_id: str - :param high_recall_id: The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). + :param high_recall_id: The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). :type high_recall_id: str - :param bot: Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. + :param bot: Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. :type bot: SearchEventsBot - :param bot_info: Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. + :param bot_info: Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. :type bot_info: SearchEventsBotInfo - :param bot_info_category: Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_category: Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_category: List[BotInfoCategory] - :param bot_info_identity: Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_identity: Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_identity: List[BotInfoIdentity] - :param bot_info_confidence: Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_confidence: Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_confidence: List[BotInfoConfidence] - :param bot_info_provider: Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_provider: Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_provider: List[str] - :param bot_info_name: Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_name: Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_name: List[str] - :param ip_address: Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 + :param ip_address: Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 :type ip_address: str - :param asn: Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. + :param asn: Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. :type asn: str - :param linked_id: Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. + :param linked_id: Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. :type linked_id: str - :param url: Filter events by the URL (`url` property) associated with the event. + :param url: Filter events by the URL (`url` property) associated with the event. :type url: str - :param bundle_id: Filter events by the Bundle ID (iOS) associated with the event. + :param bundle_id: Filter events by the Bundle ID (iOS) associated with the event. :type bundle_id: str - :param package_name: Filter events by the Package Name (Android) associated with the event. + :param package_name: Filter events by the Package Name (Android) associated with the event. :type package_name: str - :param origin: Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) + :param origin: Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) :type origin: str - :param start: Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. + :param start: Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. :type start: SearchEventsStartParameter - :param end: Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. + :param end: Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. :type end: SearchEventsEndParameter - :param reverse: When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). + :param reverse: When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). :type reverse: bool - :param suspect: Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. + :param suspect: Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. :type suspect: bool - :param vpn: Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. + :param vpn: Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. :type vpn: bool - :param virtual_machine: Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. + :param virtual_machine: Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. :type virtual_machine: bool - :param tampering: Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. + :param tampering: Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. :type tampering: bool - :param anti_detect_browser: Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. + :param anti_detect_browser: Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. :type anti_detect_browser: bool - :param incognito: Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. + :param incognito: Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. :type incognito: bool - :param privacy_settings: Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. + :param privacy_settings: Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. :type privacy_settings: bool - :param jailbroken: Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. + :param jailbroken: Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. :type jailbroken: bool - :param frida: Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. + :param frida: Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. :type frida: bool - :param factory_reset: Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. + :param factory_reset: Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. :type factory_reset: bool - :param cloned_app: Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. + :param cloned_app: Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. :type cloned_app: bool - :param emulator: Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. + :param emulator: Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. :type emulator: bool - :param root_apps: Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. + :param root_apps: Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. :type root_apps: bool - :param vpn_confidence: Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. + :param vpn_confidence: Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. :type vpn_confidence: SearchEventsVpnConfidence - :param min_suspect_score: Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. + :param min_suspect_score: Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. :type min_suspect_score: float - :param developer_tools: Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. + :param developer_tools: Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. :type developer_tools: bool - :param location_spoofing: Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. + :param location_spoofing: Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. :type location_spoofing: bool - :param mitm_attack: Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. + :param mitm_attack: Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. :type mitm_attack: bool - :param rare_device: Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). + :param rare_device: Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). :type rare_device: bool - :param rare_device_percentile_bucket: Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). + :param rare_device_percentile_bucket: Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). :type rare_device_percentile_bucket: SearchEventsRareDevicePercentileBucket - :param proxy: Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. + :param proxy: Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. :type proxy: bool - :param sdk_version: Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` + :param sdk_version: Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` :type sdk_version: str - :param sdk_platform: Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. + :param sdk_platform: Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. :type sdk_platform: SearchEventsSdkPlatform - :param environment: Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. + :param environment: Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. :type environment: List[str] - :param proximity_id: Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. + :param proximity_id: Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. :type proximity_id: str - :param total_hits: When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. + :param total_hits: When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. :type total_hits: int - :param tor_node: Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. + :param tor_node: Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. :type tor_node: bool - :param incremental_identification_status: Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. + :param incremental_identification_status: Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. :type incremental_identification_status: SearchEventsIncrementalIdentificationStatus - :param simulator: Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. + :param simulator: Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. :type simulator: bool - :param source: Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. - :type source: List[SearchEventsSource] - :param active_call: Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. + :param active_call: Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. :type active_call: bool + :param source: Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. + :type source: List[SearchEventsSource] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -1015,7 +1058,7 @@ def search_events( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._search_events_serialize( limit=limit, @@ -1068,347 +1111,96 @@ def search_events( tor_node=tor_node, incremental_identification_status=incremental_identification_status, simulator=simulator, - source=source, active_call=active_call, + source=source, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, ) _response_types_map: dict[str, Optional[str]] = { - '200': 'EventSearch', - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', - '500': 'ErrorResponse', - '504': 'ErrorResponse', + '200': "EventSearch", + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + '504': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) response_data.read() return self.api_client.response_deserialize( response_data=response_data, response_types_map=_response_types_map, ).data + @validate_call def search_events_with_http_info( self, - limit: Annotated[ - Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], - Field( - description='Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. ' - ), - ] = None, - pagination_key: Annotated[ - Optional[StrictStr], - Field( - description='Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` ' - ), - ] = None, - visitor_id: Annotated[ - Optional[StrictStr], - Field( - description='Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). ' - ), - ] = None, - high_recall_id: Annotated[ - Optional[StrictStr], - Field( - description='The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). ' - ), - ] = None, - bot: Annotated[ - Optional[SearchEventsBot], - Field( - description='Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. ' - ), - ] = None, - bot_info: Annotated[ - Optional[SearchEventsBotInfo], - Field( - description='Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. ' - ), - ] = None, - bot_info_category: Annotated[ - Optional[list[BotInfoCategory]], - Field( - description='Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_identity: Annotated[ - Optional[list[BotInfoIdentity]], - Field( - description='Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_confidence: Annotated[ - Optional[list[BotInfoConfidence]], - Field( - description='Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_provider: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_name: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - ip_address: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 ' - ), - ] = None, - asn: Annotated[ - Optional[StrictStr], - Field( - description="Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. " - ), - ] = None, - linked_id: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. ' - ), - ] = None, - url: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the URL (`url` property) associated with the event. ' - ), - ] = None, - bundle_id: Annotated[ - Optional[StrictStr], - Field(description='Filter events by the Bundle ID (iOS) associated with the event. '), - ] = None, - package_name: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the Package Name (Android) associated with the event. ' - ), - ] = None, - origin: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) ' - ), - ] = None, - start: Annotated[ - Optional[SearchEventsStartParameter], - Field( - description='Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. ', - ), - ] = None, - end: Annotated[ - Optional[SearchEventsEndParameter], - Field( - description='Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. ', - ), - ] = None, - reverse: Annotated[ - Optional[StrictBool], - Field( - description='When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). ' - ), - ] = None, - suspect: Annotated[ - Optional[StrictBool], - Field( - description='Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. ' - ), - ] = None, - vpn: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. ' - ), - ] = None, - virtual_machine: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. ' - ), - ] = None, - tampering: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ' - ), - ] = None, - anti_detect_browser: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ' - ), - ] = None, - incognito: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. ' - ), - ] = None, - privacy_settings: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. ' - ), - ] = None, - jailbroken: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. ' - ), - ] = None, - frida: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. ' - ), - ] = None, - factory_reset: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. ' - ), - ] = None, - cloned_app: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. ' - ), - ] = None, - emulator: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. ' - ), - ] = None, - root_apps: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. ' - ), - ] = None, - vpn_confidence: Annotated[ - Optional[SearchEventsVpnConfidence], - Field( - description='Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. ' - ), - ] = None, - min_suspect_score: Annotated[ - Optional[Union[StrictFloat, StrictInt]], - Field( - description='Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. ' - ), - ] = None, - developer_tools: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. ' - ), - ] = None, - location_spoofing: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. ' - ), - ] = None, - mitm_attack: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. ' - ), - ] = None, - rare_device: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ' - ), - ] = None, - rare_device_percentile_bucket: Annotated[ - Optional[SearchEventsRareDevicePercentileBucket], - Field( - description='Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ' - ), - ] = None, - proxy: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. ' - ), - ] = None, - sdk_version: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` ' - ), - ] = None, - sdk_platform: Annotated[ - Optional[SearchEventsSdkPlatform], - Field( - description='Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. ' - ), - ] = None, - environment: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. ' - ), - ] = None, - proximity_id: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. ' - ), - ] = None, - total_hits: Annotated[ - Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], - Field( - description='When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. ' - ), - ] = None, - tor_node: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. ' - ), - ] = None, - incremental_identification_status: Annotated[ - Optional[SearchEventsIncrementalIdentificationStatus], - Field( - description='Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. ' - ), - ] = None, - simulator: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. ' - ), - ] = None, - source: Annotated[ - Optional[Annotated[list[SearchEventsSource], Field(max_length=1)]], - Field( - description='Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. ' - ), - ] = None, - active_call: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. ' - ), - ] = None, + limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. ")] = None, + pagination_key: Annotated[Optional[StrictStr], Field(description="Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` ")] = None, + visitor_id: Annotated[Optional[StrictStr], Field(description="Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). ")] = None, + high_recall_id: Annotated[Optional[StrictStr], Field(description="The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). ")] = None, + bot: Annotated[Optional[SearchEventsBot], Field(description="Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. ")] = None, + bot_info: Annotated[Optional[SearchEventsBotInfo], Field(description="Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. ")] = None, + bot_info_category: Annotated[Optional[List[BotInfoCategory]], Field(description="Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_identity: Annotated[Optional[List[BotInfoIdentity]], Field(description="Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_confidence: Annotated[Optional[List[BotInfoConfidence]], Field(description="Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_provider: Annotated[Optional[List[StrictStr]], Field(description="Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_name: Annotated[Optional[List[StrictStr]], Field(description="Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + ip_address: Annotated[Optional[StrictStr], Field(description="Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 ")] = None, + asn: Annotated[Optional[StrictStr], Field(description="Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. ")] = None, + linked_id: Annotated[Optional[StrictStr], Field(description="Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. ")] = None, + url: Annotated[Optional[StrictStr], Field(description="Filter events by the URL (`url` property) associated with the event. ")] = None, + bundle_id: Annotated[Optional[StrictStr], Field(description="Filter events by the Bundle ID (iOS) associated with the event. ")] = None, + package_name: Annotated[Optional[StrictStr], Field(description="Filter events by the Package Name (Android) associated with the event. ")] = None, + origin: Annotated[Optional[StrictStr], Field(description="Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) ")] = None, + start: Annotated[Optional[SearchEventsStartParameter],Field(description="Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. ",)] = None, + end: Annotated[Optional[SearchEventsEndParameter],Field(description="Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. ",)] = None, + reverse: Annotated[Optional[StrictBool], Field(description="When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). ")] = None, + suspect: Annotated[Optional[StrictBool], Field(description="Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. ")] = None, + vpn: Annotated[Optional[StrictBool], Field(description="Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. ")] = None, + virtual_machine: Annotated[Optional[StrictBool], Field(description="Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. ")] = None, + tampering: Annotated[Optional[StrictBool], Field(description="Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ")] = None, + anti_detect_browser: Annotated[Optional[StrictBool], Field(description="Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ")] = None, + incognito: Annotated[Optional[StrictBool], Field(description="Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. ")] = None, + privacy_settings: Annotated[Optional[StrictBool], Field(description="Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. ")] = None, + jailbroken: Annotated[Optional[StrictBool], Field(description="Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. ")] = None, + frida: Annotated[Optional[StrictBool], Field(description="Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. ")] = None, + factory_reset: Annotated[Optional[StrictBool], Field(description="Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. ")] = None, + cloned_app: Annotated[Optional[StrictBool], Field(description="Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. ")] = None, + emulator: Annotated[Optional[StrictBool], Field(description="Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. ")] = None, + root_apps: Annotated[Optional[StrictBool], Field(description="Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. ")] = None, + vpn_confidence: Annotated[Optional[SearchEventsVpnConfidence], Field(description="Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. ")] = None, + min_suspect_score: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description="Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. ")] = None, + developer_tools: Annotated[Optional[StrictBool], Field(description="Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. ")] = None, + location_spoofing: Annotated[Optional[StrictBool], Field(description="Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. ")] = None, + mitm_attack: Annotated[Optional[StrictBool], Field(description="Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. ")] = None, + rare_device: Annotated[Optional[StrictBool], Field(description="Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ")] = None, + rare_device_percentile_bucket: Annotated[Optional[SearchEventsRareDevicePercentileBucket], Field(description="Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ")] = None, + proxy: Annotated[Optional[StrictBool], Field(description="Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. ")] = None, + sdk_version: Annotated[Optional[StrictStr], Field(description="Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` ")] = None, + sdk_platform: Annotated[Optional[SearchEventsSdkPlatform], Field(description="Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. ")] = None, + environment: Annotated[Optional[List[StrictStr]], Field(description="Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. ")] = None, + proximity_id: Annotated[Optional[StrictStr], Field(description="Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. ")] = None, + total_hits: Annotated[Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], Field(description="When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. ")] = None, + tor_node: Annotated[Optional[StrictBool], Field(description="Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. ")] = None, + incremental_identification_status: Annotated[Optional[SearchEventsIncrementalIdentificationStatus], Field(description="Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. ")] = None, + simulator: Annotated[Optional[StrictBool], Field(description="Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. ")] = None, + active_call: Annotated[Optional[StrictBool], Field(description="Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. ")] = None, + source: Annotated[Optional[Annotated[List[SearchEventsSource], Field(max_length=1)]], Field(description="Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1416,112 +1208,112 @@ def search_events_with_http_info( ) -> ApiResponse[EventSearch]: """Search events - ## Search The `/v4/events` endpoint provides a convenient way to search for past events based on specific parameters. Typical use cases and queries include: - Searching for events associated with a single `visitor_id` within a time range to get historical behavior of a visitor. - Searching for events associated with a single `linked_id` within a time range to get all events associated with your internal account identifier. - Excluding all bot traffic from the query (`good` and `bad` bots) By default, the API searches events from the last 7 days, sorts them by newest first and returns the last 10 events. - Use `start` and `end` to specify the time range of the search. - Use `reverse=true` to sort the results oldest first. - Use `limit` to specify the number of events to return. - Use `pagination_key` to get the next page of results if there are more than `limit` events. ### Filtering events with the `suspect` flag The `/v4/events` endpoint unlocks a powerful method for fraud protection analytics. The `suspect` flag is exposed in all events where it was previously set by the update API. You can also apply the `suspect` query parameter as a filter to find all potentially fraudulent activity that you previously marked as `suspect`. This helps identify patterns of fraudulent behavior. ### Environment scoping If you use a secret key that is scoped to an environment, you will only get events associated with the same environment. With a workspace-scoped environment, you will get events from all environments. Smart Signals not activated for your workspace or are not included in the response. + ## Search The `/v4/events` endpoint provides a convenient way to search for past events based on specific parameters. Typical use cases and queries include: - Searching for events associated with a single `visitor_id` within a time range to get historical behavior of a visitor. - Searching for events associated with a single `linked_id` within a time range to get all events associated with your internal account identifier. - Excluding all bot traffic from the query (`good` and `bad` bots) By default, the API searches events from the last 7 days, sorts them by newest first and returns the last 10 events. - Use `start` and `end` to specify the time range of the search. - Use `reverse=true` to sort the results oldest first. - Use `limit` to specify the number of events to return. - Use `pagination_key` to get the next page of results if there are more than `limit` events. ### Filtering events with the `suspect` flag The `/v4/events` endpoint unlocks a powerful method for fraud protection analytics. The `suspect` flag is exposed in all events where it was previously set by the update API. You can also apply the `suspect` query parameter as a filter to find all potentially fraudulent activity that you previously marked as `suspect`. This helps identify patterns of fraudulent behavior. ### Environment scoping If you use a secret key that is scoped to an environment, you will only get events associated with the same environment. With a workspace-scoped environment, you will get events from all environments. Smart Signals not activated for your workspace or are not included in the response. - :param limit: Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. + :param limit: Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. :type limit: int - :param pagination_key: Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` + :param pagination_key: Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` :type pagination_key: str - :param visitor_id: Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). + :param visitor_id: Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). :type visitor_id: str - :param high_recall_id: The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). + :param high_recall_id: The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). :type high_recall_id: str - :param bot: Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. + :param bot: Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. :type bot: SearchEventsBot - :param bot_info: Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. + :param bot_info: Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. :type bot_info: SearchEventsBotInfo - :param bot_info_category: Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_category: Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_category: List[BotInfoCategory] - :param bot_info_identity: Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_identity: Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_identity: List[BotInfoIdentity] - :param bot_info_confidence: Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_confidence: Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_confidence: List[BotInfoConfidence] - :param bot_info_provider: Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_provider: Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_provider: List[str] - :param bot_info_name: Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_name: Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_name: List[str] - :param ip_address: Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 + :param ip_address: Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 :type ip_address: str - :param asn: Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. + :param asn: Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. :type asn: str - :param linked_id: Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. + :param linked_id: Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. :type linked_id: str - :param url: Filter events by the URL (`url` property) associated with the event. + :param url: Filter events by the URL (`url` property) associated with the event. :type url: str - :param bundle_id: Filter events by the Bundle ID (iOS) associated with the event. + :param bundle_id: Filter events by the Bundle ID (iOS) associated with the event. :type bundle_id: str - :param package_name: Filter events by the Package Name (Android) associated with the event. + :param package_name: Filter events by the Package Name (Android) associated with the event. :type package_name: str - :param origin: Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) + :param origin: Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) :type origin: str - :param start: Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. + :param start: Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. :type start: SearchEventsStartParameter - :param end: Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. + :param end: Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. :type end: SearchEventsEndParameter - :param reverse: When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). + :param reverse: When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). :type reverse: bool - :param suspect: Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. + :param suspect: Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. :type suspect: bool - :param vpn: Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. + :param vpn: Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. :type vpn: bool - :param virtual_machine: Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. + :param virtual_machine: Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. :type virtual_machine: bool - :param tampering: Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. + :param tampering: Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. :type tampering: bool - :param anti_detect_browser: Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. + :param anti_detect_browser: Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. :type anti_detect_browser: bool - :param incognito: Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. + :param incognito: Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. :type incognito: bool - :param privacy_settings: Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. + :param privacy_settings: Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. :type privacy_settings: bool - :param jailbroken: Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. + :param jailbroken: Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. :type jailbroken: bool - :param frida: Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. + :param frida: Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. :type frida: bool - :param factory_reset: Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. + :param factory_reset: Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. :type factory_reset: bool - :param cloned_app: Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. + :param cloned_app: Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. :type cloned_app: bool - :param emulator: Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. + :param emulator: Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. :type emulator: bool - :param root_apps: Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. + :param root_apps: Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. :type root_apps: bool - :param vpn_confidence: Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. + :param vpn_confidence: Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. :type vpn_confidence: SearchEventsVpnConfidence - :param min_suspect_score: Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. + :param min_suspect_score: Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. :type min_suspect_score: float - :param developer_tools: Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. + :param developer_tools: Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. :type developer_tools: bool - :param location_spoofing: Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. + :param location_spoofing: Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. :type location_spoofing: bool - :param mitm_attack: Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. + :param mitm_attack: Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. :type mitm_attack: bool - :param rare_device: Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). + :param rare_device: Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). :type rare_device: bool - :param rare_device_percentile_bucket: Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). + :param rare_device_percentile_bucket: Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). :type rare_device_percentile_bucket: SearchEventsRareDevicePercentileBucket - :param proxy: Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. + :param proxy: Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. :type proxy: bool - :param sdk_version: Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` + :param sdk_version: Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` :type sdk_version: str - :param sdk_platform: Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. + :param sdk_platform: Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. :type sdk_platform: SearchEventsSdkPlatform - :param environment: Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. + :param environment: Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. :type environment: List[str] - :param proximity_id: Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. + :param proximity_id: Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. :type proximity_id: str - :param total_hits: When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. + :param total_hits: When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. :type total_hits: int - :param tor_node: Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. + :param tor_node: Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. :type tor_node: bool - :param incremental_identification_status: Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. + :param incremental_identification_status: Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. :type incremental_identification_status: SearchEventsIncrementalIdentificationStatus - :param simulator: Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. + :param simulator: Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. :type simulator: bool - :param source: Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. - :type source: List[SearchEventsSource] - :param active_call: Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. + :param active_call: Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. :type active_call: bool + :param source: Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. + :type source: List[SearchEventsSource] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -1538,7 +1330,7 @@ def search_events_with_http_info( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._search_events_serialize( limit=limit, @@ -1591,347 +1383,96 @@ def search_events_with_http_info( tor_node=tor_node, incremental_identification_status=incremental_identification_status, simulator=simulator, - source=source, active_call=active_call, + source=source, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, ) _response_types_map: dict[str, Optional[str]] = { - '200': 'EventSearch', - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', - '500': 'ErrorResponse', - '504': 'ErrorResponse', + '200': "EventSearch", + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + '504': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) response_data.read() return self.api_client.response_deserialize( response_data=response_data, response_types_map=_response_types_map, ) + @validate_call def search_events_without_preload_content( self, - limit: Annotated[ - Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], - Field( - description='Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. ' - ), - ] = None, - pagination_key: Annotated[ - Optional[StrictStr], - Field( - description='Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` ' - ), - ] = None, - visitor_id: Annotated[ - Optional[StrictStr], - Field( - description='Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). ' - ), - ] = None, - high_recall_id: Annotated[ - Optional[StrictStr], - Field( - description='The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). ' - ), - ] = None, - bot: Annotated[ - Optional[SearchEventsBot], - Field( - description='Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. ' - ), - ] = None, - bot_info: Annotated[ - Optional[SearchEventsBotInfo], - Field( - description='Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. ' - ), - ] = None, - bot_info_category: Annotated[ - Optional[list[BotInfoCategory]], - Field( - description='Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_identity: Annotated[ - Optional[list[BotInfoIdentity]], - Field( - description='Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_confidence: Annotated[ - Optional[list[BotInfoConfidence]], - Field( - description='Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_provider: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - bot_info_name: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. ' - ), - ] = None, - ip_address: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 ' - ), - ] = None, - asn: Annotated[ - Optional[StrictStr], - Field( - description="Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. " - ), - ] = None, - linked_id: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. ' - ), - ] = None, - url: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the URL (`url` property) associated with the event. ' - ), - ] = None, - bundle_id: Annotated[ - Optional[StrictStr], - Field(description='Filter events by the Bundle ID (iOS) associated with the event. '), - ] = None, - package_name: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the Package Name (Android) associated with the event. ' - ), - ] = None, - origin: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) ' - ), - ] = None, - start: Annotated[ - Optional[SearchEventsStartParameter], - Field( - description='Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. ', - ), - ] = None, - end: Annotated[ - Optional[SearchEventsEndParameter], - Field( - description='Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. ', - ), - ] = None, - reverse: Annotated[ - Optional[StrictBool], - Field( - description='When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). ' - ), - ] = None, - suspect: Annotated[ - Optional[StrictBool], - Field( - description='Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. ' - ), - ] = None, - vpn: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. ' - ), - ] = None, - virtual_machine: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. ' - ), - ] = None, - tampering: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ' - ), - ] = None, - anti_detect_browser: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ' - ), - ] = None, - incognito: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. ' - ), - ] = None, - privacy_settings: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. ' - ), - ] = None, - jailbroken: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. ' - ), - ] = None, - frida: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. ' - ), - ] = None, - factory_reset: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. ' - ), - ] = None, - cloned_app: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. ' - ), - ] = None, - emulator: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. ' - ), - ] = None, - root_apps: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. ' - ), - ] = None, - vpn_confidence: Annotated[ - Optional[SearchEventsVpnConfidence], - Field( - description='Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. ' - ), - ] = None, - min_suspect_score: Annotated[ - Optional[Union[StrictFloat, StrictInt]], - Field( - description='Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. ' - ), - ] = None, - developer_tools: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. ' - ), - ] = None, - location_spoofing: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. ' - ), - ] = None, - mitm_attack: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. ' - ), - ] = None, - rare_device: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ' - ), - ] = None, - rare_device_percentile_bucket: Annotated[ - Optional[SearchEventsRareDevicePercentileBucket], - Field( - description='Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ' - ), - ] = None, - proxy: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. ' - ), - ] = None, - sdk_version: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` ' - ), - ] = None, - sdk_platform: Annotated[ - Optional[SearchEventsSdkPlatform], - Field( - description='Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. ' - ), - ] = None, - environment: Annotated[ - Optional[list[StrictStr]], - Field( - description='Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. ' - ), - ] = None, - proximity_id: Annotated[ - Optional[StrictStr], - Field( - description='Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. ' - ), - ] = None, - total_hits: Annotated[ - Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], - Field( - description='When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. ' - ), - ] = None, - tor_node: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. ' - ), - ] = None, - incremental_identification_status: Annotated[ - Optional[SearchEventsIncrementalIdentificationStatus], - Field( - description='Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. ' - ), - ] = None, - simulator: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. ' - ), - ] = None, - source: Annotated[ - Optional[Annotated[list[SearchEventsSource], Field(max_length=1)]], - Field( - description='Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. ' - ), - ] = None, - active_call: Annotated[ - Optional[StrictBool], - Field( - description='Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. ' - ), - ] = None, + limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. ")] = None, + pagination_key: Annotated[Optional[StrictStr], Field(description="Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` ")] = None, + visitor_id: Annotated[Optional[StrictStr], Field(description="Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). ")] = None, + high_recall_id: Annotated[Optional[StrictStr], Field(description="The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). ")] = None, + bot: Annotated[Optional[SearchEventsBot], Field(description="Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. ")] = None, + bot_info: Annotated[Optional[SearchEventsBotInfo], Field(description="Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. ")] = None, + bot_info_category: Annotated[Optional[List[BotInfoCategory]], Field(description="Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_identity: Annotated[Optional[List[BotInfoIdentity]], Field(description="Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_confidence: Annotated[Optional[List[BotInfoConfidence]], Field(description="Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_provider: Annotated[Optional[List[StrictStr]], Field(description="Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + bot_info_name: Annotated[Optional[List[StrictStr]], Field(description="Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. ")] = None, + ip_address: Annotated[Optional[StrictStr], Field(description="Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 ")] = None, + asn: Annotated[Optional[StrictStr], Field(description="Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. ")] = None, + linked_id: Annotated[Optional[StrictStr], Field(description="Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. ")] = None, + url: Annotated[Optional[StrictStr], Field(description="Filter events by the URL (`url` property) associated with the event. ")] = None, + bundle_id: Annotated[Optional[StrictStr], Field(description="Filter events by the Bundle ID (iOS) associated with the event. ")] = None, + package_name: Annotated[Optional[StrictStr], Field(description="Filter events by the Package Name (Android) associated with the event. ")] = None, + origin: Annotated[Optional[StrictStr], Field(description="Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) ")] = None, + start: Annotated[Optional[SearchEventsStartParameter],Field(description="Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. ",)] = None, + end: Annotated[Optional[SearchEventsEndParameter],Field(description="Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. ",)] = None, + reverse: Annotated[Optional[StrictBool], Field(description="When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). ")] = None, + suspect: Annotated[Optional[StrictBool], Field(description="Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. ")] = None, + vpn: Annotated[Optional[StrictBool], Field(description="Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. ")] = None, + virtual_machine: Annotated[Optional[StrictBool], Field(description="Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. ")] = None, + tampering: Annotated[Optional[StrictBool], Field(description="Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ")] = None, + anti_detect_browser: Annotated[Optional[StrictBool], Field(description="Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. ")] = None, + incognito: Annotated[Optional[StrictBool], Field(description="Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. ")] = None, + privacy_settings: Annotated[Optional[StrictBool], Field(description="Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. ")] = None, + jailbroken: Annotated[Optional[StrictBool], Field(description="Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. ")] = None, + frida: Annotated[Optional[StrictBool], Field(description="Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. ")] = None, + factory_reset: Annotated[Optional[StrictBool], Field(description="Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. ")] = None, + cloned_app: Annotated[Optional[StrictBool], Field(description="Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. ")] = None, + emulator: Annotated[Optional[StrictBool], Field(description="Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. ")] = None, + root_apps: Annotated[Optional[StrictBool], Field(description="Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. ")] = None, + vpn_confidence: Annotated[Optional[SearchEventsVpnConfidence], Field(description="Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. ")] = None, + min_suspect_score: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description="Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. ")] = None, + developer_tools: Annotated[Optional[StrictBool], Field(description="Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. ")] = None, + location_spoofing: Annotated[Optional[StrictBool], Field(description="Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. ")] = None, + mitm_attack: Annotated[Optional[StrictBool], Field(description="Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. ")] = None, + rare_device: Annotated[Optional[StrictBool], Field(description="Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ")] = None, + rare_device_percentile_bucket: Annotated[Optional[SearchEventsRareDevicePercentileBucket], Field(description="Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ")] = None, + proxy: Annotated[Optional[StrictBool], Field(description="Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. ")] = None, + sdk_version: Annotated[Optional[StrictStr], Field(description="Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` ")] = None, + sdk_platform: Annotated[Optional[SearchEventsSdkPlatform], Field(description="Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. ")] = None, + environment: Annotated[Optional[List[StrictStr]], Field(description="Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. ")] = None, + proximity_id: Annotated[Optional[StrictStr], Field(description="Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. ")] = None, + total_hits: Annotated[Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]], Field(description="When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. ")] = None, + tor_node: Annotated[Optional[StrictBool], Field(description="Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. ")] = None, + incremental_identification_status: Annotated[Optional[SearchEventsIncrementalIdentificationStatus], Field(description="Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. ")] = None, + simulator: Annotated[Optional[StrictBool], Field(description="Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. ")] = None, + active_call: Annotated[Optional[StrictBool], Field(description="Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. ")] = None, + source: Annotated[Optional[Annotated[List[SearchEventsSource], Field(max_length=1)]], Field(description="Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -1939,112 +1480,112 @@ def search_events_without_preload_content( ) -> RESTResponseType: """Search events - ## Search The `/v4/events` endpoint provides a convenient way to search for past events based on specific parameters. Typical use cases and queries include: - Searching for events associated with a single `visitor_id` within a time range to get historical behavior of a visitor. - Searching for events associated with a single `linked_id` within a time range to get all events associated with your internal account identifier. - Excluding all bot traffic from the query (`good` and `bad` bots) By default, the API searches events from the last 7 days, sorts them by newest first and returns the last 10 events. - Use `start` and `end` to specify the time range of the search. - Use `reverse=true` to sort the results oldest first. - Use `limit` to specify the number of events to return. - Use `pagination_key` to get the next page of results if there are more than `limit` events. ### Filtering events with the `suspect` flag The `/v4/events` endpoint unlocks a powerful method for fraud protection analytics. The `suspect` flag is exposed in all events where it was previously set by the update API. You can also apply the `suspect` query parameter as a filter to find all potentially fraudulent activity that you previously marked as `suspect`. This helps identify patterns of fraudulent behavior. ### Environment scoping If you use a secret key that is scoped to an environment, you will only get events associated with the same environment. With a workspace-scoped environment, you will get events from all environments. Smart Signals not activated for your workspace or are not included in the response. + ## Search The `/v4/events` endpoint provides a convenient way to search for past events based on specific parameters. Typical use cases and queries include: - Searching for events associated with a single `visitor_id` within a time range to get historical behavior of a visitor. - Searching for events associated with a single `linked_id` within a time range to get all events associated with your internal account identifier. - Excluding all bot traffic from the query (`good` and `bad` bots) By default, the API searches events from the last 7 days, sorts them by newest first and returns the last 10 events. - Use `start` and `end` to specify the time range of the search. - Use `reverse=true` to sort the results oldest first. - Use `limit` to specify the number of events to return. - Use `pagination_key` to get the next page of results if there are more than `limit` events. ### Filtering events with the `suspect` flag The `/v4/events` endpoint unlocks a powerful method for fraud protection analytics. The `suspect` flag is exposed in all events where it was previously set by the update API. You can also apply the `suspect` query parameter as a filter to find all potentially fraudulent activity that you previously marked as `suspect`. This helps identify patterns of fraudulent behavior. ### Environment scoping If you use a secret key that is scoped to an environment, you will only get events associated with the same environment. With a workspace-scoped environment, you will get events from all environments. Smart Signals not activated for your workspace or are not included in the response. - :param limit: Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. + :param limit: Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. :type limit: int - :param pagination_key: Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` + :param pagination_key: Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` :type pagination_key: str - :param visitor_id: Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). + :param visitor_id: Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). :type visitor_id: str - :param high_recall_id: The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). + :param high_recall_id: The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). :type high_recall_id: str - :param bot: Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. + :param bot: Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. :type bot: SearchEventsBot - :param bot_info: Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. + :param bot_info: Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. :type bot_info: SearchEventsBotInfo - :param bot_info_category: Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_category: Filter events by their Bot Info Category. Multiple categories can be provided using the repeated keys syntax. For example, `bot_info_category=ai_agent&bot_info_category=ai_assistant`, will match events with a Bot Info Category of `ai_agent` or `ai_assistant`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_category: List[BotInfoCategory] - :param bot_info_identity: Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_identity: Filter events by their Bot Info Identity type. Multiple identity types can be provided using the repeated keys syntax. For example, `bot_info_identity=verified&bot_info_identity=signed`, will match events with a Bot Info Identity of `verified` or `signed`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_identity: List[BotInfoIdentity] - :param bot_info_confidence: Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_confidence: Filter events by their Bot Info Confidence. Multiple confidences can be provided using the repeated keys syntax. For example, `bot_info_confidence=high&bot_info_confidence=medium`, will match events with a Bot Info Confidence of `high` or `medium`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_confidence: List[BotInfoConfidence] - :param bot_info_provider: Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_provider: Filter events by their Bot Info Provider. The provider must match exactly, partial or wildcard matching is not supported. Multiple Providers can be provided using the repeated keys syntax. For example, `bot_info_provider=OpenAI&bot_info_provider=AWS`, will match events with a Bot Info Provider of `OpenAI` or `AWS`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_provider: List[str] - :param bot_info_name: Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. + :param bot_info_name: Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. :type bot_info_name: List[str] - :param ip_address: Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 + :param ip_address: Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 :type ip_address: str - :param asn: Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. + :param asn: Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. :type asn: str - :param linked_id: Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. + :param linked_id: Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. :type linked_id: str - :param url: Filter events by the URL (`url` property) associated with the event. + :param url: Filter events by the URL (`url` property) associated with the event. :type url: str - :param bundle_id: Filter events by the Bundle ID (iOS) associated with the event. + :param bundle_id: Filter events by the Bundle ID (iOS) associated with the event. :type bundle_id: str - :param package_name: Filter events by the Package Name (Android) associated with the event. + :param package_name: Filter events by the Package Name (Android) associated with the event. :type package_name: str - :param origin: Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) + :param origin: Filter events by the origin field of the event. This is applicable to web events only (e.g., https://example.com) :type origin: str - :param start: Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. + :param start: Include events that happened after the provided `start` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to 7 days ago. Setting `start` does not change the default `end` date of `now` — adjust it separately if needed. :type start: SearchEventsStartParameter - :param end: Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. + :param end: Include events that happened before the provided `end` date formatted as an RFC3339 timestamp. For backward compatibility, a Unix milliseconds timestamp is also accepted. Defaults to now. Setting `end` does not change the default `start` date of `7 days ago` — adjust it separately if needed. :type end: SearchEventsEndParameter - :param reverse: When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). + :param reverse: When `true`, sort events oldest first (ascending timestamp order). Defaults to `false` (newest first, descending timestamp order). :type reverse: bool - :param suspect: Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. + :param suspect: Filter events previously tagged as suspicious via the [Update API](https://docs.fingerprint.com/reference/server-api-v4-update-event). > Note: When using this parameter, only events with the `suspect` property explicitly set to `true` or `false` are returned. Events with undefined `suspect` property are left out of the response. :type suspect: bool - :param vpn: Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. + :param vpn: Filter events by VPN Detection result. > Note: When using this parameter, only events with the `vpn` property set to `true` or `false` are returned. Events without a `vpn` Smart Signal result are left out of the response. :type vpn: bool - :param virtual_machine: Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. + :param virtual_machine: Filter events by Virtual Machine Detection result. > Note: When using this parameter, only events with the `virtual_machine` property set to `true` or `false` are returned. Events without a `virtual_machine` Smart Signal result are left out of the response. :type virtual_machine: bool - :param tampering: Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. + :param tampering: Filter events by Browser Tampering Detection result. > Note: When using this parameter, only events with the `tampering` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. :type tampering: bool - :param anti_detect_browser: Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. + :param anti_detect_browser: Filter events by Anti-detect Browser Detection result. > Note: When using this parameter, only events with the `tampering_details.anti_detect_browser` property set to `true` or `false` are returned. Events without a `tampering` Smart Signal result are left out of the response. :type anti_detect_browser: bool - :param incognito: Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. + :param incognito: Filter events by Browser Incognito Detection result. > Note: When using this parameter, only events with the `incognito` property set to `true` or `false` are returned. Events without an `incognito` Smart Signal result are left out of the response. :type incognito: bool - :param privacy_settings: Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. + :param privacy_settings: Filter events by Privacy Settings Detection result. > Note: When using this parameter, only events with the `privacy_settings` property set to `true` or `false` are returned. Events without a `privacy_settings` Smart Signal result are left out of the response. :type privacy_settings: bool - :param jailbroken: Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. + :param jailbroken: Filter events by Jailbroken Device Detection result. > Note: When using this parameter, only events with the `jailbroken` property set to `true` or `false` are returned. Events without a `jailbroken` Smart Signal result are left out of the response. :type jailbroken: bool - :param frida: Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. + :param frida: Filter events by Frida Detection result. > Note: When using this parameter, only events with the `frida` property set to `true` or `false` are returned. Events without a `frida` Smart Signal result are left out of the response. :type frida: bool - :param factory_reset: Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. + :param factory_reset: Filter events by Factory Reset Detection result. > Note: When using this parameter, only events with a `factory_reset_timestamp` property populated are included. Events without a `factory_reset_timestamp` Smart Signal result are left out of the response. :type factory_reset: bool - :param cloned_app: Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. + :param cloned_app: Filter events by Cloned App Detection result. > Note: When using this parameter, only events with the `cloned_app` property set to `true` or `false` are returned. Events without a `cloned_app` Smart Signal result are left out of the response. :type cloned_app: bool - :param emulator: Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. + :param emulator: Filter events by Android Emulator Detection result. > Note: When using this parameter, only events with the `emulator` property set to `true` or `false` are returned. Events without an `emulator` Smart Signal result are left out of the response. :type emulator: bool - :param root_apps: Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. + :param root_apps: Filter events by Rooted Device Detection result. > Note: When using this parameter, only events with the `root_apps` property set to `true` or `false` are returned. Events without a `root_apps` Smart Signal result are left out of the response. :type root_apps: bool - :param vpn_confidence: Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. + :param vpn_confidence: Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. :type vpn_confidence: SearchEventsVpnConfidence - :param min_suspect_score: Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. + :param min_suspect_score: Filter events with Suspect Score result above a provided minimum threshold. > Note: When using this parameter, only events where the `suspect_score` property set to a value exceeding your threshold are returned. Events without a `suspect_score` Smart Signal result are left out of the response. :type min_suspect_score: float - :param developer_tools: Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. + :param developer_tools: Filter events by Developer Tools detection result. > Note: When using this parameter, only events with the `developer_tools` property set to `true` or `false` are returned. Events without a `developer_tools` Smart Signal result are left out of the response. :type developer_tools: bool - :param location_spoofing: Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. + :param location_spoofing: Filter events by Location Spoofing detection result. > Note: When using this parameter, only events with the `location_spoofing` property set to `true` or `false` are returned. Events without a `location_spoofing` Smart Signal result are left out of the response. :type location_spoofing: bool - :param mitm_attack: Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. + :param mitm_attack: Filter events by MITM (Man-in-the-Middle) Attack detection result. > Note: When using this parameter, only events with the `mitm_attack` property set to `true` or `false` are returned. Events without a `mitm_attack` Smart Signal result are left out of the response. :type mitm_attack: bool - :param rare_device: Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). + :param rare_device: Filter events by Device Rarity detection result. > Note: When using this parameter, only events with the `rare_device` property set to `true` or `false` are returned. Events without a Device Rarity Smart Signal result are left out of the response. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). :type rare_device: bool - :param rare_device_percentile_bucket: Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). + :param rare_device_percentile_bucket: Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). :type rare_device_percentile_bucket: SearchEventsRareDevicePercentileBucket - :param proxy: Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. + :param proxy: Filter events by Proxy detection result. > Note: When using this parameter, only events with the `proxy` property set to `true` or `false` are returned. Events without a `proxy` Smart Signal result are left out of the response. :type proxy: bool - :param sdk_version: Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` + :param sdk_version: Filter events by a specific SDK version associated with the identification event (`sdk.version` property). Example: `3.11.14` :type sdk_version: str - :param sdk_platform: Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. + :param sdk_platform: Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. :type sdk_platform: SearchEventsSdkPlatform - :param environment: Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. + :param environment: Filter for events by providing one or more environment IDs (`environment_id` property). ### Array syntax To provide multiple environment IDs, use the repeated keys syntax (`environment=env1&environment=env2`). Other notations like comma-separated (`environment=env1,env2`) or bracket notation (`environment[]=env1&environment[]=env2`) are not supported. :type environment: List[str] - :param proximity_id: Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. + :param proximity_id: Filter events by the most precise Proximity ID provided by default. > Note: When using this parameter, only events with the `proximity.id` property matching the provided ID are returned. Events without a `proximity` result are left out of the response. :type proximity_id: str - :param total_hits: When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. + :param total_hits: When set, the response will include a `total_hits` property with a count of total query matches across all pages, up to the specified limit. :type total_hits: int - :param tor_node: Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. + :param tor_node: Filter events by Tor Node detection result. > Note: When using this parameter, only events with the `tor_node` property set to `true` or `false` are returned. Events without a `tor_node` detection result are left out of the response. :type tor_node: bool - :param incremental_identification_status: Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. + :param incremental_identification_status: Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. :type incremental_identification_status: SearchEventsIncrementalIdentificationStatus - :param simulator: Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. + :param simulator: Filter events by iOS Simulator Detection result. > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. :type simulator: bool - :param source: Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. - :type source: List[SearchEventsSource] - :param active_call: Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. + :param active_call: Filter events by Active Call Detection result on mobile devices. > Note: When using this parameter, only events with the `active_call` property set to `true` or `false` are returned. Events without an `active_call` Smart Signal result are left out of the response. :type active_call: bool + :param source: Selects the source of events to search. When omitted, only traditional identification events generated from devices are returned (the default behavior). When set to `edge`, only Automation Intelligence (Edge) events are returned. To retrieve all events regardless of source, you must make two requests. One with the `source` parameter set to `edge`, and another with the `source` parameter omitted. > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. + :type source: List[SearchEventsSource] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -2061,7 +1602,7 @@ def search_events_without_preload_content( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._search_events_serialize( limit=limit, @@ -2114,26 +1655,30 @@ def search_events_without_preload_content( tor_node=tor_node, incremental_identification_status=incremental_identification_status, simulator=simulator, - source=source, active_call=active_call, + source=source, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, ) _response_types_map: dict[str, Optional[str]] = { - '200': 'EventSearch', - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '429': 'ErrorResponse', - '500': 'ErrorResponse', - '504': 'ErrorResponse', + '200': "EventSearch", + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '429': "ErrorResponse", + '500': "ErrorResponse", + '504': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) return response_data.response + def _search_events_serialize( self, limit: Optional[int], @@ -2142,11 +1687,11 @@ def _search_events_serialize( high_recall_id: Optional[str], bot: Optional[SearchEventsBot], bot_info: Optional[SearchEventsBotInfo], - bot_info_category: Optional[list[BotInfoCategory]], - bot_info_identity: Optional[list[BotInfoIdentity]], - bot_info_confidence: Optional[list[BotInfoConfidence]], - bot_info_provider: Optional[list[str]], - bot_info_name: Optional[list[str]], + bot_info_category: Optional[List[BotInfoCategory]], + bot_info_identity: Optional[List[BotInfoIdentity]], + bot_info_confidence: Optional[List[BotInfoConfidence]], + bot_info_provider: Optional[List[str]], + bot_info_name: Optional[List[str]], ip_address: Optional[str], asn: Optional[str], linked_id: Optional[str], @@ -2180,14 +1725,14 @@ def _search_events_serialize( proxy: Optional[bool], sdk_version: Optional[str], sdk_platform: Optional[SearchEventsSdkPlatform], - environment: Optional[list[str]], + environment: Optional[List[str]], proximity_id: Optional[str], total_hits: Optional[int], tor_node: Optional[bool], incremental_identification_status: Optional[SearchEventsIncrementalIdentificationStatus], simulator: Optional[bool], - source: Optional[list[SearchEventsSource]], active_call: Optional[bool], + source: Optional[List[SearchEventsSource]], _request_auth: Optional[dict[StrictStr, Any]], _content_type: Optional[StrictStr], _headers: Optional[dict[StrictStr, Any]], @@ -2213,232 +1758,311 @@ def _search_events_serialize( ] = {} _body_params: Optional[Any] = None + # process the query parameters if limit is not None: + _query_params.append(('limit', limit)) - + # process the query parameters if pagination_key is not None: + _query_params.append(('pagination_key', pagination_key)) - + # process the query parameters if visitor_id is not None: + _query_params.append(('visitor_id', visitor_id)) - + # process the query parameters if high_recall_id is not None: + _query_params.append(('high_recall_id', high_recall_id)) - + # process the query parameters if bot is not None: + _query_params.append(('bot', bot.value)) - + # process the query parameters if bot_info is not None: + _query_params.append(('bot_info', bot_info.value)) - + # process the query parameters if bot_info_category is not None: + _query_params.append(('bot_info_category', bot_info_category)) - + # process the query parameters if bot_info_identity is not None: + _query_params.append(('bot_info_identity', bot_info_identity)) - + # process the query parameters if bot_info_confidence is not None: + _query_params.append(('bot_info_confidence', bot_info_confidence)) - + # process the query parameters if bot_info_provider is not None: + _query_params.append(('bot_info_provider', bot_info_provider)) - + # process the query parameters if bot_info_name is not None: + _query_params.append(('bot_info_name', bot_info_name)) - + # process the query parameters if ip_address is not None: + _query_params.append(('ip_address', ip_address)) - + # process the query parameters if asn is not None: + _query_params.append(('asn', asn)) - + # process the query parameters if linked_id is not None: + _query_params.append(('linked_id', linked_id)) - + # process the query parameters if url is not None: + _query_params.append(('url', url)) - + # process the query parameters if bundle_id is not None: + _query_params.append(('bundle_id', bundle_id)) - + # process the query parameters if package_name is not None: + _query_params.append(('package_name', package_name)) - + # process the query parameters if origin is not None: + _query_params.append(('origin', origin)) - + # process the query parameters if start is not None: if isinstance(start, datetime): - _query_params.append(('start', start.isoformat(timespec='microseconds'))) + _query_params.append( + ( + 'start', + start.isoformat(timespec='microseconds') + ) + ) elif isinstance(start, date): - _query_params.append(('start', start.isoformat())) + _query_params.append( + ( + 'start', + start.isoformat() + ) + ) else: _query_params.append(('start', start)) # process the query parameters if end is not None: if isinstance(end, datetime): - _query_params.append(('end', end.isoformat(timespec='microseconds'))) + _query_params.append( + ( + 'end', + end.isoformat(timespec='microseconds') + ) + ) elif isinstance(end, date): - _query_params.append(('end', end.isoformat())) + _query_params.append( + ( + 'end', + end.isoformat() + ) + ) else: _query_params.append(('end', end)) # process the query parameters if reverse is not None: + _query_params.append(('reverse', reverse)) - + # process the query parameters if suspect is not None: + _query_params.append(('suspect', suspect)) - + # process the query parameters if vpn is not None: + _query_params.append(('vpn', vpn)) - + # process the query parameters if virtual_machine is not None: + _query_params.append(('virtual_machine', virtual_machine)) - + # process the query parameters if tampering is not None: + _query_params.append(('tampering', tampering)) - + # process the query parameters if anti_detect_browser is not None: + _query_params.append(('anti_detect_browser', anti_detect_browser)) - + # process the query parameters if incognito is not None: + _query_params.append(('incognito', incognito)) - + # process the query parameters if privacy_settings is not None: + _query_params.append(('privacy_settings', privacy_settings)) - + # process the query parameters if jailbroken is not None: + _query_params.append(('jailbroken', jailbroken)) - + # process the query parameters if frida is not None: + _query_params.append(('frida', frida)) - + # process the query parameters if factory_reset is not None: + _query_params.append(('factory_reset', factory_reset)) - + # process the query parameters if cloned_app is not None: + _query_params.append(('cloned_app', cloned_app)) - + # process the query parameters if emulator is not None: + _query_params.append(('emulator', emulator)) - + # process the query parameters if root_apps is not None: + _query_params.append(('root_apps', root_apps)) - + # process the query parameters if vpn_confidence is not None: + _query_params.append(('vpn_confidence', vpn_confidence.value)) - + # process the query parameters if min_suspect_score is not None: + _query_params.append(('min_suspect_score', min_suspect_score)) - + # process the query parameters if developer_tools is not None: + _query_params.append(('developer_tools', developer_tools)) - + # process the query parameters if location_spoofing is not None: + _query_params.append(('location_spoofing', location_spoofing)) - + # process the query parameters if mitm_attack is not None: + _query_params.append(('mitm_attack', mitm_attack)) - + # process the query parameters if rare_device is not None: + _query_params.append(('rare_device', rare_device)) - + # process the query parameters if rare_device_percentile_bucket is not None: - _query_params.append( - ('rare_device_percentile_bucket', rare_device_percentile_bucket.value) - ) - + + _query_params.append(('rare_device_percentile_bucket', rare_device_percentile_bucket.value)) + # process the query parameters if proxy is not None: + _query_params.append(('proxy', proxy)) - + # process the query parameters if sdk_version is not None: + _query_params.append(('sdk_version', sdk_version)) - + # process the query parameters if sdk_platform is not None: + _query_params.append(('sdk_platform', sdk_platform.value)) - + # process the query parameters if environment is not None: + _query_params.append(('environment', environment)) - + # process the query parameters if proximity_id is not None: + _query_params.append(('proximity_id', proximity_id)) - + # process the query parameters if total_hits is not None: + _query_params.append(('total_hits', total_hits)) - + # process the query parameters if tor_node is not None: + _query_params.append(('tor_node', tor_node)) - + # process the query parameters if incremental_identification_status is not None: - _query_params.append( - ('incremental_identification_status', incremental_identification_status.value) - ) - + + _query_params.append(('incremental_identification_status', incremental_identification_status.value)) + # process the query parameters if simulator is not None: + _query_params.append(('simulator', simulator)) - + + # process the query parameters + if active_call is not None: + + _query_params.append(('active_call', active_call)) + # process the query parameters if source is not None: + _query_params.append(('source', source)) + + + + - # process the query parameters - if active_call is not None: - _query_params.append(('active_call', active_call)) # set the HTTP header `Accept` if 'Accept' not in _header_params: - _header_params['Accept'] = self.api_client.select_header_accept(['application/json']) + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + # authentication setting - _auth_settings: list[str] = ['bearerAuth'] + _auth_settings: list[str] = [ + 'bearerAuth' + ] return self.api_client.param_serialize( method='GET', @@ -2454,20 +2078,21 @@ def _search_events_serialize( _request_auth=_request_auth, ) + + + @validate_call def update_event( self, - event_id: Annotated[ - StrictStr, - Field( - description='The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id).' - ), - ], + event_id: Annotated[StrictStr, Field(description="The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id).")], event_update: EventUpdate, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -2475,9 +2100,9 @@ def update_event( ) -> None: """Update an event - Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. + Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. - :param event_id: The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). (required) + :param event_id: The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). (required) :type event_id: str :param event_update: (required) :type event_update: EventUpdate @@ -2497,7 +2122,7 @@ def update_event( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._update_event_serialize( event_id=event_id, @@ -2509,33 +2134,35 @@ def update_event( _response_types_map: dict[str, Optional[str]] = { '200': None, - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '409': 'ErrorResponse', + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '409': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) response_data.read() self.api_client.response_deserialize( response_data=response_data, response_types_map=_response_types_map, ) + @validate_call def update_event_with_http_info( self, - event_id: Annotated[ - StrictStr, - Field( - description='The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id).' - ), - ], + event_id: Annotated[StrictStr, Field(description="The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id).")], event_update: EventUpdate, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -2543,9 +2170,9 @@ def update_event_with_http_info( ) -> ApiResponse[None]: """Update an event - Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. + Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. - :param event_id: The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). (required) + :param event_id: The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). (required) :type event_id: str :param event_update: (required) :type event_update: EventUpdate @@ -2565,7 +2192,7 @@ def update_event_with_http_info( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._update_event_serialize( event_id=event_id, @@ -2577,33 +2204,35 @@ def update_event_with_http_info( _response_types_map: dict[str, Optional[str]] = { '200': None, - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '409': 'ErrorResponse', + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '409': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) response_data.read() return self.api_client.response_deserialize( response_data=response_data, response_types_map=_response_types_map, ) + @validate_call def update_event_without_preload_content( self, - event_id: Annotated[ - StrictStr, - Field( - description='The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id).' - ), - ], + event_id: Annotated[StrictStr, Field(description="The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id).")], event_update: EventUpdate, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], - tuple[Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]], + tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] ] = None, _request_auth: Optional[dict[StrictStr, Any]] = None, _content_type: Optional[StrictStr] = None, @@ -2611,9 +2240,9 @@ def update_event_without_preload_content( ) -> RESTResponseType: """Update an event - Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. + Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. - :param event_id: The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). (required) + :param event_id: The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). (required) :type event_id: str :param event_update: (required) :type event_update: EventUpdate @@ -2633,7 +2262,7 @@ def update_event_without_preload_content( in the spec for a single request. :type _headers: dict, optional :return: Returns the result object. - """ # noqa: E501 + """ # noqa: E501 _param = self._update_event_serialize( event_id=event_id, @@ -2645,15 +2274,19 @@ def update_event_without_preload_content( _response_types_map: dict[str, Optional[str]] = { '200': None, - '400': 'ErrorResponse', - '403': 'ErrorResponse', - '404': 'ErrorResponse', - '409': 'ErrorResponse', + '400': "ErrorResponse", + '403': "ErrorResponse", + '404': "ErrorResponse", + '409': "ErrorResponse", } - response_data = self.api_client.call_api(*_param, _request_timeout=_request_timeout) + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) return response_data.response + def _update_event_serialize( self, event_id: str, @@ -2663,7 +2296,8 @@ def _update_event_serialize( _headers: Optional[dict[StrictStr, Any]], ) -> RequestSerialized: - _collection_formats: dict[str, str] = {} + _collection_formats: dict[str, str] = { + } _path_params: dict[str, str] = {} _query_params: list[tuple[str, ParamValue]] = [] @@ -2679,26 +2313,40 @@ def _update_event_serialize( if event_id is not None: _path_params['event_id'] = event_id + + + # process the body parameter if event_update is not None: _body_params = event_update + # set the HTTP header `Accept` if 'Accept' not in _header_params: - _header_params['Accept'] = self.api_client.select_header_accept(['application/json']) + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) # set the HTTP header `Content-Type` if _content_type: _header_params['Content-Type'] = _content_type else: - _default_content_type = self.api_client.select_header_content_type( - ['application/json'] + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) ) if _default_content_type is not None: _header_params['Content-Type'] = _default_content_type # authentication setting - _auth_settings: list[str] = ['bearerAuth'] + _auth_settings: list[str] = [ + 'bearerAuth' + ] return self.api_client.param_serialize( method='PATCH', @@ -2713,3 +2361,5 @@ def _update_event_serialize( collection_formats=_collection_formats, _request_auth=_request_auth, ) + + diff --git a/fingerprint_server_sdk/api_client.py b/fingerprint_server_sdk/api_client.py index 7469b4e1..a48f5d5e 100644 --- a/fingerprint_server_sdk/api_client.py +++ b/fingerprint_server_sdk/api_client.py @@ -10,7 +10,6 @@ Do not edit the class manually. """ # noqa: E501 - from __future__ import annotations import datetime @@ -78,7 +77,7 @@ def __init__( configuration: Configuration, header_name: Optional[str] = None, header_value: Optional[str] = None, - cookie: Optional[str] = None, + cookie: Optional[str] = None ) -> None: self.configuration = configuration @@ -114,6 +113,7 @@ def user_agent(self, value: str) -> None: def set_default_header(self, header_name: str, header_value: str) -> None: self.default_headers[header_name] = header_value + def param_serialize( self, method: str, @@ -128,6 +128,7 @@ def param_serialize( collection_formats: Optional[dict[str, str]] = None, _request_auth: Optional[dict[str, Any]] = None, ) -> RequestSerialized: + """Builds the HTTP request params needed by the request. :param method: Method to call. :param resource_path: Path to method endpoint. @@ -159,7 +160,9 @@ def param_serialize( header_params['Cookie'] = self.cookie if header_params: header_params = self.sanitize_for_serialization(header_params) - header_params = dict(self.parameters_to_tuples(header_params, collection_formats)) + header_params = dict( + self.parameters_to_tuples(header_params, collection_formats) + ) # path parameters if path_params: @@ -192,7 +195,7 @@ def param_serialize( resource_path, method, body, - request_auth=_request_auth, + request_auth=_request_auth ) # body @@ -203,7 +206,7 @@ def param_serialize( url = self.configuration.host + resource_path query_params = list(query_params or []) - if getattr(self.configuration, 'default_query_params', None): + if getattr(self.configuration, "default_query_params", None): existing_keys = {k for k, _ in query_params} for k, v in self.configuration.default_query_params: if k not in existing_keys: @@ -212,11 +215,15 @@ def param_serialize( # query parameters if query_params: query_params = self.sanitize_for_serialization(query_params) - url_query = self.parameters_to_url_query(query_params, collection_formats) - url += '?' + url_query + url_query = self.parameters_to_url_query( + query_params, + collection_formats + ) + url += "?" + url_query return method, url, header_params, body, post_params_result + def call_api( self, method: str, @@ -246,7 +253,7 @@ def call_api( headers=header_params, body=body, post_params=post_params, - _request_timeout=_request_timeout, + _request_timeout=_request_timeout ) except ApiException as e: @@ -265,7 +272,7 @@ def response_deserialize( :return: ApiResponse """ - msg = 'RESTResponse.read() must be called before passing it to response_deserialize()' + msg = "RESTResponse.read() must be called before passing it to response_deserialize()" assert response_data.data is not None, msg if response_types_map is None: @@ -284,16 +291,16 @@ def response_deserialize( response_text: Optional[str] = None return_data: Any = None try: - if response_type == 'bytearray': + if response_type == "bytearray": return_data = response_data.data - elif response_type == 'file': + elif response_type == "file": return_data = self.__deserialize_file(response_data) elif response_type is not None: match = None content_type = response_data.getheader('content-type') if content_type is not None: - match = re.search(r'charset=([a-zA-Z\-\d]+)[\s;]?', content_type) - encoding = match.group(1) if match else 'utf-8' + match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type) + encoding = match.group(1) if match else "utf-8" response_text = response_data.data.decode(encoding) return_data = self.deserialize(response_text, response_type, content_type) finally: @@ -305,10 +312,10 @@ def response_deserialize( ) return ApiResponse( - status_code=response_data.status, - data=return_data, - headers=response_data.getheaders(), - raw_data=response_data.data, + status_code = response_data.status, + data = return_data, + headers = response_data.getheaders(), + raw_data = response_data.data ) def sanitize_for_serialization(self, obj: Any) -> Any: @@ -338,9 +345,13 @@ def sanitize_for_serialization(self, obj: Any) -> Any: elif isinstance(obj, uuid.UUID): return str(obj) elif isinstance(obj, list): - return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj] + return [ + self.sanitize_for_serialization(sub_obj) for sub_obj in obj + ] elif isinstance(obj, tuple): - return tuple(self.sanitize_for_serialization(sub_obj) for sub_obj in obj) + return tuple( + self.sanitize_for_serialization(sub_obj) for sub_obj in obj + ) elif isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() elif isinstance(obj, decimal.Decimal): @@ -364,7 +375,10 @@ def sanitize_for_serialization(self, obj: Any) -> Any: # and only became a real list by calling to_dict() return self.sanitize_for_serialization(obj_dict) - return {key: self.sanitize_for_serialization(val) for key, val in obj_dict.items()} + return { + key: self.sanitize_for_serialization(val) + for key, val in obj_dict.items() + } def deserialize( self, response_text: str, response_type: str, content_type: Optional[str] @@ -385,11 +399,9 @@ def deserialize( data = json.loads(response_text) except ValueError: data = response_text - elif re.match( - r'^application/(json|[\w!#$&.+\-^_]+\+json)\s*(;|$)', content_type, re.IGNORECASE - ): - if response_text == '': - data = '' + elif re.match(r'^application/(json|[\w!#$&.+\-^_]+\+json)\s*(;|$)', content_type, re.IGNORECASE): + if response_text == "": + data = "" else: data = json.loads(response_text) elif re.match(r'^text\/[a-z.+-]+\s*(;|$)', content_type, re.IGNORECASE): @@ -413,15 +425,17 @@ def __deserialize(self, data: Any, klass: Any) -> Any: if isinstance(klass, str): if klass.startswith('List['): m = re.match(r'List\[(.*)]', klass) - assert m is not None, 'Malformed List type definition' + assert m is not None, "Malformed List type definition" sub_kls = m.group(1) - return [self.__deserialize(sub_data, sub_kls) for sub_data in data] + return [self.__deserialize(sub_data, sub_kls) + for sub_data in data] if klass.startswith('Dict['): m = re.match(r'Dict\[([^,]*), (.*)]', klass) - assert m is not None, 'Malformed Dict type definition' + assert m is not None, "Malformed Dict type definition" sub_kls = m.group(2) - return {k: self.__deserialize(v, sub_kls) for k, v in data.items()} + return {k: self.__deserialize(v, sub_kls) + for k, v in data.items()} # convert str to class if klass in self.NATIVE_TYPES_MAPPING: @@ -472,7 +486,8 @@ def parameters_to_tuples( delimiter = '|' else: # csv is the default delimiter = ',' - new_params.append((k, delimiter.join(str(value) for value in v))) + new_params.append( + (k, delimiter.join(str(value) for value in v))) else: new_params.append((k, v)) return new_params @@ -512,11 +527,13 @@ def parameters_to_url_query( delimiter = '|' else: # csv is the default delimiter = ',' - new_params.append((k, delimiter.join(quote(str(value)) for value in v))) + new_params.append( + (k, delimiter.join(quote(str(value)) for value in v)) + ) else: new_params.append((k, quote(str(v)))) - return '&'.join(['='.join(map(str, item)) for item in new_params]) + return "&".join(["=".join(map(str, item)) for item in new_params]) def files_parameters( self, @@ -543,8 +560,11 @@ def files_parameters( params.extend(self.files_parameters({k: file_param})) continue else: - raise ValueError('Unsupported file value') - mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' + raise ValueError("Unsupported file value") + mimetype = ( + mimetypes.guess_type(filename)[0] + or 'application/octet-stream' + ) params.append((k, (filename, filedata, mimetype))) return params @@ -604,7 +624,14 @@ def update_params_for_auth( return if request_auth: - self._apply_auth_params(headers, queries, resource_path, method, body, request_auth) + self._apply_auth_params( + headers, + queries, + resource_path, + method, + body, + request_auth + ) else: for auth in auth_settings: auth_setting = self.configuration.auth_settings().get(auth) @@ -646,7 +673,9 @@ def _apply_auth_params( if queries is not None: queries.append((auth_setting['key'], auth_setting['value'])) else: - raise ApiValueError('Authentication token must be in `query` or `header`') + raise ApiValueError( + 'Authentication token must be in `query` or `header`' + ) def __deserialize_file(self, response: rest.RESTResponse) -> Any: """Deserializes body to file @@ -660,13 +689,16 @@ def __deserialize_file(self, response: rest.RESTResponse) -> Any: :param response: RESTResponse. :return: file path. """ - fd, path = tempfile.mkstemp(dir=getattr(self.configuration, 'temp_folder_path', None)) + fd, path = tempfile.mkstemp(dir=getattr(self.configuration, "temp_folder_path", None)) os.close(fd) os.remove(path) - content_disposition = response.getheader('Content-Disposition') + content_disposition = response.getheader("Content-Disposition") if content_disposition: - m = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition) + m = re.search( + r'filename=[\'"]?([^\'"\s]+)[\'"]?', + content_disposition + ) assert m is not None, "Unexpected 'content-disposition' header value" filename = m.group(1) path = os.path.join(os.path.dirname(path), filename) @@ -711,7 +743,8 @@ def __deserialize_date(self, string: str) -> datetime.date: return string # type: ignore[return-value] except ValueError as err: raise ApiException( - status=0, reason=f'Failed to parse `{string}` as date object' + status=0, + reason="Failed to parse `{0}` as date object".format(string) ) from err def __deserialize_datetime(self, string: str) -> datetime.datetime: @@ -728,7 +761,11 @@ def __deserialize_datetime(self, string: str) -> datetime.datetime: return string # type: ignore[return-value] except ValueError as err: raise ApiException( - status=0, reason=(f'Failed to parse `{string}` as datetime object') + status=0, + reason=( + "Failed to parse `{0}` as datetime object" + .format(string) + ) ) from err def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Enum: @@ -742,7 +779,11 @@ def __deserialize_enum(self, data: Any, klass: type[Enum]) -> Enum: return klass(data) except ValueError as err: raise ApiException( - status=0, reason=(f'Failed to parse `{data}` as `{klass}`') + status=0, + reason=( + "Failed to parse `{0}` as `{1}`" + .format(data, klass) + ) ) from err def __deserialize_model(self, data: Any, klass: Any) -> Any: @@ -753,4 +794,4 @@ def __deserialize_model(self, data: Any, klass: Any) -> Any: :return: model object. """ - return klass.from_dict(data) + return klass.from_dict(data) \ No newline at end of file diff --git a/fingerprint_server_sdk/api_response.py b/fingerprint_server_sdk/api_response.py index 9dd29d86..9bc7c11f 100644 --- a/fingerprint_server_sdk/api_response.py +++ b/fingerprint_server_sdk/api_response.py @@ -1,23 +1,21 @@ """API response object.""" from __future__ import annotations +from typing import Optional, Generic, Mapping, TypeVar +from pydantic import Field, StrictInt, StrictBytes, BaseModel -from collections.abc import Mapping -from typing import Generic, Optional, TypeVar - -from pydantic import BaseModel, Field, StrictBytes, StrictInt - -T = TypeVar('T') - +T = TypeVar("T") class ApiResponse(BaseModel, Generic[T]): """ API response object """ - status_code: StrictInt = Field(description='HTTP status code') - headers: Optional[Mapping[str, str]] = Field(None, description='HTTP headers') - data: T = Field(description='Deserialized data given the data type') - raw_data: StrictBytes = Field(description='Raw data (HTTP response body)') + status_code: StrictInt = Field(description="HTTP status code") + headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers") + data: T = Field(description="Deserialized data given the data type") + raw_data: StrictBytes = Field(description="Raw data (HTTP response body)") - model_config = {'arbitrary_types_allowed': True} + model_config = { + "arbitrary_types_allowed": True + } diff --git a/fingerprint_server_sdk/configuration.py b/fingerprint_server_sdk/configuration.py index 809b969f..e3f2765e 100644 --- a/fingerprint_server_sdk/configuration.py +++ b/fingerprint_server_sdk/configuration.py @@ -25,40 +25,38 @@ from fingerprint_server_sdk import __version__ JSON_SCHEMA_VALIDATION_KEYWORDS = { - 'multipleOf', - 'maximum', - 'exclusiveMaximum', - 'minimum', - 'exclusiveMinimum', - 'maxLength', - 'minLength', - 'pattern', - 'maxItems', - 'minItems', + 'multipleOf', 'maximum', 'exclusiveMaximum', + 'minimum', 'exclusiveMinimum', 'maxLength', + 'minLength', 'pattern', 'maxItems', 'minItems' } ServerVariablesT = dict[str, str] BearerFormatAuthSetting = TypedDict( - 'BearerFormatAuthSetting', + "BearerFormatAuthSetting", { - 'type': Literal['bearer'], - 'in': Literal['header'], - 'format': Literal['JWT'], - 'key': Literal['Authorization'], - 'value': str, + "type": Literal["bearer"], + "in": Literal["header"], + "format": Literal["JWT"], + "key": Literal["Authorization"], + "value": str, }, ) -class AuthSettings(TypedDict, total=False): - bearerAuth: BearerFormatAuthSetting +AuthSettings = TypedDict( + "AuthSettings", + { + "bearerAuth": BearerFormatAuthSetting, + }, + total=False, +) class Region(Enum): - US = 'us' - EU = 'eu' - AP = 'ap' + US = "us" + EU = "eu" + AP = "ap" class Configuration: @@ -89,7 +87,8 @@ def __init__( *, debug: Optional[bool] = None, ) -> None: - """Constructor""" + """Constructor + """ if host: self._base_path = host else: @@ -100,8 +99,8 @@ def __init__( self.logger = {} """Logging Settings """ - self.logger['package_logger'] = logging.getLogger('fingerprint_server_sdk') - self.logger['urllib3_logger'] = logging.getLogger('urllib3') + self.logger["package_logger"] = logging.getLogger("fingerprint_server_sdk") + self.logger["urllib3_logger"] = logging.getLogger("urllib3") self.logger_format = '%(asctime)s %(levelname)s %(message)s' """Log format """ @@ -174,21 +173,21 @@ def __init__( """Options to pass down to the underlying urllib3 socket """ - self.datetime_format = '%Y-%m-%dT%H:%M:%S.%f%z' + self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z" """datetime format """ - self.date_format = '%Y-%m-%d' + self.date_format = "%Y-%m-%d" """date format """ self.default_query_params: list[tuple[str, str]] = ( default_query_params if default_query_params - else [('ii', f'fingerprint-pro-server-python-sdk/{__version__}')] + else [("ii", f"fingerprint-pro-server-python-sdk/{__version__}")] ) - def __deepcopy__(self, memo: dict[int, Any]) -> Self: + def __deepcopy__(self, memo: dict[int, Any]) -> Self: cls = self.__class__ result = cls.__new__(cls) memo[id(self)] = result @@ -309,7 +308,7 @@ def auth_settings(self) -> AuthSettings: 'in': 'header', 'format': 'JWT', 'key': 'Authorization', - 'value': 'Bearer ' + self.api_key, + 'value': 'Bearer ' + self.api_key } auth['bearerAuth'] = bearerAuth @@ -320,21 +319,20 @@ def to_debug_report(self) -> str: :return: The report for debugging. """ - return ( - 'Python SDK Debug Report:\n' - f'OS: {sys.platform}\n' - f'Python Version: {sys.version}\n' - 'Version of the API: 4\n' - 'SDK Package Version: 9.7.1' - ) + return "Python SDK Debug Report:\n"\ + "OS: {env}\n"\ + "Python Version: {pyversion}\n"\ + "Version of the API: 4\n"\ + "SDK Package Version: 9.7.1".\ + format(env=sys.platform, pyversion=sys.version) @staticmethod def get_host(region: Region) -> str: return { - Region.US: 'https://api.fpjs.io/v4', - Region.EU: 'https://eu.api.fpjs.io/v4', - Region.AP: 'https://ap.api.fpjs.io/v4', - }.get(region, 'https://api.fpjs.io/v4') + Region.US: "https://api.fpjs.io/v4", + Region.EU: "https://eu.api.fpjs.io/v4", + Region.AP: "https://ap.api.fpjs.io/v4", + }.get(region, "https://api.fpjs.io/v4") @property def host(self) -> str: diff --git a/fingerprint_server_sdk/event_source.py b/fingerprint_server_sdk/event_source.py new file mode 100644 index 00000000..a350edc0 --- /dev/null +++ b/fingerprint_server_sdk/event_source.py @@ -0,0 +1,19 @@ +"""Hydrate a missing Event source before oneOf discriminator lookup.""" + +from __future__ import annotations + +import json +from typing import Any + + +def hydrate_event_discriminator(class_name: str, json_str: str, property_name: str) -> tuple[str, Any]: + payload = json.loads(json_str) + data_type = payload.get(property_name) + if class_name != "Event": + return json_str, data_type + if data_type is None or data_type == "": + payload["source"] = "device" + return json.dumps(payload), "device" + if data_type not in ("device", "edge"): + raise ValueError(f"unknown Event source: {data_type!r}") + return json_str, data_type diff --git a/fingerprint_server_sdk/exceptions.py b/fingerprint_server_sdk/exceptions.py index 1361a649..fc2ebe6d 100644 --- a/fingerprint_server_sdk/exceptions.py +++ b/fingerprint_server_sdk/exceptions.py @@ -10,7 +10,6 @@ Do not edit the class manually. """ # noqa: E501 - from __future__ import annotations import contextlib @@ -34,7 +33,7 @@ def __init__( valid_classes: Optional[tuple[type, ...]] = None, key_type: Optional[bool] = None, ) -> None: - """Raises an exception for TypeErrors + """ Raises an exception for TypeErrors Args: msg (str): the exception message @@ -56,7 +55,7 @@ def __init__( self.key_type = key_type full_msg = msg if path_to_item: - full_msg = f'{msg} at {render_path(path_to_item)}' + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) super().__init__(full_msg) @@ -74,7 +73,7 @@ def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None: self.path_to_item = path_to_item full_msg = msg if path_to_item: - full_msg = f'{msg} at {render_path(path_to_item)}' + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) super().__init__(full_msg) @@ -93,7 +92,7 @@ def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None: self.path_to_item = path_to_item full_msg = msg if path_to_item: - full_msg = f'{msg} at {render_path(path_to_item)}' + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) super().__init__(full_msg) @@ -110,7 +109,7 @@ def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None: self.path_to_item = path_to_item full_msg = msg if path_to_item: - full_msg = f'{msg} at {render_path(path_to_item)}' + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) super().__init__(full_msg) @@ -119,7 +118,7 @@ def __init__( self, status: Optional[int] = None, reason: Optional[str] = None, - http_resp: Optional[RESTResponse] = None, + http_resp: Optional["RESTResponse"] = None, *, body: Optional[str] = None, data: Optional[Any] = None, @@ -179,15 +178,17 @@ def from_response( def __str__(self) -> str: """Custom error messages for exception""" - error_message = f'({self.status})\nReason: {self.reason}\n' + error_message = "({0})\n"\ + "Reason: {1}\n".format(self.status, self.reason) if self.headers: - error_message += f'HTTP response headers: {self.headers}\n' + error_message += "HTTP response headers: {0}\n".format( + self.headers) if self.body: - error_message += f'HTTP response body: {self.body}\n' + error_message += "HTTP response body: {0}\n".format(self.body) if self.data: - error_message += f'HTTP response data: {self.data}\n' + error_message += "HTTP response data: {0}\n".format(self.data) return error_message @@ -214,34 +215,30 @@ class ServiceException(ApiException): class ConflictException(ApiException): """Exception for HTTP 409 Conflict.""" - pass class UnprocessableEntityException(ApiException): """Exception for HTTP 422 Unprocessable Entity.""" - pass class TooManyRequestsException(ApiException): """Exception for HTTP 429 Too Many Requests.""" - pass class GatewayTimeoutException(ServiceException): """Exception for HTTP 504 Gateway Timeout.""" - pass def render_path(path_to_item: list[Any]) -> str: """Returns a string representation of a path""" - result = '' + result = "" for pth in path_to_item: if isinstance(pth, int): - result += f'[{pth}]' + result += "[{0}]".format(pth) else: - result += f"['{pth}']" - return result + result += "['{0}']".format(pth) + return result \ No newline at end of file diff --git a/fingerprint_server_sdk/models/__init__.py b/fingerprint_server_sdk/models/__init__.py index eba59cff..f099886e 100644 --- a/fingerprint_server_sdk/models/__init__.py +++ b/fingerprint_server_sdk/models/__init__.py @@ -11,7 +11,6 @@ Do not edit the class manually. """ # noqa: E501 - # import models into model package from fingerprint_server_sdk.models.bot_info import BotInfo from fingerprint_server_sdk.models.bot_info_category import BotInfoCategory @@ -20,11 +19,15 @@ from fingerprint_server_sdk.models.bot_result import BotResult from fingerprint_server_sdk.models.browser_details import BrowserDetails from fingerprint_server_sdk.models.canvas import Canvas +from fingerprint_server_sdk.models.edge_request import EdgeRequest +from fingerprint_server_sdk.models.edge_request_headers_inner import EdgeRequestHeadersInner from fingerprint_server_sdk.models.emoji import Emoji from fingerprint_server_sdk.models.error import Error from fingerprint_server_sdk.models.error_code import ErrorCode from fingerprint_server_sdk.models.error_response import ErrorResponse from fingerprint_server_sdk.models.event import Event +from fingerprint_server_sdk.models.event_device import EventDevice +from fingerprint_server_sdk.models.event_edge import EventEdge from fingerprint_server_sdk.models.event_rule_action import EventRuleAction from fingerprint_server_sdk.models.event_rule_action_allow import EventRuleActionAllow from fingerprint_server_sdk.models.event_rule_action_block import EventRuleActionBlock @@ -33,18 +36,14 @@ from fingerprint_server_sdk.models.event_update import EventUpdate from fingerprint_server_sdk.models.font_preferences import FontPreferences from fingerprint_server_sdk.models.geolocation import Geolocation -from fingerprint_server_sdk.models.geolocation_subdivisions_inner import ( - GeolocationSubdivisionsInner, -) +from fingerprint_server_sdk.models.geolocation_subdivisions_inner import GeolocationSubdivisionsInner from fingerprint_server_sdk.models.ip_block_list import IPBlockList from fingerprint_server_sdk.models.ip_info import IPInfo from fingerprint_server_sdk.models.ip_info_v4 import IPInfoV4 from fingerprint_server_sdk.models.ip_info_v6 import IPInfoV6 from fingerprint_server_sdk.models.identification import Identification from fingerprint_server_sdk.models.identification_confidence import IdentificationConfidence -from fingerprint_server_sdk.models.incremental_identification_status import ( - IncrementalIdentificationStatus, -) +from fingerprint_server_sdk.models.incremental_identification_status import IncrementalIdentificationStatus from fingerprint_server_sdk.models.integration import Integration from fingerprint_server_sdk.models.integration_subintegration import IntegrationSubintegration from fingerprint_server_sdk.models.labels_inner import LabelsInner @@ -62,12 +61,8 @@ from fingerprint_server_sdk.models.search_events_bot import SearchEventsBot from fingerprint_server_sdk.models.search_events_bot_info import SearchEventsBotInfo from fingerprint_server_sdk.models.search_events_end_parameter import SearchEventsEndParameter -from fingerprint_server_sdk.models.search_events_incremental_identification_status import ( - SearchEventsIncrementalIdentificationStatus, -) -from fingerprint_server_sdk.models.search_events_rare_device_percentile_bucket import ( - SearchEventsRareDevicePercentileBucket, -) +from fingerprint_server_sdk.models.search_events_incremental_identification_status import SearchEventsIncrementalIdentificationStatus +from fingerprint_server_sdk.models.search_events_rare_device_percentile_bucket import SearchEventsRareDevicePercentileBucket from fingerprint_server_sdk.models.search_events_sdk_platform import SearchEventsSdkPlatform from fingerprint_server_sdk.models.search_events_source import SearchEventsSource from fingerprint_server_sdk.models.search_events_start_parameter import SearchEventsStartParameter @@ -82,3 +77,4 @@ from fingerprint_server_sdk.models.vpn_methods import VpnMethods from fingerprint_server_sdk.models.web_gl_basics import WebGlBasics from fingerprint_server_sdk.models.web_gl_extensions import WebGlExtensions + diff --git a/fingerprint_server_sdk/models/bot_info.py b/fingerprint_server_sdk/models/bot_info.py index 75781a78..02b6d824 100644 --- a/fingerprint_server_sdk/models/bot_info.py +++ b/fingerprint_server_sdk/models/bot_info.py @@ -18,7 +18,8 @@ import re # noqa: F401 from typing import Any, ClassVar, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -27,24 +28,13 @@ class BotInfo(BaseModel): Extended bot information. """ - category: StrictStr = Field(description='The type and purpose of the bot. ') - provider: StrictStr = Field(description='The organization or company operating the bot.') - provider_url: Optional[StrictStr] = Field( - default=None, description="The URL of the bot provider's website." - ) - name: StrictStr = Field(description='The specific name or identifier of the bot.') - identity: StrictStr = Field( - description="The verification status of the bot's identity: * `verified` - well-known bot with publicly verifiable identity, directed by the bot provider. * `signed` - bot that signs its platform via Web Bot Auth, directed by the bot provider's customers. * `spoofed` - bot that claims a public identity but fails verification. * `unknown` - bot that does not publish a verifiable identity. " - ) - confidence: StrictStr = Field(description='Confidence level of the bot identification.') - __properties: ClassVar[list[str]] = [ - 'category', - 'provider', - 'provider_url', - 'name', - 'identity', - 'confidence', - ] + category: StrictStr = Field(description="The type and purpose of the bot. ") + provider: StrictStr = Field(description="The organization or company operating the bot.") + provider_url: Optional[StrictStr] = Field(default=None, description="The URL of the bot provider's website.") + name: StrictStr = Field(description="The specific name or identifier of the bot.") + identity: StrictStr = Field(description="The verification status of the bot's identity: * `verified` - well-known bot with publicly verifiable identity, directed by the bot provider. * `signed` - bot that signs its platform via Web Bot Auth, directed by the bot provider's customers. * `spoofed` - bot that claims a public identity but fails verification. * `unknown` - bot that does not publish a verifiable identity. ") + confidence: StrictStr = Field(description="Confidence level of the bot identification.") + __properties: ClassVar[list[str]] = ['category', 'provider', 'provider_url', 'name', 'identity', 'confidence'] model_config = ConfigDict( populate_by_name=True, @@ -76,7 +66,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -94,14 +85,14 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'category': obj.get('category'), - 'provider': obj.get('provider'), - 'provider_url': obj.get('provider_url'), - 'name': obj.get('name'), - 'identity': obj.get('identity'), - 'confidence': obj.get('confidence'), - } - ) + _obj = cls.model_validate({ + "category": obj.get("category"), + "provider": obj.get("provider"), + "provider_url": obj.get("provider_url"), + "name": obj.get("name"), + "identity": obj.get("identity"), + "confidence": obj.get("confidence") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/bot_info_category.py b/fingerprint_server_sdk/models/bot_info_category.py index 0f9809c7..66a2963e 100644 --- a/fingerprint_server_sdk/models/bot_info_category.py +++ b/fingerprint_server_sdk/models/bot_info_category.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class BotInfoCategory(str, Enum): """ - The type and purpose of the bot. + The type and purpose of the bot. """ """ @@ -53,7 +51,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/bot_info_confidence.py b/fingerprint_server_sdk/models/bot_info_confidence.py index 74ae0764..3fcdca87 100644 --- a/fingerprint_server_sdk/models/bot_info_confidence.py +++ b/fingerprint_server_sdk/models/bot_info_confidence.py @@ -12,10 +12,8 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self @@ -40,7 +38,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/bot_info_identity.py b/fingerprint_server_sdk/models/bot_info_identity.py index b10eb8f8..ba792861 100644 --- a/fingerprint_server_sdk/models/bot_info_identity.py +++ b/fingerprint_server_sdk/models/bot_info_identity.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class BotInfoIdentity(str, Enum): """ - The verification status of the bot's identity: * `verified` - well-known bot with publicly verifiable identity, directed by the bot provider. * `signed` - bot that signs its platform via Web Bot Auth, directed by the bot provider's customers. * `spoofed` - bot that claims a public identity but fails verification. * `unknown` - bot that does not publish a verifiable identity. + The verification status of the bot's identity: * `verified` - well-known bot with publicly verifiable identity, directed by the bot provider. * `signed` - bot that signs its platform via Web Bot Auth, directed by the bot provider's customers. * `spoofed` - bot that claims a public identity but fails verification. * `unknown` - bot that does not publish a verifiable identity. """ """ @@ -41,7 +39,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/bot_result.py b/fingerprint_server_sdk/models/bot_result.py index 9bc334f9..9f449687 100644 --- a/fingerprint_server_sdk/models/bot_result.py +++ b/fingerprint_server_sdk/models/bot_result.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class BotResult(str, Enum): """ - Bot detection result: * `bad` - bad bot detected, such as Selenium, Puppeteer, Playwright, headless browsers, and so on * `good` - good bot detected, such as Google bot, Baidu Spider, AlexaBot and so on * `not_detected` - the visitor is not a bot + Bot detection result: * `bad` - bad bot detected, such as Selenium, Puppeteer, Playwright, headless browsers, and so on * `good` - good bot detected, such as Google bot, Baidu Spider, AlexaBot and so on * `not_detected` - the visitor is not a bot """ """ @@ -40,7 +38,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/browser_details.py b/fingerprint_server_sdk/models/browser_details.py index fa86ccc8..e49279b0 100644 --- a/fingerprint_server_sdk/models/browser_details.py +++ b/fingerprint_server_sdk/models/browser_details.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List from typing_extensions import Self @@ -33,14 +34,7 @@ class BrowserDetails(BaseModel): os: StrictStr os_version: StrictStr device: StrictStr - __properties: ClassVar[list[str]] = [ - 'browser_name', - 'browser_major_version', - 'browser_full_version', - 'os', - 'os_version', - 'device', - ] + __properties: ClassVar[list[str]] = ['browser_name', 'browser_major_version', 'browser_full_version', 'os', 'os_version', 'device'] model_config = ConfigDict( populate_by_name=True, @@ -72,7 +66,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -90,14 +85,14 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'browser_name': obj.get('browser_name'), - 'browser_major_version': obj.get('browser_major_version'), - 'browser_full_version': obj.get('browser_full_version'), - 'os': obj.get('os'), - 'os_version': obj.get('os_version'), - 'device': obj.get('device'), - } - ) + _obj = cls.model_validate({ + "browser_name": obj.get("browser_name"), + "browser_major_version": obj.get("browser_major_version"), + "browser_full_version": obj.get("browser_full_version"), + "os": obj.get("os"), + "os_version": obj.get("os_version"), + "device": obj.get("device") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/canvas.py b/fingerprint_server_sdk/models/canvas.py index 150e0812..87c7c2b9 100644 --- a/fingerprint_server_sdk/models/canvas.py +++ b/fingerprint_server_sdk/models/canvas.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -28,12 +29,8 @@ class Canvas(BaseModel): """ winding: Optional[StrictBool] = None - geometry: Optional[StrictStr] = Field( - default=None, description='Hash of geometry rendering output or `unsupported` markers.' - ) - text: Optional[StrictStr] = Field( - default=None, description='Hash of text rendering output or `unsupported` markers.' - ) + geometry: Optional[StrictStr] = Field(default=None, description="Hash of geometry rendering output or `unsupported` markers.") + text: Optional[StrictStr] = Field(default=None, description="Hash of text rendering output or `unsupported` markers.") __properties: ClassVar[list[str]] = ['winding', 'geometry', 'text'] model_config = ConfigDict( @@ -66,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -84,11 +82,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'winding': obj.get('winding'), - 'geometry': obj.get('geometry'), - 'text': obj.get('text'), - } - ) + _obj = cls.model_validate({ + "winding": obj.get("winding"), + "geometry": obj.get("geometry"), + "text": obj.get("text") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/edge_request.py b/fingerprint_server_sdk/models/edge_request.py new file mode 100644 index 00000000..f02f19a2 --- /dev/null +++ b/fingerprint_server_sdk/models/edge_request.py @@ -0,0 +1,109 @@ +""" +Server API +Fingerprint Server API allows you to get, search, and update Events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. +Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. +The API also supports collection of Automation Intelligence for requests to your server in edge, pre-origin, or middleware contexts. + +The version of the OpenAPI document: 4 +Contact: support@fingerprint.com +Generated by OpenAPI Generator (https://openapi-generator.tech) + +Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +import re # noqa: F401 +from typing import Any, ClassVar, Optional + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from fingerprint_server_sdk.models.edge_request_headers_inner import EdgeRequestHeadersInner +from typing_extensions import Self + + +class EdgeRequest(BaseModel): + """ + HTTP request metadata (including the HTTP method, headers and IP address) sent by you (your server) to the Fingerprint API for IP and bot analysis. To improve accuracy, retain as much of the original semantics of the HTTP request as possible. For example, preserve the order of the request headers and their capitalization. At least one of `ipv4_address` or `ipv6_address` must be provided; a request with neither is rejected with a `400` error. If both IPv4 and IPv6 are provided, IP intelligence will be provided for each address. If an IPv4-mapped IPv6 address is provided in the `ipv6_address` request property, the IP intelligence will be provided in the `ipv4_address` property of the response. + """ + + headers: Annotated[List[EdgeRequestHeadersInner], Field(min_length=1)] = Field(description="Ordered header entries from the request made to your server. Each entry represents one header line. If one header name appears as multiple lines, send each as a separate item in the array. Headers that contain authentication or session data must still be included, but with with their value set to an empty string. This includes headers like `Authorization` and `Cookie`, but may contain more depending on your specific project, for instance `Proxy-Authenticate` or `X-Api-Key`. Omitting the headers entirely changes the shape of the request and can affect detection. Never forward the real secret values. Whenever possible, we recommend preserving header order and capitalization to provide the best accuracy, however it’s not a strict requirement if your runtime does not maintain http header order or canonicalizes header names. ") + method: StrictStr = Field(description="The original HTTP method of the request. If supported in your runtime, preserve the original casing.") + url: StrictStr = Field(description="Absolute URL of the request, without a \\#fragment suffix. Only HTTP and HTTPS schemes are supported.") + ipv4_address: Optional[StrictStr] = Field(default=None, description="Client IPv4 address observed by your server.") + ipv6_address: Optional[StrictStr] = Field(default=None, description="Client IPv6 address observed by your server.") + linked_id: Optional[StrictStr] = Field(default=None, description="A customer-provided id that was sent with the request.") + tags: Optional[Dict[str, Any]] = Field(default=None, description="A customer-provided value or an object that was sent with the identification request or updated later.") + __properties: ClassVar[list[str]] = ['headers', 'method', 'url', 'ipv4_address', 'ipv6_address', 'linked_id', 'tags'] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EdgeRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in headers (list) + _items = [] + if self.headers: + for _item_headers in self.headers: + if _item_headers: + _items.append(_item_headers.to_dict()) + _dict['headers'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: + """Create an instance of EdgeRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "headers": [EdgeRequestHeadersInner.from_dict(_item) for _item in obj["headers"]] if obj.get("headers") is not None else None, + "method": obj.get("method"), + "url": obj.get("url"), + "ipv4_address": obj.get("ipv4_address"), + "ipv6_address": obj.get("ipv6_address"), + "linked_id": obj.get("linked_id"), + "tags": obj.get("tags") + }) + return _obj + + diff --git a/fingerprint_server_sdk/models/edge_request_headers_inner.py b/fingerprint_server_sdk/models/edge_request_headers_inner.py new file mode 100644 index 00000000..3b3a0fb0 --- /dev/null +++ b/fingerprint_server_sdk/models/edge_request_headers_inner.py @@ -0,0 +1,90 @@ +""" +Server API +Fingerprint Server API allows you to get, search, and update Events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. +Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. +The API also supports collection of Automation Intelligence for requests to your server in edge, pre-origin, or middleware contexts. + +The version of the OpenAPI document: 4 +Contact: support@fingerprint.com +Generated by OpenAPI Generator (https://openapi-generator.tech) + +Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +import re # noqa: F401 +from typing import Any, ClassVar, Optional + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List +from typing_extensions import Self + + +class EdgeRequestHeadersInner(BaseModel): + """ + EdgeRequestHeadersInner + """ + + name: StrictStr = Field(description="Header name as forwarded by your server. Headers must be valid according to RFC 7230 and will be canonicalized according to RFC 9112.") + value: StrictStr = Field(description="Value of a single forwarded header entry. Be careful to preserve the original encoding and escaping. For example, do not double escape quotes.") + __properties: ClassVar[list[str]] = ['name', 'value'] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EdgeRequestHeadersInner from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: + """Create an instance of EdgeRequestHeadersInner from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "name": obj.get("name"), + "value": obj.get("value") + }) + return _obj + + diff --git a/fingerprint_server_sdk/models/emoji.py b/fingerprint_server_sdk/models/emoji.py index 3c4fa0e5..f877ca96 100644 --- a/fingerprint_server_sdk/models/emoji.py +++ b/fingerprint_server_sdk/models/emoji.py @@ -16,9 +16,10 @@ import json import pprint import re # noqa: F401 -from typing import Any, ClassVar, Optional, Union +from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union from typing_extensions import Self @@ -27,9 +28,7 @@ class Emoji(BaseModel): Bounding box metrics describing how the emoji glyph renders. """ - font: Optional[StrictStr] = Field( - default=None, description='Font family reported by the browser when drawing the emoji.' - ) + font: Optional[StrictStr] = Field(default=None, description="Font family reported by the browser when drawing the emoji.") width: Optional[Union[StrictFloat, StrictInt]] = None height: Optional[Union[StrictFloat, StrictInt]] = None top: Optional[Union[StrictFloat, StrictInt]] = None @@ -38,17 +37,7 @@ class Emoji(BaseModel): right: Optional[Union[StrictFloat, StrictInt]] = None x: Optional[Union[StrictFloat, StrictInt]] = None y: Optional[Union[StrictFloat, StrictInt]] = None - __properties: ClassVar[list[str]] = [ - 'font', - 'width', - 'height', - 'top', - 'bottom', - 'left', - 'right', - 'x', - 'y', - ] + __properties: ClassVar[list[str]] = ['font', 'width', 'height', 'top', 'bottom', 'left', 'right', 'x', 'y'] model_config = ConfigDict( populate_by_name=True, @@ -80,7 +69,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -98,17 +88,17 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'font': obj.get('font'), - 'width': obj.get('width'), - 'height': obj.get('height'), - 'top': obj.get('top'), - 'bottom': obj.get('bottom'), - 'left': obj.get('left'), - 'right': obj.get('right'), - 'x': obj.get('x'), - 'y': obj.get('y'), - } - ) + _obj = cls.model_validate({ + "font": obj.get("font"), + "width": obj.get("width"), + "height": obj.get("height"), + "top": obj.get("top"), + "bottom": obj.get("bottom"), + "left": obj.get("left"), + "right": obj.get("right"), + "x": obj.get("x"), + "y": obj.get("y") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/error.py b/fingerprint_server_sdk/models/error.py index 25a188be..d2f6ad26 100644 --- a/fingerprint_server_sdk/models/error.py +++ b/fingerprint_server_sdk/models/error.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List from fingerprint_server_sdk.models.error_code import ErrorCode +from typing_extensions import Self class Error(BaseModel): @@ -63,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -81,5 +82,10 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({'code': obj.get('code'), 'message': obj.get('message')}) + _obj = cls.model_validate({ + "code": obj.get("code"), + "message": obj.get("message") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/error_code.py b/fingerprint_server_sdk/models/error_code.py index 42001929..dcf0e72f 100644 --- a/fingerprint_server_sdk/models/error_code.py +++ b/fingerprint_server_sdk/models/error_code.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class ErrorCode(str, Enum): """ - Error code: * `request_cannot_be_parsed` - The query parameters or JSON payload contains some errors that prevented us from parsing it (wrong type/surpassed limits). * `request_read_timeout` - The request body could not be read before the connection timed out. * `secret_api_key_required` - secret API key in header is missing or empty. * `secret_api_key_not_found` - No Fingerprint workspace found for specified secret API key. * `public_api_key_required` - public API key in header is missing or empty. * `public_api_key_not_found` - No Fingerprint workspace found for specified public API key. * `subscription_not_active` - Fingerprint workspace is not active. * `wrong_region` - Server and workspace region differ. * `feature_not_enabled` - This feature (for example, Delete API) is not enabled for your workspace. * `visitor_not_found` - The specified visitor ID was not found. It never existed or it may have already been deleted. * `too_many_requests` - The limit on secret API key requests per second has been exceeded. * `state_not_ready` - The event specified with event ID is not ready for updates yet. Try again. This error happens in rare cases when update API is called immediately after receiving the event ID on the client. In case you need to send information right away, we recommend using the JS agent API instead. * `failed` - Internal server error. * `event_not_found` - The specified event ID was not found. It never existed, expired, or it has been deleted. * `missing_module` - The request is invalid because it is missing a required module. * `payload_too_large` - The request payload is too large and cannot be processed. * `service_unavailable` - The service was unable to process the request. * `ruleset_not_found` - The specified ruleset was not found. It never existed or it has been deleted. + Error code: * `request_cannot_be_parsed` - The query parameters or JSON payload contains some errors that prevented us from parsing it (wrong type/surpassed limits). * `request_read_timeout` - The request body could not be read before the connection timed out. * `secret_api_key_required` - secret API key in header is missing or empty. * `secret_api_key_not_found` - No Fingerprint workspace found for specified secret API key. * `public_api_key_required` - public API key in header is missing or empty. * `public_api_key_not_found` - No Fingerprint workspace found for specified public API key. * `subscription_not_active` - Fingerprint workspace is not active. * `wrong_region` - Server and workspace region differ. * `feature_not_enabled` - This feature (for example, Delete API) is not enabled for your workspace. * `visitor_not_found` - The specified visitor ID was not found. It never existed or it may have already been deleted. * `too_many_requests` - The limit on secret API key requests per second has been exceeded. * `state_not_ready` - The event specified with event ID is not ready for updates yet. Try again. This error happens in rare cases when update API is called immediately after receiving the event ID on the client. In case you need to send information right away, we recommend using the JS agent API instead. * `failed` - Internal server error. * `event_not_found` - The specified event ID was not found. It never existed, expired, or it has been deleted. * `missing_module` - The request is invalid because it is missing a required module. * `payload_too_large` - The request payload is too large and cannot be processed. * `service_unavailable` - The service was unable to process the request. * `ruleset_not_found` - The specified ruleset was not found. It never existed or it has been deleted. """ """ @@ -55,7 +53,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/error_response.py b/fingerprint_server_sdk/models/error_response.py index b6529989..44d5ce9d 100644 --- a/fingerprint_server_sdk/models/error_response.py +++ b/fingerprint_server_sdk/models/error_response.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List from fingerprint_server_sdk.models.error import Error +from typing_extensions import Self class ErrorResponse(BaseModel): @@ -62,7 +62,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -83,7 +84,9 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - {'error': Error.from_dict(obj['error']) if obj.get('error') is not None else None} - ) + _obj = cls.model_validate({ + "error": Error.from_dict(obj["error"]) if obj.get("error") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/event.py b/fingerprint_server_sdk/models/event.py index 9badf776..bc2fdc5a 100644 --- a/fingerprint_server_sdk/models/event.py +++ b/fingerprint_server_sdk/models/event.py @@ -12,516 +12,147 @@ """ # noqa: E501 from __future__ import annotations - import json import pprint -import re # noqa: F401 -from typing import Annotated, Any, ClassVar, Optional, Union - -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr +from typing import Any, Optional, Union +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Any, List, Optional +from fingerprint_server_sdk.models.event_device import EventDevice +from fingerprint_server_sdk.models.event_edge import EventEdge from typing_extensions import Self +from fingerprint_server_sdk.event_source import hydrate_event_discriminator -from fingerprint_server_sdk.models.bot_info import BotInfo -from fingerprint_server_sdk.models.bot_result import BotResult -from fingerprint_server_sdk.models.browser_details import BrowserDetails -from fingerprint_server_sdk.models.event_rule_action import EventRuleAction -from fingerprint_server_sdk.models.event_source import EventSource -from fingerprint_server_sdk.models.identification import Identification -from fingerprint_server_sdk.models.incremental_identification_status import ( - IncrementalIdentificationStatus, -) -from fingerprint_server_sdk.models.ip_block_list import IPBlockList -from fingerprint_server_sdk.models.ip_info import IPInfo -from fingerprint_server_sdk.models.labels_inner import LabelsInner -from fingerprint_server_sdk.models.proximity import Proximity -from fingerprint_server_sdk.models.proxy_confidence import ProxyConfidence -from fingerprint_server_sdk.models.proxy_details import ProxyDetails -from fingerprint_server_sdk.models.rare_device_percentile_bucket import RareDevicePercentileBucket -from fingerprint_server_sdk.models.raw_device_attributes import RawDeviceAttributes -from fingerprint_server_sdk.models.sdk import SDK -from fingerprint_server_sdk.models.supplementary_id_high_recall import SupplementaryIDHighRecall -from fingerprint_server_sdk.models.tampering_confidence import TamperingConfidence -from fingerprint_server_sdk.models.tampering_details import TamperingDetails -from fingerprint_server_sdk.models.velocity import Velocity -from fingerprint_server_sdk.models.vpn_confidence import VpnConfidence -from fingerprint_server_sdk.models.vpn_methods import VpnMethods - +EVENT_ONE_OF_SCHEMAS = ["EventDevice", "EventEdge"] class Event(BaseModel): """ - Contains results from Fingerprint Identification and all active Smart Signals. Some Smart Signals are only supported for certain device types, these fields will be omitted for events not generated from the supported devices. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. + An identification event (`source: device`) or an Automation Intelligence event (`source: edge`). Use `source` to tell them apart. Device events include Identification and device-derived Smart Signals. Edge events do not. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. """ - - event_id: StrictStr = Field( - description="Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. " - ) - timestamp: StrictInt = Field( - description='Timestamp of the event with millisecond precision in Unix time.' - ) - source: Optional[EventSource] = None - incremental_identification_status: Optional[IncrementalIdentificationStatus] = None - linked_id: Optional[StrictStr] = Field( - default=None, description='A customer-provided id that was sent with the request.' - ) - environment_id: Optional[StrictStr] = Field( - default=None, description='Environment Id of the event.' - ) - suspect: Optional[StrictBool] = Field( - default=None, - description='Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-v4-update-event).', - ) - sdk: Optional[SDK] = None - replayed: Optional[StrictBool] = Field( - default=None, - description='`true` if we determined that this payload was replayed, `false` otherwise. ', - ) - identification: Optional[Identification] = None - supplementary_id_high_recall: Optional[SupplementaryIDHighRecall] = None - tags: Optional[dict[str, Any]] = Field( - default=None, - description='A customer-provided value or an object that was sent with the identification request or updated later.', - ) - url: Optional[StrictStr] = Field( - default=None, description='Page URL from which the request was sent.' - ) - bundle_id: Optional[StrictStr] = Field( - default=None, - description='Bundle Id of the iOS application integrated with the Fingerprint SDK for the event. ', - ) - package_name: Optional[StrictStr] = Field( - default=None, - description='Package name of the Android application integrated with the Fingerprint SDK for the event. ', - ) - ip_address: Optional[StrictStr] = Field( - default=None, description='IP address of the requesting browser or bot.' - ) - user_agent: Optional[StrictStr] = Field(default=None, description='User Agent of the client.') - device: Optional[StrictStr] = Field( - default=None, - description='Device model or family extracted from the user agent string. On web, this field is also present inside `browser_details`. ', - ) - os: Optional[StrictStr] = Field( - default=None, - description='Operating system family extracted from the user agent string. On web, this field is also present inside `browser_details`. ', - ) - os_version: Optional[StrictStr] = Field( - default=None, - description='Operating system version string extracted from the user agent string. On web, this field is also present inside `browser_details`. ', - ) - client_referrer: Optional[StrictStr] = Field( - default=None, - description='Client Referrer field corresponds to the `document.referrer` field gathered during an identification request. The value is an empty string if the user navigated to the page directly (not through a link, but, for example, by using a bookmark). ', - ) - browser_details: Optional[BrowserDetails] = None - proximity: Optional[Proximity] = None - active_call: Optional[StrictBool] = Field( - default=None, - description='Indicates whether the mobile device had an active call (cellular or VoIP) at the time of the request. Available from SDK 2.16.0+ on iOS and Android. ', - ) - bot: Optional[BotResult] = None - bot_type: Optional[StrictStr] = Field( - default=None, description='Additional classification of the bot type if detected. ' - ) - bot_info: Optional[BotInfo] = None - cloned_app: Optional[StrictBool] = Field( - default=None, - description='Android specific cloned application detection. There are 2 values: * `true` - Presence of app cloners work detected (e.g. fully cloned application found or launch of it inside of a not main working profile detected). * `false` - No signs of cloned application detected or the client is not Android. ', - ) - developer_tools: Optional[StrictBool] = Field( - default=None, - description='`true` if the browser has DevTools open (Chrome, Firefox) or the Android/iOS device has Developer Tools enabled, `false` otherwise. ', - ) - emulator: Optional[StrictBool] = Field( - default=None, - description='Android specific emulator detection. There are 2 values: * `true` - Emulated environment detected (e.g. launch inside of AVD). * `false` - No signs of emulated environment detected or the client is not Android. ', - ) - factory_reset_timestamp: Optional[StrictInt] = Field( - default=None, - description='The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. When a factory reset cannot be detected on the mobile device or when the request is initiated from a browser, this field will correspond to the *epoch* time (i.e 1 Jan 1970 UTC) as a value of 0. See [Factory Reset Detection](https://docs.fingerprint.com/docs/smart-signals-reference#factory-reset-detection) to learn more about this Smart Signal. ', - ) - frida: Optional[StrictBool] = Field( - default=None, - description='[Frida](https://frida.re/docs/) detection for Android and iOS devices. There are 2 values: * `true` - Frida detected * `false` - No signs of Frida or the client is not a mobile device. ', - ) - ip_blocklist: Optional[IPBlockList] = None - ip_info: Optional[IPInfo] = None - proxy: Optional[StrictBool] = Field( - default=None, - description='IP address was used by a public proxy provider or belonged to a known recent residential proxy ', - ) - proxy_confidence: Optional[ProxyConfidence] = None - proxy_details: Optional[ProxyDetails] = None - proxy_ml_score: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - default=None, - description='Machine learning–based proxy score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `proxy` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ', - ) - incognito: Optional[StrictBool] = Field( - default=None, - description='`true` if we detected incognito mode used in the browser, `false` otherwise. ', - ) - jailbroken: Optional[StrictBool] = Field( - default=None, - description='iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. ', - ) - location_spoofing: Optional[StrictBool] = Field( - default=None, - description='Flag indicating whether the request came from a mobile device with location spoofing enabled.', - ) - mitm_attack: Optional[StrictBool] = Field( - default=None, - description="* `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://docs.fingerprint.com/docs/smart-signals-reference#mitm-attack-detection) to learn more about this Smart Signal. ", - ) - privacy_settings: Optional[StrictBool] = Field( - default=None, - description='`true` if the request is from a privacy aware browser (e.g. Tor) or from a browser in which fingerprinting is blocked. Otherwise `false`. ', - ) - root_apps: Optional[StrictBool] = Field( - default=None, - description="Android specific root management apps detection. There are 2 values: * `true` - Root Management Apps detected (e.g. Magisk). * `false` - No Root Management Apps detected or the client isn't Android. ", - ) - rule_action: Optional[EventRuleAction] = None - simulator: Optional[StrictBool] = Field( - default=None, - description='iOS specific simulator detection. There are 2 values: * `true` - Simulator environment detected. * `false` - No signs of simulator or the client is not iOS. ', - ) - suspect_score: Optional[StrictInt] = Field( - default=None, - description='Suspect Score is an easy way to integrate Smart Signals into your fraud protection work flow. It is a weighted representation of all Smart Signals present in the payload that helps identify suspicious activity. The value range is [0; S] where S is sum of all Smart Signals weights. See more details here: https://docs.fingerprint.com/docs/suspect-score ', - ) - tampering: Optional[StrictBool] = Field( - default=None, - description='The field can be used as a standalone flag for tampering detection. Alternatively, the more granular fields documented below can be used for workflows that require more context. * `true` if tampering is detected through an anomalous browser signature, anti-detect browser detection, or other tampering-related methods * `false` if none of the tampering checks return a positive result ', - ) - tampering_confidence: Optional[TamperingConfidence] = None - tampering_ml_score: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - default=None, - description='The output of this model is captured as tampering_ml_score, a number indicating how likely an event is coming from an anti detect browser. Values close to 1 signify higher confidence and we consider anything above the threshold of 0.8 to be actionable (the result and anti_detect_browser fields conveniently captures that fact) ', - ) - tampering_details: Optional[TamperingDetails] = None - velocity: Optional[Velocity] = None - virtual_machine: Optional[StrictBool] = Field( - default=None, - description='`true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. ', - ) - virtual_machine_ml_score: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - default=None, - description='Machine learning–based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ', - ) - vpn: Optional[StrictBool] = Field( - default=None, - description='VPN or other anonymizing service has been used when sending the request. ', - ) - vpn_confidence: Optional[VpnConfidence] = None - vpn_ml_score: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - default=None, - description='Machine learning–based VPN score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `vpn` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ', - ) - vpn_origin_timezone: Optional[StrictStr] = Field( - default=None, description='Local timezone which is used in timezone_mismatch method. ' - ) - vpn_origin_country: Optional[StrictStr] = Field( - default=None, - description='Country of the request (Android SDK version >= 2.4.0, iOS SDK version >= 2.9.0, JS agent >= 3.12.9 / 4.0.2), ISO 3166 format or unknown. ', - ) - vpn_methods: Optional[VpnMethods] = None - high_activity_device: Optional[StrictBool] = Field( - default=None, - description='Flag indicating if the request came from a high-activity visitor.', - ) - rare_device: Optional[StrictBool] = Field( - default=None, - description='`true` if the device is considered rare based on its combination of hardware and software attributes. A device is classified as rare if it falls within the top 99.9 percentile (lowest-frequency segment) of observed traffic, or if its configuration has not been previously seen (`not_seen`). > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ', - ) - rare_device_percentile_bucket: Optional[RareDevicePercentileBucket] = None - raw_device_attributes: Optional[RawDeviceAttributes] = None - labels: Optional[list[LabelsInner]] = Field( - default=None, - description='Each label returns a prediction (true or false) for a specific use case (label field) based on a machine learning score. The machine learning score is determined by a model trained on customer data for that use case. This field is in the beta phase and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ', - ) - __properties: ClassVar[list[str]] = [ - 'event_id', - 'timestamp', - 'source', - 'incremental_identification_status', - 'linked_id', - 'environment_id', - 'suspect', - 'sdk', - 'replayed', - 'identification', - 'supplementary_id_high_recall', - 'tags', - 'url', - 'bundle_id', - 'package_name', - 'ip_address', - 'user_agent', - 'device', - 'os', - 'os_version', - 'client_referrer', - 'browser_details', - 'proximity', - 'active_call', - 'bot', - 'bot_type', - 'bot_info', - 'cloned_app', - 'developer_tools', - 'emulator', - 'factory_reset_timestamp', - 'frida', - 'ip_blocklist', - 'ip_info', - 'proxy', - 'proxy_confidence', - 'proxy_details', - 'proxy_ml_score', - 'incognito', - 'jailbroken', - 'location_spoofing', - 'mitm_attack', - 'privacy_settings', - 'root_apps', - 'rule_action', - 'simulator', - 'suspect_score', - 'tampering', - 'tampering_confidence', - 'tampering_ml_score', - 'tampering_details', - 'velocity', - 'virtual_machine', - 'virtual_machine_ml_score', - 'vpn', - 'vpn_confidence', - 'vpn_ml_score', - 'vpn_origin_timezone', - 'vpn_origin_country', - 'vpn_methods', - 'high_activity_device', - 'rare_device', - 'rare_device_percentile_bucket', - 'raw_device_attributes', - 'labels', - ] + # SPIKE INTER-2457 — BREAKING CHANGE. DO NOT SHIP. + # Event is no longer a flat model. Fields like `identification` live on + # `actual_instance` (EventDevice | EventEdge). Existing callers that do + # `event.identification` raise AttributeError at runtime. + # data type: EventDevice + oneof_schema_1_validator: Optional[EventDevice] = None + # data type: EventEdge + oneof_schema_2_validator: Optional[EventEdge] = None + actual_instance: Optional[Union[EventDevice, EventEdge]] = None + one_of_schemas: set[str] = { "EventDevice", "EventEdge" } model_config = ConfigDict( - populate_by_name=True, validate_assignment=True, protected_namespaces=(), ) - def to_str(self) -> str: - """Returns the string representation of the model using alias""" - return pprint.pformat(self.model_dump(by_alias=True)) - def to_json(self) -> str: - """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) + discriminator_value_class_map: dict[str, str] = { + } + + def __init__(self, *args: Any, **kwargs: Any) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_oneof(cls, v: Any) -> Any: + Event.model_construct() + error_messages = [] + match = 0 + # validate data type: EventDevice + if not isinstance(v, EventDevice): + error_messages.append(f"Error! Input type `{type(v)}` is not `EventDevice`") + else: + match += 1 + # validate data type: EventEdge + if not isinstance(v, EventEdge): + error_messages.append(f"Error! Input type `{type(v)}` is not `EventEdge`") + else: + match += 1 + if match > 1: + # more than 1 match + raise ValueError("Multiple matches found when setting `actual_instance` in Event with oneOf schemas: EventDevice, EventEdge. Details: " + ", ".join(error_messages)) + elif match == 0: + # no match + raise ValueError("No match found when setting `actual_instance` in Event with oneOf schemas: EventDevice, EventEdge. Details: " + ", ".join(error_messages)) + else: + return v @classmethod - def from_json(cls, json_str: str) -> Optional[Self]: - """Create an instance of Event from a JSON string""" - return cls.from_dict(json.loads(json_str)) + def from_dict(cls, obj: Union[str, dict[str, Any]]) -> Self: + return cls.from_json(json.dumps(obj)) - def to_dict(self) -> dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + match = 0 + + # use oneOf discriminator to lookup the data type + json_str, _data_type = hydrate_event_discriminator("Event", json_str, "source") + if "Event" != "Event" and not _data_type: + raise ValueError("Failed to lookup data type from the field `source` in the input.") + + # check if data type is `EventDevice` + if _data_type == "device": + instance.actual_instance = EventDevice.from_json(json_str) + return instance + + # check if data type is `EventEdge` + if _data_type == "edge": + instance.actual_instance = EventEdge.from_json(json_str) + return instance + + # deserialize data into EventDevice + try: + instance.actual_instance = EventDevice.from_json(json_str) + match += 1 + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into EventEdge + try: + instance.actual_instance = EventEdge.from_json(json_str) + match += 1 + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if match > 1: + # more than 1 match + raise ValueError("Multiple matches found when deserializing the JSON string into Event with oneOf schemas: EventDevice, EventEdge. Details: " + ", ".join(error_messages)) + elif match == 0: + # no match + raise ValueError("No match found when deserializing the JSON string into Event with oneOf schemas: EventDevice, EventEdge. Details: " + ", ".join(error_messages)) + else: + return instance - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - """ - excluded_fields: set[str] = set([]) + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[dict[str, Any], EventDevice, EventEdge]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of sdk - if self.sdk: - _dict['sdk'] = self.sdk.to_dict() - # override the default output from pydantic by calling `to_dict()` of identification - if self.identification: - _dict['identification'] = self.identification.to_dict() - # override the default output from pydantic by calling `to_dict()` of supplementary_id_high_recall - if self.supplementary_id_high_recall: - _dict['supplementary_id_high_recall'] = self.supplementary_id_high_recall.to_dict() - # override the default output from pydantic by calling `to_dict()` of browser_details - if self.browser_details: - _dict['browser_details'] = self.browser_details.to_dict() - # override the default output from pydantic by calling `to_dict()` of proximity - if self.proximity: - _dict['proximity'] = self.proximity.to_dict() - # override the default output from pydantic by calling `to_dict()` of bot_info - if self.bot_info: - _dict['bot_info'] = self.bot_info.to_dict() - # override the default output from pydantic by calling `to_dict()` of ip_blocklist - if self.ip_blocklist: - _dict['ip_blocklist'] = self.ip_blocklist.to_dict() - # override the default output from pydantic by calling `to_dict()` of ip_info - if self.ip_info: - _dict['ip_info'] = self.ip_info.to_dict() - # override the default output from pydantic by calling `to_dict()` of proxy_details - if self.proxy_details: - _dict['proxy_details'] = self.proxy_details.to_dict() - # override the default output from pydantic by calling `to_dict()` of rule_action - if self.rule_action: - _dict['rule_action'] = self.rule_action.to_dict() - # override the default output from pydantic by calling `to_dict()` of tampering_details - if self.tampering_details: - _dict['tampering_details'] = self.tampering_details.to_dict() - # override the default output from pydantic by calling `to_dict()` of velocity - if self.velocity: - _dict['velocity'] = self.velocity.to_dict() - # override the default output from pydantic by calling `to_dict()` of vpn_methods - if self.vpn_methods: - _dict['vpn_methods'] = self.vpn_methods.to_dict() - # override the default output from pydantic by calling `to_dict()` of raw_device_attributes - if self.raw_device_attributes: - _dict['raw_device_attributes'] = self.raw_device_attributes.to_dict() - # override the default output from pydantic by calling `to_dict()` of each item in labels (list) - _items = [] - if self.labels: - for _item_labels in self.labels: - if _item_labels: - _items.append(_item_labels.to_dict()) - _dict['labels'] = _items - return _dict + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + # primitive type + return self.actual_instance - @classmethod - def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: - """Create an instance of Event from a dict""" - if obj is None: - return None + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) - if not isinstance(obj, dict): - return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'event_id': obj.get('event_id'), - 'timestamp': obj.get('timestamp'), - 'source': obj.get('source'), - 'incremental_identification_status': obj.get('incremental_identification_status'), - 'linked_id': obj.get('linked_id'), - 'environment_id': obj.get('environment_id'), - 'suspect': obj.get('suspect'), - 'sdk': SDK.from_dict(obj['sdk']) if obj.get('sdk') is not None else None, - 'replayed': obj.get('replayed'), - 'identification': Identification.from_dict(obj['identification']) - if obj.get('identification') is not None - else None, - 'supplementary_id_high_recall': SupplementaryIDHighRecall.from_dict( - obj['supplementary_id_high_recall'] - ) - if obj.get('supplementary_id_high_recall') is not None - else None, - 'tags': obj.get('tags'), - 'url': obj.get('url'), - 'bundle_id': obj.get('bundle_id'), - 'package_name': obj.get('package_name'), - 'ip_address': obj.get('ip_address'), - 'user_agent': obj.get('user_agent'), - 'device': obj.get('device'), - 'os': obj.get('os'), - 'os_version': obj.get('os_version'), - 'client_referrer': obj.get('client_referrer'), - 'browser_details': BrowserDetails.from_dict(obj['browser_details']) - if obj.get('browser_details') is not None - else None, - 'proximity': Proximity.from_dict(obj['proximity']) - if obj.get('proximity') is not None - else None, - 'active_call': obj.get('active_call'), - 'bot': obj.get('bot'), - 'bot_type': obj.get('bot_type'), - 'bot_info': BotInfo.from_dict(obj['bot_info']) - if obj.get('bot_info') is not None - else None, - 'cloned_app': obj.get('cloned_app'), - 'developer_tools': obj.get('developer_tools'), - 'emulator': obj.get('emulator'), - 'factory_reset_timestamp': obj.get('factory_reset_timestamp'), - 'frida': obj.get('frida'), - 'ip_blocklist': IPBlockList.from_dict(obj['ip_blocklist']) - if obj.get('ip_blocklist') is not None - else None, - 'ip_info': IPInfo.from_dict(obj['ip_info']) - if obj.get('ip_info') is not None - else None, - 'proxy': obj.get('proxy'), - 'proxy_confidence': obj.get('proxy_confidence'), - 'proxy_details': ProxyDetails.from_dict(obj['proxy_details']) - if obj.get('proxy_details') is not None - else None, - 'proxy_ml_score': obj.get('proxy_ml_score'), - 'incognito': obj.get('incognito'), - 'jailbroken': obj.get('jailbroken'), - 'location_spoofing': obj.get('location_spoofing'), - 'mitm_attack': obj.get('mitm_attack'), - 'privacy_settings': obj.get('privacy_settings'), - 'root_apps': obj.get('root_apps'), - 'rule_action': EventRuleAction.from_dict(obj['rule_action']) - if obj.get('rule_action') is not None - else None, - 'simulator': obj.get('simulator'), - 'suspect_score': obj.get('suspect_score'), - 'tampering': obj.get('tampering'), - 'tampering_confidence': obj.get('tampering_confidence'), - 'tampering_ml_score': obj.get('tampering_ml_score'), - 'tampering_details': TamperingDetails.from_dict(obj['tampering_details']) - if obj.get('tampering_details') is not None - else None, - 'velocity': Velocity.from_dict(obj['velocity']) - if obj.get('velocity') is not None - else None, - 'virtual_machine': obj.get('virtual_machine'), - 'virtual_machine_ml_score': obj.get('virtual_machine_ml_score'), - 'vpn': obj.get('vpn'), - 'vpn_confidence': obj.get('vpn_confidence'), - 'vpn_ml_score': obj.get('vpn_ml_score'), - 'vpn_origin_timezone': obj.get('vpn_origin_timezone'), - 'vpn_origin_country': obj.get('vpn_origin_country'), - 'vpn_methods': VpnMethods.from_dict(obj['vpn_methods']) - if obj.get('vpn_methods') is not None - else None, - 'high_activity_device': obj.get('high_activity_device'), - 'rare_device': obj.get('rare_device'), - 'rare_device_percentile_bucket': obj.get('rare_device_percentile_bucket'), - 'raw_device_attributes': RawDeviceAttributes.from_dict( - obj['raw_device_attributes'] - ) - if obj.get('raw_device_attributes') is not None - else None, - 'labels': [LabelsInner.from_dict(_item) for _item in obj['labels']] - if obj.get('labels') is not None - else None, - } - ) - return _obj diff --git a/fingerprint_server_sdk/models/event_device.py b/fingerprint_server_sdk/models/event_device.py new file mode 100644 index 00000000..8c4117c1 --- /dev/null +++ b/fingerprint_server_sdk/models/event_device.py @@ -0,0 +1,288 @@ +""" +Server API +Fingerprint Server API allows you to get, search, and update Events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. +Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. +The API also supports collection of Automation Intelligence for requests to your server in edge, pre-origin, or middleware contexts. + +The version of the OpenAPI document: 4 +Contact: support@fingerprint.com +Generated by OpenAPI Generator (https://openapi-generator.tech) + +Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +import re # noqa: F401 +from typing import Any, ClassVar, Optional + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated +from fingerprint_server_sdk.models.bot_info import BotInfo +from fingerprint_server_sdk.models.bot_result import BotResult +from fingerprint_server_sdk.models.browser_details import BrowserDetails +from fingerprint_server_sdk.models.event_rule_action import EventRuleAction +from fingerprint_server_sdk.models.event_source import EventSource +from fingerprint_server_sdk.models.identification import Identification +from fingerprint_server_sdk.models.incremental_identification_status import IncrementalIdentificationStatus +from fingerprint_server_sdk.models.ip_block_list import IPBlockList +from fingerprint_server_sdk.models.ip_info import IPInfo +from fingerprint_server_sdk.models.labels_inner import LabelsInner +from fingerprint_server_sdk.models.proximity import Proximity +from fingerprint_server_sdk.models.proxy_confidence import ProxyConfidence +from fingerprint_server_sdk.models.proxy_details import ProxyDetails +from fingerprint_server_sdk.models.rare_device_percentile_bucket import RareDevicePercentileBucket +from fingerprint_server_sdk.models.raw_device_attributes import RawDeviceAttributes +from fingerprint_server_sdk.models.sdk import SDK +from fingerprint_server_sdk.models.supplementary_id_high_recall import SupplementaryIDHighRecall +from fingerprint_server_sdk.models.tampering_confidence import TamperingConfidence +from fingerprint_server_sdk.models.tampering_details import TamperingDetails +from fingerprint_server_sdk.models.velocity import Velocity +from fingerprint_server_sdk.models.vpn_confidence import VpnConfidence +from fingerprint_server_sdk.models.vpn_methods import VpnMethods +from typing_extensions import Self + + +class EventDevice(BaseModel): + """ + Contains results from Fingerprint Identification and Smart Signals derived from client-side device telemetry. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. + """ + + event_id: StrictStr = Field(description="Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. ") + timestamp: StrictInt = Field(description="Timestamp of the event with millisecond precision in Unix time.") + linked_id: Optional[StrictStr] = Field(default=None, description="A customer-provided id that was sent with the request.") + tags: Optional[Dict[str, Any]] = Field(default=None, description="A customer-provided value or an object that was sent with the identification request or updated later.") + url: Optional[StrictStr] = Field(default=None, description="Page URL from which the request was sent.") + bot_info: Optional[BotInfo] = None + ip_info: Optional[IPInfo] = None + proxy: Optional[StrictBool] = Field(default=None, description="IP address was used by a public proxy provider or belonged to a known recent residential proxy ") + proxy_confidence: Optional[ProxyConfidence] = None + proxy_details: Optional[ProxyDetails] = None + vpn: Optional[StrictBool] = Field(default=None, description="VPN or other anonymizing service has been used when sending the request. ") + vpn_confidence: Optional[VpnConfidence] = None + vpn_methods: Optional[VpnMethods] = None + source: EventSource + incremental_identification_status: Optional[IncrementalIdentificationStatus] = None + environment_id: Optional[StrictStr] = Field(default=None, description="Environment Id of the event.") + suspect: Optional[StrictBool] = Field(default=None, description="Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-update-event).") + sdk: Optional[SDK] = None + replayed: Optional[StrictBool] = Field(default=None, description="`true` if we determined that this payload was replayed, `false` otherwise. ") + identification: Optional[Identification] = None + supplementary_id_high_recall: Optional[SupplementaryIDHighRecall] = None + bundle_id: Optional[StrictStr] = Field(default=None, description="Bundle Id of the iOS application integrated with the Fingerprint SDK for the event. ") + package_name: Optional[StrictStr] = Field(default=None, description="Package name of the Android application integrated with the Fingerprint SDK for the event. ") + ip_address: Optional[StrictStr] = Field(default=None, description="IP address of the requesting browser or bot.") + user_agent: Optional[StrictStr] = Field(default=None, description="User Agent of the client.") + device: Optional[StrictStr] = Field(default=None, description="Device model or family extracted from the user agent string. On web, this field is also present inside `browser_details`. ") + os: Optional[StrictStr] = Field(default=None, description="Operating system family extracted from the user agent string. On web, this field is also present inside `browser_details`. ") + os_version: Optional[StrictStr] = Field(default=None, description="Operating system version string extracted from the user agent string. On web, this field is also present inside `browser_details`. ") + client_referrer: Optional[StrictStr] = Field(default=None, description="Client Referrer field corresponds to the `document.referrer` field gathered during an identification request. The value is an empty string if the user navigated to the page directly (not through a link, but, for example, by using a bookmark). ") + browser_details: Optional[BrowserDetails] = None + proximity: Optional[Proximity] = None + active_call: Optional[StrictBool] = Field(default=None, description="Indicates whether the mobile device had an active call (cellular or VoIP) at the time of the request. Available from SDK 2.16.0+ on iOS and Android. ") + bot: Optional[BotResult] = None + bot_type: Optional[StrictStr] = Field(default=None, description="Additional classification of the bot type if detected. ") + cloned_app: Optional[StrictBool] = Field(default=None, description="Android specific cloned application detection. There are 2 values: * `true` - Presence of app cloners work detected (e.g. fully cloned application found or launch of it inside of a not main working profile detected). * `false` - No signs of cloned application detected or the client is not Android. ") + developer_tools: Optional[StrictBool] = Field(default=None, description="`true` if the browser has DevTools open (Chrome, Firefox) or the Android/iOS device has Developer Tools enabled, `false` otherwise. ") + emulator: Optional[StrictBool] = Field(default=None, description="Android specific emulator detection. There are 2 values: * `true` - Emulated environment detected (e.g. launch inside of AVD). * `false` - No signs of emulated environment detected or the client is not Android. ") + factory_reset_timestamp: Optional[StrictInt] = Field(default=None, description="The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. When a factory reset cannot be detected on the mobile device or when the request is initiated from a browser, this field will correspond to the *epoch* time (i.e 1 Jan 1970 UTC) as a value of 0. See [Factory Reset Detection](https://docs.fingerprint.com/docs/smart-signals-reference#factory-reset-detection) to learn more about this Smart Signal. ") + frida: Optional[StrictBool] = Field(default=None, description="[Frida](https://frida.re/docs/) detection for Android and iOS devices. There are 2 values: * `true` - Frida detected * `false` - No signs of Frida or the client is not a mobile device. ") + ip_blocklist: Optional[IPBlockList] = None + proxy_ml_score: Optional[Union[Annotated[float, Field(le=1, strict=True, ge=0)], Annotated[int, Field(le=1, strict=True, ge=0)]]] = Field(default=None, description="Machine learning–based proxy score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `proxy` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ") + incognito: Optional[StrictBool] = Field(default=None, description="`true` if we detected incognito mode used in the browser, `false` otherwise. ") + jailbroken: Optional[StrictBool] = Field(default=None, description="iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. ") + location_spoofing: Optional[StrictBool] = Field(default=None, description="Flag indicating whether the request came from a mobile device with location spoofing enabled.") + mitm_attack: Optional[StrictBool] = Field(default=None, description="* `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://docs.fingerprint.com/docs/smart-signals-reference#mitm-attack-detection) to learn more about this Smart Signal. ") + privacy_settings: Optional[StrictBool] = Field(default=None, description="`true` if the request is from a privacy aware browser (e.g. Tor) or from a browser in which fingerprinting is blocked. Otherwise `false`. ") + root_apps: Optional[StrictBool] = Field(default=None, description="Android specific root management apps detection. There are 2 values: * `true` - Root Management Apps detected (e.g. Magisk). * `false` - No Root Management Apps detected or the client isn't Android. ") + rule_action: Optional[EventRuleAction] = None + simulator: Optional[StrictBool] = Field(default=None, description="iOS specific simulator detection. There are 2 values: * `true` - Simulator environment detected. * `false` - No signs of simulator or the client is not iOS. ") + suspect_score: Optional[StrictInt] = Field(default=None, description="Suspect Score is an easy way to integrate Smart Signals into your fraud protection work flow. It is a weighted representation of all Smart Signals present in the payload that helps identify suspicious activity. The value range is [0; S] where S is sum of all Smart Signals weights. See more details here: https://docs.fingerprint.com/docs/suspect-score ") + tampering: Optional[StrictBool] = Field(default=None, description="The field can be used as a standalone flag for tampering detection. Alternatively, the more granular fields documented below can be used for workflows that require more context. * `true` if tampering is detected through an anomalous browser signature, anti-detect browser detection, or other tampering-related methods * `false` if none of the tampering checks return a positive result ") + tampering_confidence: Optional[TamperingConfidence] = None + tampering_ml_score: Optional[Union[Annotated[float, Field(le=1, strict=True, ge=0)], Annotated[int, Field(le=1, strict=True, ge=0)]]] = Field(default=None, description="The output of this model is captured as tampering_ml_score, a number indicating how likely an event is coming from an anti detect browser. Values close to 1 signify higher confidence and we consider anything above the threshold of 0.8 to be actionable (the result and anti_detect_browser fields conveniently captures that fact) ") + tampering_details: Optional[TamperingDetails] = None + velocity: Optional[Velocity] = None + virtual_machine: Optional[StrictBool] = Field(default=None, description="`true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. ") + virtual_machine_ml_score: Optional[Union[Annotated[float, Field(le=1, strict=True, ge=0)], Annotated[int, Field(le=1, strict=True, ge=0)]]] = Field(default=None, description="Machine learning–based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ") + vpn_ml_score: Optional[Union[Annotated[float, Field(le=1, strict=True, ge=0)], Annotated[int, Field(le=1, strict=True, ge=0)]]] = Field(default=None, description="Machine learning–based VPN score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `vpn` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ") + vpn_origin_timezone: Optional[StrictStr] = Field(default=None, description="Local timezone which is used in timezone_mismatch method. ") + vpn_origin_country: Optional[StrictStr] = Field(default=None, description="Country of the request (Android SDK version >= 2.4.0, iOS SDK version >= 2.9.0, JS agent >= 3.12.9 / 4.0.2), ISO 3166 format or unknown. ") + high_activity_device: Optional[StrictBool] = Field(default=None, description="Flag indicating if the request came from a high-activity visitor.") + rare_device: Optional[StrictBool] = Field(default=None, description="`true` if the device is considered rare based on its combination of hardware and software attributes. A device is classified as rare if it falls within the top 99.9 percentile (lowest-frequency segment) of observed traffic, or if its configuration has not been previously seen (`not_seen`). > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ") + rare_device_percentile_bucket: Optional[RareDevicePercentileBucket] = None + raw_device_attributes: Optional[RawDeviceAttributes] = None + labels: Optional[List[LabelsInner]] = Field(default=None, description="Each label returns a prediction (true or false) for a specific use case (label field) based on a machine learning score. The machine learning score is determined by a model trained on customer data for that use case. This field is in the beta phase and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). ") + __properties: ClassVar[list[str]] = ['event_id', 'timestamp', 'linked_id', 'tags', 'url', 'bot_info', 'ip_info', 'proxy', 'proxy_confidence', 'proxy_details', 'vpn', 'vpn_confidence', 'vpn_methods', 'source', 'incremental_identification_status', 'environment_id', 'suspect', 'sdk', 'replayed', 'identification', 'supplementary_id_high_recall', 'bundle_id', 'package_name', 'ip_address', 'user_agent', 'device', 'os', 'os_version', 'client_referrer', 'browser_details', 'proximity', 'active_call', 'bot', 'bot_type', 'cloned_app', 'developer_tools', 'emulator', 'factory_reset_timestamp', 'frida', 'ip_blocklist', 'proxy_ml_score', 'incognito', 'jailbroken', 'location_spoofing', 'mitm_attack', 'privacy_settings', 'root_apps', 'rule_action', 'simulator', 'suspect_score', 'tampering', 'tampering_confidence', 'tampering_ml_score', 'tampering_details', 'velocity', 'virtual_machine', 'virtual_machine_ml_score', 'vpn_ml_score', 'vpn_origin_timezone', 'vpn_origin_country', 'high_activity_device', 'rare_device', 'rare_device_percentile_bucket', 'raw_device_attributes', 'labels'] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EventDevice from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of bot_info + if self.bot_info: + _dict['bot_info'] = self.bot_info.to_dict() + # override the default output from pydantic by calling `to_dict()` of ip_info + if self.ip_info: + _dict['ip_info'] = self.ip_info.to_dict() + # override the default output from pydantic by calling `to_dict()` of proxy_details + if self.proxy_details: + _dict['proxy_details'] = self.proxy_details.to_dict() + # override the default output from pydantic by calling `to_dict()` of vpn_methods + if self.vpn_methods: + _dict['vpn_methods'] = self.vpn_methods.to_dict() + # override the default output from pydantic by calling `to_dict()` of sdk + if self.sdk: + _dict['sdk'] = self.sdk.to_dict() + # override the default output from pydantic by calling `to_dict()` of identification + if self.identification: + _dict['identification'] = self.identification.to_dict() + # override the default output from pydantic by calling `to_dict()` of supplementary_id_high_recall + if self.supplementary_id_high_recall: + _dict['supplementary_id_high_recall'] = self.supplementary_id_high_recall.to_dict() + # override the default output from pydantic by calling `to_dict()` of browser_details + if self.browser_details: + _dict['browser_details'] = self.browser_details.to_dict() + # override the default output from pydantic by calling `to_dict()` of proximity + if self.proximity: + _dict['proximity'] = self.proximity.to_dict() + # override the default output from pydantic by calling `to_dict()` of ip_blocklist + if self.ip_blocklist: + _dict['ip_blocklist'] = self.ip_blocklist.to_dict() + # override the default output from pydantic by calling `to_dict()` of rule_action + if self.rule_action: + _dict['rule_action'] = self.rule_action.to_dict() + # override the default output from pydantic by calling `to_dict()` of tampering_details + if self.tampering_details: + _dict['tampering_details'] = self.tampering_details.to_dict() + # override the default output from pydantic by calling `to_dict()` of velocity + if self.velocity: + _dict['velocity'] = self.velocity.to_dict() + # override the default output from pydantic by calling `to_dict()` of raw_device_attributes + if self.raw_device_attributes: + _dict['raw_device_attributes'] = self.raw_device_attributes.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in labels (list) + _items = [] + if self.labels: + for _item_labels in self.labels: + if _item_labels: + _items.append(_item_labels.to_dict()) + _dict['labels'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: + """Create an instance of EventDevice from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "event_id": obj.get("event_id"), + "timestamp": obj.get("timestamp"), + "linked_id": obj.get("linked_id"), + "tags": obj.get("tags"), + "url": obj.get("url"), + "bot_info": BotInfo.from_dict(obj["bot_info"]) if obj.get("bot_info") is not None else None, + "ip_info": IPInfo.from_dict(obj["ip_info"]) if obj.get("ip_info") is not None else None, + "proxy": obj.get("proxy"), + "proxy_confidence": obj.get("proxy_confidence"), + "proxy_details": ProxyDetails.from_dict(obj["proxy_details"]) if obj.get("proxy_details") is not None else None, + "vpn": obj.get("vpn"), + "vpn_confidence": obj.get("vpn_confidence"), + "vpn_methods": VpnMethods.from_dict(obj["vpn_methods"]) if obj.get("vpn_methods") is not None else None, + "source": obj.get("source"), + "incremental_identification_status": obj.get("incremental_identification_status"), + "environment_id": obj.get("environment_id"), + "suspect": obj.get("suspect"), + "sdk": SDK.from_dict(obj["sdk"]) if obj.get("sdk") is not None else None, + "replayed": obj.get("replayed"), + "identification": Identification.from_dict(obj["identification"]) if obj.get("identification") is not None else None, + "supplementary_id_high_recall": SupplementaryIDHighRecall.from_dict(obj["supplementary_id_high_recall"]) if obj.get("supplementary_id_high_recall") is not None else None, + "bundle_id": obj.get("bundle_id"), + "package_name": obj.get("package_name"), + "ip_address": obj.get("ip_address"), + "user_agent": obj.get("user_agent"), + "device": obj.get("device"), + "os": obj.get("os"), + "os_version": obj.get("os_version"), + "client_referrer": obj.get("client_referrer"), + "browser_details": BrowserDetails.from_dict(obj["browser_details"]) if obj.get("browser_details") is not None else None, + "proximity": Proximity.from_dict(obj["proximity"]) if obj.get("proximity") is not None else None, + "active_call": obj.get("active_call"), + "bot": obj.get("bot"), + "bot_type": obj.get("bot_type"), + "cloned_app": obj.get("cloned_app"), + "developer_tools": obj.get("developer_tools"), + "emulator": obj.get("emulator"), + "factory_reset_timestamp": obj.get("factory_reset_timestamp"), + "frida": obj.get("frida"), + "ip_blocklist": IPBlockList.from_dict(obj["ip_blocklist"]) if obj.get("ip_blocklist") is not None else None, + "proxy_ml_score": obj.get("proxy_ml_score"), + "incognito": obj.get("incognito"), + "jailbroken": obj.get("jailbroken"), + "location_spoofing": obj.get("location_spoofing"), + "mitm_attack": obj.get("mitm_attack"), + "privacy_settings": obj.get("privacy_settings"), + "root_apps": obj.get("root_apps"), + "rule_action": EventRuleAction.from_dict(obj["rule_action"]) if obj.get("rule_action") is not None else None, + "simulator": obj.get("simulator"), + "suspect_score": obj.get("suspect_score"), + "tampering": obj.get("tampering"), + "tampering_confidence": obj.get("tampering_confidence"), + "tampering_ml_score": obj.get("tampering_ml_score"), + "tampering_details": TamperingDetails.from_dict(obj["tampering_details"]) if obj.get("tampering_details") is not None else None, + "velocity": Velocity.from_dict(obj["velocity"]) if obj.get("velocity") is not None else None, + "virtual_machine": obj.get("virtual_machine"), + "virtual_machine_ml_score": obj.get("virtual_machine_ml_score"), + "vpn_ml_score": obj.get("vpn_ml_score"), + "vpn_origin_timezone": obj.get("vpn_origin_timezone"), + "vpn_origin_country": obj.get("vpn_origin_country"), + "high_activity_device": obj.get("high_activity_device"), + "rare_device": obj.get("rare_device"), + "rare_device_percentile_bucket": obj.get("rare_device_percentile_bucket"), + "raw_device_attributes": RawDeviceAttributes.from_dict(obj["raw_device_attributes"]) if obj.get("raw_device_attributes") is not None else None, + "labels": [LabelsInner.from_dict(_item) for _item in obj["labels"]] if obj.get("labels") is not None else None + }) + return _obj + + diff --git a/fingerprint_server_sdk/models/event_edge.py b/fingerprint_server_sdk/models/event_edge.py new file mode 100644 index 00000000..b7a745f1 --- /dev/null +++ b/fingerprint_server_sdk/models/event_edge.py @@ -0,0 +1,133 @@ +""" +Server API +Fingerprint Server API allows you to get, search, and update Events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. +Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. +The API also supports collection of Automation Intelligence for requests to your server in edge, pre-origin, or middleware contexts. + +The version of the OpenAPI document: 4 +Contact: support@fingerprint.com +Generated by OpenAPI Generator (https://openapi-generator.tech) + +Do not edit the class manually. +""" # noqa: E501 + +from __future__ import annotations + +import json +import pprint +import re # noqa: F401 +from typing import Any, ClassVar, Optional + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from fingerprint_server_sdk.models.bot_info import BotInfo +from fingerprint_server_sdk.models.event_source import EventSource +from fingerprint_server_sdk.models.ip_info import IPInfo +from fingerprint_server_sdk.models.proxy_confidence import ProxyConfidence +from fingerprint_server_sdk.models.proxy_details import ProxyDetails +from fingerprint_server_sdk.models.vpn_confidence import VpnConfidence +from fingerprint_server_sdk.models.vpn_methods import VpnMethods +from typing_extensions import Self + + +class EventEdge(BaseModel): + """ + IP and bot analysis for an event generated by the Automation Intelligence API (`/edge` endpoint). No client-side collection agent is involved, so Identification (`visitor_id`) and device-telemetry-derived Smart Signals are not available. + """ + + event_id: StrictStr = Field(description="Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. ") + timestamp: StrictInt = Field(description="Timestamp of the event with millisecond precision in Unix time.") + linked_id: Optional[StrictStr] = Field(default=None, description="A customer-provided id that was sent with the request.") + tags: Optional[Dict[str, Any]] = Field(default=None, description="A customer-provided value or an object that was sent with the identification request or updated later.") + url: Optional[StrictStr] = Field(default=None, description="Page URL from which the request was sent.") + bot_info: Optional[BotInfo] = None + ip_info: IPInfo + proxy: Optional[StrictBool] = Field(default=None, description="IP address was used by a public proxy provider or belonged to a known recent residential proxy ") + proxy_confidence: Optional[ProxyConfidence] = None + proxy_details: Optional[ProxyDetails] = None + vpn: Optional[StrictBool] = Field(default=None, description="VPN or other anonymizing service has been used when sending the request. ") + vpn_confidence: Optional[VpnConfidence] = None + vpn_methods: Optional[VpnMethods] = None + source: EventSource + __properties: ClassVar[list[str]] = ['event_id', 'timestamp', 'linked_id', 'tags', 'url', 'bot_info', 'ip_info', 'proxy', 'proxy_confidence', 'proxy_details', 'vpn', 'vpn_confidence', 'vpn_methods', 'source'] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EventEdge from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of bot_info + if self.bot_info: + _dict['bot_info'] = self.bot_info.to_dict() + # override the default output from pydantic by calling `to_dict()` of ip_info + if self.ip_info: + _dict['ip_info'] = self.ip_info.to_dict() + # override the default output from pydantic by calling `to_dict()` of proxy_details + if self.proxy_details: + _dict['proxy_details'] = self.proxy_details.to_dict() + # override the default output from pydantic by calling `to_dict()` of vpn_methods + if self.vpn_methods: + _dict['vpn_methods'] = self.vpn_methods.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: + """Create an instance of EventEdge from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "event_id": obj.get("event_id"), + "timestamp": obj.get("timestamp"), + "linked_id": obj.get("linked_id"), + "tags": obj.get("tags"), + "url": obj.get("url"), + "bot_info": BotInfo.from_dict(obj["bot_info"]) if obj.get("bot_info") is not None else None, + "ip_info": IPInfo.from_dict(obj["ip_info"]) if obj.get("ip_info") is not None else None, + "proxy": obj.get("proxy"), + "proxy_confidence": obj.get("proxy_confidence"), + "proxy_details": ProxyDetails.from_dict(obj["proxy_details"]) if obj.get("proxy_details") is not None else None, + "vpn": obj.get("vpn"), + "vpn_confidence": obj.get("vpn_confidence"), + "vpn_methods": VpnMethods.from_dict(obj["vpn_methods"]) if obj.get("vpn_methods") is not None else None, + "source": obj.get("source") + }) + return _obj + + diff --git a/fingerprint_server_sdk/models/event_rule_action.py b/fingerprint_server_sdk/models/event_rule_action.py index 87eb5580..1f7bda78 100644 --- a/fingerprint_server_sdk/models/event_rule_action.py +++ b/fingerprint_server_sdk/models/event_rule_action.py @@ -12,49 +12,44 @@ """ # noqa: E501 from __future__ import annotations - import json import pprint from typing import Any, Optional, Union - -from pydantic import BaseModel, ConfigDict, ValidationError, field_validator -from typing_extensions import Self - +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Any, List, Optional from fingerprint_server_sdk.models.event_rule_action_allow import EventRuleActionAllow from fingerprint_server_sdk.models.event_rule_action_block import EventRuleActionBlock +from typing_extensions import Self +from fingerprint_server_sdk.event_source import hydrate_event_discriminator -EVENTRULEACTION_ONE_OF_SCHEMAS = ['EventRuleActionAllow', 'EventRuleActionBlock'] - +EVENTRULEACTION_ONE_OF_SCHEMAS = ["EventRuleActionAllow", "EventRuleActionBlock"] class EventRuleAction(BaseModel): """ Describes the action the client should take, according to the rule in the ruleset that matched the event. When getting an event by event ID, the rule_action will only be included when the ruleset_id query parameter is specified. """ - # data type: EventRuleActionAllow oneof_schema_1_validator: Optional[EventRuleActionAllow] = None # data type: EventRuleActionBlock oneof_schema_2_validator: Optional[EventRuleActionBlock] = None actual_instance: Optional[Union[EventRuleActionAllow, EventRuleActionBlock]] = None - one_of_schemas: set[str] = {'EventRuleActionAllow', 'EventRuleActionBlock'} + one_of_schemas: set[str] = { "EventRuleActionAllow", "EventRuleActionBlock" } model_config = ConfigDict( validate_assignment=True, protected_namespaces=(), ) - discriminator_value_class_map: dict[str, str] = {} + + discriminator_value_class_map: dict[str, str] = { + } def __init__(self, *args: Any, **kwargs: Any) -> None: if args: if len(args) > 1: - raise ValueError( - 'If a position argument is used, only 1 is allowed to set `actual_instance`' - ) + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") if kwargs: - raise ValueError( - 'If a position argument is used, keyword arguments cannot be used.' - ) + raise ValueError("If a position argument is used, keyword arguments cannot be used.") super().__init__(actual_instance=args[0]) else: super().__init__(**kwargs) @@ -66,26 +61,20 @@ def actual_instance_must_validate_oneof(cls, v: Any) -> Any: match = 0 # validate data type: EventRuleActionAllow if not isinstance(v, EventRuleActionAllow): - error_messages.append(f'Error! Input type `{type(v)}` is not `EventRuleActionAllow`') + error_messages.append(f"Error! Input type `{type(v)}` is not `EventRuleActionAllow`") else: match += 1 # validate data type: EventRuleActionBlock if not isinstance(v, EventRuleActionBlock): - error_messages.append(f'Error! Input type `{type(v)}` is not `EventRuleActionBlock`') + error_messages.append(f"Error! Input type `{type(v)}` is not `EventRuleActionBlock`") else: match += 1 if match > 1: # more than 1 match - raise ValueError( - 'Multiple matches found when setting `actual_instance` in EventRuleAction with oneOf schemas: EventRuleActionAllow, EventRuleActionBlock. Details: ' - + ', '.join(error_messages) - ) + raise ValueError("Multiple matches found when setting `actual_instance` in EventRuleAction with oneOf schemas: EventRuleActionAllow, EventRuleActionBlock. Details: " + ", ".join(error_messages)) elif match == 0: # no match - raise ValueError( - 'No match found when setting `actual_instance` in EventRuleAction with oneOf schemas: EventRuleActionAllow, EventRuleActionBlock. Details: ' - + ', '.join(error_messages) - ) + raise ValueError("No match found when setting `actual_instance` in EventRuleAction with oneOf schemas: EventRuleActionAllow, EventRuleActionBlock. Details: " + ", ".join(error_messages)) else: return v @@ -101,17 +90,17 @@ def from_json(cls, json_str: str) -> Self: match = 0 # use oneOf discriminator to lookup the data type - _data_type = json.loads(json_str).get('type') - if not _data_type: - raise ValueError('Failed to lookup data type from the field `type` in the input.') + json_str, _data_type = hydrate_event_discriminator("EventRuleAction", json_str, "type") + if "EventRuleAction" != "Event" and not _data_type: + raise ValueError("Failed to lookup data type from the field `type` in the input.") # check if data type is `EventRuleActionAllow` - if _data_type == 'allow': + if _data_type == "allow": instance.actual_instance = EventRuleActionAllow.from_json(json_str) return instance # check if data type is `EventRuleActionBlock` - if _data_type == 'block': + if _data_type == "block": instance.actual_instance = EventRuleActionBlock.from_json(json_str) return instance @@ -130,37 +119,29 @@ def from_json(cls, json_str: str) -> Self: if match > 1: # more than 1 match - raise ValueError( - 'Multiple matches found when deserializing the JSON string into EventRuleAction with oneOf schemas: EventRuleActionAllow, EventRuleActionBlock. Details: ' - + ', '.join(error_messages) - ) + raise ValueError("Multiple matches found when deserializing the JSON string into EventRuleAction with oneOf schemas: EventRuleActionAllow, EventRuleActionBlock. Details: " + ", ".join(error_messages)) elif match == 0: # no match - raise ValueError( - 'No match found when deserializing the JSON string into EventRuleAction with oneOf schemas: EventRuleActionAllow, EventRuleActionBlock. Details: ' - + ', '.join(error_messages) - ) + raise ValueError("No match found when deserializing the JSON string into EventRuleAction with oneOf schemas: EventRuleActionAllow, EventRuleActionBlock. Details: " + ", ".join(error_messages)) else: return instance def to_json(self) -> str: """Returns the JSON representation of the actual instance""" if self.actual_instance is None: - return 'null' + return "null" - if hasattr(self.actual_instance, 'to_json') and callable(self.actual_instance.to_json): + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): return self.actual_instance.to_json() else: return json.dumps(self.actual_instance) - def to_dict( - self, - ) -> Optional[Union[dict[str, Any], EventRuleActionAllow, EventRuleActionBlock]]: + def to_dict(self) -> Optional[Union[dict[str, Any], EventRuleActionAllow, EventRuleActionBlock]]: """Returns the dict representation of the actual instance""" if self.actual_instance is None: return None - if hasattr(self.actual_instance, 'to_dict') and callable(self.actual_instance.to_dict): + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): return self.actual_instance.to_dict() else: # primitive type @@ -169,3 +150,5 @@ def to_dict( def to_str(self) -> str: """Returns the string representation of the actual instance""" return pprint.pformat(self.model_dump()) + + diff --git a/fingerprint_server_sdk/models/event_rule_action_allow.py b/fingerprint_server_sdk/models/event_rule_action_allow.py index 0cdb614a..6f997ad6 100644 --- a/fingerprint_server_sdk/models/event_rule_action_allow.py +++ b/fingerprint_server_sdk/models/event_rule_action_allow.py @@ -19,10 +19,10 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.request_header_modifications import RequestHeaderModifications from fingerprint_server_sdk.models.rule_action_type import RuleActionType +from typing_extensions import Self class EventRuleActionAllow(BaseModel): @@ -30,23 +30,12 @@ class EventRuleActionAllow(BaseModel): Informs the client that the request should be forwarded to the origin with optional request header modifications. """ - ruleset_id: StrictStr = Field(description='The ID of the evaluated ruleset.') - rule_id: Optional[StrictStr] = Field( - default=None, description='The ID of the rule that matched the identification event.' - ) - rule_expression: Optional[StrictStr] = Field( - default=None, - description='The expression of the rule that matched the identification event.', - ) + ruleset_id: StrictStr = Field(description="The ID of the evaluated ruleset.") + rule_id: Optional[StrictStr] = Field(default=None, description="The ID of the rule that matched the identification event.") + rule_expression: Optional[StrictStr] = Field(default=None, description="The expression of the rule that matched the identification event.") type: RuleActionType request_header_modifications: Optional[RequestHeaderModifications] = None - __properties: ClassVar[list[str]] = [ - 'ruleset_id', - 'rule_id', - 'rule_expression', - 'type', - 'request_header_modifications', - ] + __properties: ClassVar[list[str]] = ['ruleset_id', 'rule_id', 'rule_expression', 'type', 'request_header_modifications'] model_config = ConfigDict( populate_by_name=True, @@ -78,7 +67,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -99,17 +89,13 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'ruleset_id': obj.get('ruleset_id'), - 'rule_id': obj.get('rule_id'), - 'rule_expression': obj.get('rule_expression'), - 'type': obj.get('type'), - 'request_header_modifications': RequestHeaderModifications.from_dict( - obj['request_header_modifications'] - ) - if obj.get('request_header_modifications') is not None - else None, - } - ) + _obj = cls.model_validate({ + "ruleset_id": obj.get("ruleset_id"), + "rule_id": obj.get("rule_id"), + "rule_expression": obj.get("rule_expression"), + "type": obj.get("type"), + "request_header_modifications": RequestHeaderModifications.from_dict(obj["request_header_modifications"]) if obj.get("request_header_modifications") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/event_rule_action_block.py b/fingerprint_server_sdk/models/event_rule_action_block.py index 09c86bbc..26b7c961 100644 --- a/fingerprint_server_sdk/models/event_rule_action_block.py +++ b/fingerprint_server_sdk/models/event_rule_action_block.py @@ -19,10 +19,10 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.rule_action_header_field import RuleActionHeaderField from fingerprint_server_sdk.models.rule_action_type import RuleActionType +from typing_extensions import Self class EventRuleActionBlock(BaseModel): @@ -30,31 +30,14 @@ class EventRuleActionBlock(BaseModel): Informs the client the request should be blocked using the response described by this rule action. """ - ruleset_id: StrictStr = Field(description='The ID of the evaluated ruleset.') - rule_id: Optional[StrictStr] = Field( - default=None, description='The ID of the rule that matched the identification event.' - ) - rule_expression: Optional[StrictStr] = Field( - default=None, - description='The expression of the rule that matched the identification event.', - ) + ruleset_id: StrictStr = Field(description="The ID of the evaluated ruleset.") + rule_id: Optional[StrictStr] = Field(default=None, description="The ID of the rule that matched the identification event.") + rule_expression: Optional[StrictStr] = Field(default=None, description="The expression of the rule that matched the identification event.") type: RuleActionType - status_code: Optional[StrictInt] = Field(default=None, description='A valid HTTP status code.') - headers: Optional[list[RuleActionHeaderField]] = Field( - default=None, description='A list of headers to send.' - ) - body: Optional[StrictStr] = Field( - default=None, description='The response body to send to the client.' - ) - __properties: ClassVar[list[str]] = [ - 'ruleset_id', - 'rule_id', - 'rule_expression', - 'type', - 'status_code', - 'headers', - 'body', - ] + status_code: Optional[StrictInt] = Field(default=None, description="A valid HTTP status code.") + headers: Optional[List[RuleActionHeaderField]] = Field(default=None, description="A list of headers to send.") + body: Optional[StrictStr] = Field(default=None, description="The response body to send to the client.") + __properties: ClassVar[list[str]] = ['ruleset_id', 'rule_id', 'rule_expression', 'type', 'status_code', 'headers', 'body'] model_config = ConfigDict( populate_by_name=True, @@ -86,7 +69,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -111,17 +95,15 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'ruleset_id': obj.get('ruleset_id'), - 'rule_id': obj.get('rule_id'), - 'rule_expression': obj.get('rule_expression'), - 'type': obj.get('type'), - 'status_code': obj.get('status_code'), - 'headers': [RuleActionHeaderField.from_dict(_item) for _item in obj['headers']] - if obj.get('headers') is not None - else None, - 'body': obj.get('body'), - } - ) + _obj = cls.model_validate({ + "ruleset_id": obj.get("ruleset_id"), + "rule_id": obj.get("rule_id"), + "rule_expression": obj.get("rule_expression"), + "type": obj.get("type"), + "status_code": obj.get("status_code"), + "headers": [RuleActionHeaderField.from_dict(_item) for _item in obj["headers"]] if obj.get("headers") is not None else None, + "body": obj.get("body") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/event_search.py b/fingerprint_server_sdk/models/event_search.py index cc4b64bb..9d44a9a1 100644 --- a/fingerprint_server_sdk/models/event_search.py +++ b/fingerprint_server_sdk/models/event_search.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.event import Event +from typing_extensions import Self class EventSearch(BaseModel): @@ -29,15 +29,9 @@ class EventSearch(BaseModel): Contains a list of all identification events matching the specified search criteria. """ - events: list[Event] - pagination_key: Optional[StrictStr] = Field( - default=None, - description='Use this value in the `pagination_key` parameter to request the next page of search results.', - ) - total_hits: Optional[StrictInt] = Field( - default=None, - description='This value represents the total number of events matching the search query, up to the limit provided in the `total_hits` query parameter. Only present if the `total_hits` query parameter was provided.', - ) + events: List[Event] + pagination_key: Optional[StrictStr] = Field(default=None, description="Use this value in the `pagination_key` parameter to request the next page of search results.") + total_hits: Optional[StrictInt] = Field(default=None, description="This value represents the total number of events matching the search query, up to the limit provided in the `total_hits` query parameter. Only present if the `total_hits` query parameter was provided.") __properties: ClassVar[list[str]] = ['events', 'pagination_key', 'total_hits'] model_config = ConfigDict( @@ -70,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -95,13 +90,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'events': [Event.from_dict(_item) for _item in obj['events']] - if obj.get('events') is not None - else None, - 'pagination_key': obj.get('pagination_key'), - 'total_hits': obj.get('total_hits'), - } - ) + _obj = cls.model_validate({ + "events": [Event.from_dict(_item) for _item in obj["events"]] if obj.get("events") is not None else None, + "pagination_key": obj.get("pagination_key"), + "total_hits": obj.get("total_hits") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/event_source.py b/fingerprint_server_sdk/models/event_source.py index 63622771..3d8e32a8 100644 --- a/fingerprint_server_sdk/models/event_source.py +++ b/fingerprint_server_sdk/models/event_source.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class EventSource(str, Enum): """ - Identifies how the event was generated. - `device` - the event was generated by the JS agent or a mobile SDK running on an end-user device. - `edge` - the event was generated by the Automation Intelligence API (`/edge` endpoint), analyzing a request intercepted at the edge. + Identifies how the event was generated. - `device` - the event was generated by the JS agent or a mobile SDK running on an end-user device. - `edge` - the event was generated by the Automation Intelligence API (`/edge` endpoint), analyzing a request intercepted at the edge. """ """ @@ -39,7 +37,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/event_update.py b/fingerprint_server_sdk/models/event_update.py index 7be0a16b..08dc9027 100644 --- a/fingerprint_server_sdk/models/event_update.py +++ b/fingerprint_server_sdk/models/event_update.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -27,16 +28,9 @@ class EventUpdate(BaseModel): EventUpdate """ - linked_id: Optional[StrictStr] = Field( - default=None, description='Linked ID value to assign to the existing event' - ) - tags: Optional[dict[str, Any]] = Field( - default=None, - description='A customer-provided value or an object that was sent with the identification request or updated later.', - ) - suspect: Optional[StrictBool] = Field( - default=None, description='Suspect flag indicating observed suspicious or fraudulent event' - ) + linked_id: Optional[StrictStr] = Field(default=None, description="Linked ID value to assign to the existing event") + tags: Optional[Dict[str, Any]] = Field(default=None, description="A customer-provided value or an object that was sent with the identification request or updated later.") + suspect: Optional[StrictBool] = Field(default=None, description="Suspect flag indicating observed suspicious or fraudulent event") __properties: ClassVar[list[str]] = ['linked_id', 'tags', 'suspect'] model_config = ConfigDict( @@ -69,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -87,11 +82,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'linked_id': obj.get('linked_id'), - 'tags': obj.get('tags'), - 'suspect': obj.get('suspect'), - } - ) + _obj = cls.model_validate({ + "linked_id": obj.get("linked_id"), + "tags": obj.get("tags"), + "suspect": obj.get("suspect") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/font_preferences.py b/fingerprint_server_sdk/models/font_preferences.py index 5d48869c..b50b6cfa 100644 --- a/fingerprint_server_sdk/models/font_preferences.py +++ b/fingerprint_server_sdk/models/font_preferences.py @@ -16,15 +16,16 @@ import json import pprint import re # noqa: F401 -from typing import Any, ClassVar, Optional, Union +from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt +from typing import Any, ClassVar, Dict, List, Optional, Union from typing_extensions import Self class FontPreferences(BaseModel): """ - Baseline measurement of canonical fonts rendered on the device. Numeric width metrics, in CSS pixels, for the canonical fonts collected by the agent. + Baseline measurement of canonical fonts rendered on the device. Numeric width metrics, in CSS pixels, for the canonical fonts collected by the agent. """ default: Optional[Union[StrictFloat, StrictInt]] = None @@ -34,15 +35,7 @@ class FontPreferences(BaseModel): apple: Optional[Union[StrictFloat, StrictInt]] = None min: Optional[Union[StrictFloat, StrictInt]] = None system: Optional[Union[StrictFloat, StrictInt]] = None - __properties: ClassVar[list[str]] = [ - 'default', - 'serif', - 'sans', - 'mono', - 'apple', - 'min', - 'system', - ] + __properties: ClassVar[list[str]] = ['default', 'serif', 'sans', 'mono', 'apple', 'min', 'system'] model_config = ConfigDict( populate_by_name=True, @@ -74,7 +67,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -92,15 +86,15 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'default': obj.get('default'), - 'serif': obj.get('serif'), - 'sans': obj.get('sans'), - 'mono': obj.get('mono'), - 'apple': obj.get('apple'), - 'min': obj.get('min'), - 'system': obj.get('system'), - } - ) + _obj = cls.model_validate({ + "default": obj.get("default"), + "serif": obj.get("serif"), + "sans": obj.get("sans"), + "mono": obj.get("mono"), + "apple": obj.get("apple"), + "min": obj.get("min"), + "system": obj.get("system") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/geolocation.py b/fingerprint_server_sdk/models/geolocation.py index 558e3434..8ed00c71 100644 --- a/fingerprint_server_sdk/models/geolocation.py +++ b/fingerprint_server_sdk/models/geolocation.py @@ -16,37 +16,23 @@ import json import pprint import re # noqa: F401 -from typing import Annotated, Any, ClassVar, Optional, Union +from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated +from fingerprint_server_sdk.models.geolocation_subdivisions_inner import GeolocationSubdivisionsInner from typing_extensions import Self -from fingerprint_server_sdk.models.geolocation_subdivisions_inner import ( - GeolocationSubdivisionsInner, -) - class Geolocation(BaseModel): """ Geolocation """ - accuracy_radius: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, - description='The IP address is likely to be within this radius (in km) of the specified location.', - ) - latitude: Optional[ - Union[ - Annotated[float, Field(le=90, strict=True, ge=-90)], - Annotated[int, Field(le=90, strict=True, ge=-90)], - ] - ] = None - longitude: Optional[ - Union[ - Annotated[float, Field(le=180, strict=True, ge=-180)], - Annotated[int, Field(le=180, strict=True, ge=-180)], - ] - ] = None + accuracy_radius: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=None, description="The IP address is likely to be within this radius (in km) of the specified location.") + latitude: Optional[Union[Annotated[float, Field(le=90, strict=True, ge=-90)], Annotated[int, Field(le=90, strict=True, ge=-90)]]] = None + longitude: Optional[Union[Annotated[float, Field(le=180, strict=True, ge=-180)], Annotated[int, Field(le=180, strict=True, ge=-180)]]] = None postal_code: Optional[StrictStr] = None timezone: Optional[StrictStr] = None city_name: Optional[StrictStr] = None @@ -54,20 +40,8 @@ class Geolocation(BaseModel): country_name: Optional[StrictStr] = None continent_code: Optional[Annotated[str, Field(min_length=2, strict=True, max_length=2)]] = None continent_name: Optional[StrictStr] = None - subdivisions: Optional[list[GeolocationSubdivisionsInner]] = None - __properties: ClassVar[list[str]] = [ - 'accuracy_radius', - 'latitude', - 'longitude', - 'postal_code', - 'timezone', - 'city_name', - 'country_code', - 'country_name', - 'continent_code', - 'continent_name', - 'subdivisions', - ] + subdivisions: Optional[List[GeolocationSubdivisionsInner]] = None + __properties: ClassVar[list[str]] = ['accuracy_radius', 'latitude', 'longitude', 'postal_code', 'timezone', 'city_name', 'country_code', 'country_name', 'continent_code', 'continent_name', 'subdivisions'] model_config = ConfigDict( populate_by_name=True, @@ -99,7 +73,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -124,23 +99,19 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'accuracy_radius': obj.get('accuracy_radius'), - 'latitude': obj.get('latitude'), - 'longitude': obj.get('longitude'), - 'postal_code': obj.get('postal_code'), - 'timezone': obj.get('timezone'), - 'city_name': obj.get('city_name'), - 'country_code': obj.get('country_code'), - 'country_name': obj.get('country_name'), - 'continent_code': obj.get('continent_code'), - 'continent_name': obj.get('continent_name'), - 'subdivisions': [ - GeolocationSubdivisionsInner.from_dict(_item) for _item in obj['subdivisions'] - ] - if obj.get('subdivisions') is not None - else None, - } - ) + _obj = cls.model_validate({ + "accuracy_radius": obj.get("accuracy_radius"), + "latitude": obj.get("latitude"), + "longitude": obj.get("longitude"), + "postal_code": obj.get("postal_code"), + "timezone": obj.get("timezone"), + "city_name": obj.get("city_name"), + "country_code": obj.get("country_code"), + "country_name": obj.get("country_name"), + "continent_code": obj.get("continent_code"), + "continent_name": obj.get("continent_name"), + "subdivisions": [GeolocationSubdivisionsInner.from_dict(_item) for _item in obj["subdivisions"]] if obj.get("subdivisions") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/geolocation_subdivisions_inner.py b/fingerprint_server_sdk/models/geolocation_subdivisions_inner.py index 74daa924..1a93311e 100644 --- a/fingerprint_server_sdk/models/geolocation_subdivisions_inner.py +++ b/fingerprint_server_sdk/models/geolocation_subdivisions_inner.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List from typing_extensions import Self @@ -61,7 +62,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -79,5 +81,10 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({'iso_code': obj.get('iso_code'), 'name': obj.get('name')}) + _obj = cls.model_validate({ + "iso_code": obj.get("iso_code"), + "name": obj.get("name") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/identification.py b/fingerprint_server_sdk/models/identification.py index 90819cce..30d4f4b1 100644 --- a/fingerprint_server_sdk/models/identification.py +++ b/fingerprint_server_sdk/models/identification.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.identification_confidence import IdentificationConfidence +from typing_extensions import Self class Identification(BaseModel): @@ -29,28 +29,12 @@ class Identification(BaseModel): Identification """ - visitor_id: StrictStr = Field( - description="String of 20 characters that uniquely identifies the visitor's browser or mobile device." - ) + visitor_id: StrictStr = Field(description="String of 20 characters that uniquely identifies the visitor's browser or mobile device.") confidence: Optional[IdentificationConfidence] = None - visitor_found: StrictBool = Field( - description='Attribute represents if a visitor had been identified before.' - ) - first_seen_at: Optional[StrictInt] = Field( - default=None, - description='Unix epoch time milliseconds timestamp indicating the time at which this visitor ID was first seen. example: `1758069706642` - Corresponding to Wed Sep 17 2025 00:41:46 GMT+0000 ', - ) - last_seen_at: Optional[StrictInt] = Field( - default=None, - description='Unix epoch time milliseconds timestamp indicating the time at which this visitor ID was last seen. example: `1758069706642` - Corresponding to Wed Sep 17 2025 00:41:46 GMT+0000 ', - ) - __properties: ClassVar[list[str]] = [ - 'visitor_id', - 'confidence', - 'visitor_found', - 'first_seen_at', - 'last_seen_at', - ] + visitor_found: StrictBool = Field(description="Attribute represents if a visitor had been identified before.") + first_seen_at: Optional[StrictInt] = Field(default=None, description="Unix epoch time milliseconds timestamp indicating the time at which this visitor ID was first seen. example: `1758069706642` - Corresponding to Wed Sep 17 2025 00:41:46 GMT+0000 ") + last_seen_at: Optional[StrictInt] = Field(default=None, description="Unix epoch time milliseconds timestamp indicating the time at which this visitor ID was last seen. example: `1758069706642` - Corresponding to Wed Sep 17 2025 00:41:46 GMT+0000 ") + __properties: ClassVar[list[str]] = ['visitor_id', 'confidence', 'visitor_found', 'first_seen_at', 'last_seen_at'] model_config = ConfigDict( populate_by_name=True, @@ -82,7 +66,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -103,15 +88,13 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'visitor_id': obj.get('visitor_id'), - 'confidence': IdentificationConfidence.from_dict(obj['confidence']) - if obj.get('confidence') is not None - else None, - 'visitor_found': obj.get('visitor_found'), - 'first_seen_at': obj.get('first_seen_at'), - 'last_seen_at': obj.get('last_seen_at'), - } - ) + _obj = cls.model_validate({ + "visitor_id": obj.get("visitor_id"), + "confidence": IdentificationConfidence.from_dict(obj["confidence"]) if obj.get("confidence") is not None else None, + "visitor_found": obj.get("visitor_found"), + "first_seen_at": obj.get("first_seen_at"), + "last_seen_at": obj.get("last_seen_at") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/identification_confidence.py b/fingerprint_server_sdk/models/identification_confidence.py index 1192c695..bccd87d6 100644 --- a/fingerprint_server_sdk/models/identification_confidence.py +++ b/fingerprint_server_sdk/models/identification_confidence.py @@ -16,27 +16,21 @@ import json import pprint import re # noqa: F401 -from typing import Annotated, Any, ClassVar, Optional, Union +from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated from typing_extensions import Self class IdentificationConfidence(BaseModel): """ - The confidence score represents the probability of a false-positive identification. To learn more, visit [Confidence Score](https://docs.fingerprint.com/docs/identification-accuracy-and-confidence#confidence-score). Please note that the confidence score is not yet supported for [High Recall ID](https://docs.fingerprint.com/docs/supplementary-identifiers-highrecall). + The confidence score represents the probability of a false-positive identification. To learn more, visit [Confidence Score](https://docs.fingerprint.com/docs/identification-accuracy-and-confidence#confidence-score). Please note that the confidence score is not yet supported for [High Recall ID](https://docs.fingerprint.com/docs/supplementary-identifiers-highrecall). """ - score: Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] = Field( - description='A floating-point number between 0 and 1 that represents the probability of a false-positive identification. For High Recall ID, this value is 0. ' - ) - version: Optional[StrictStr] = Field( - default=None, - description='The version name of the method used to calculate the confidence score. For High Recall ID, this value is "Not Supported". ', - ) + score: Union[Annotated[float, Field(le=1, strict=True, ge=0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="A floating-point number between 0 and 1 that represents the probability of a false-positive identification. For High Recall ID, this value is 0. ") + version: Optional[StrictStr] = Field(default=None, description="The version name of the method used to calculate the confidence score. For High Recall ID, this value is \"Not Supported\". ") comment: Optional[StrictStr] = None __properties: ClassVar[list[str]] = ['score', 'version', 'comment'] @@ -70,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -88,11 +83,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'score': obj.get('score'), - 'version': obj.get('version'), - 'comment': obj.get('comment'), - } - ) + _obj = cls.model_validate({ + "score": obj.get("score"), + "version": obj.get("version"), + "comment": obj.get("comment") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/incremental_identification_status.py b/fingerprint_server_sdk/models/incremental_identification_status.py index fd180dda..b83ea4a4 100644 --- a/fingerprint_server_sdk/models/incremental_identification_status.py +++ b/fingerprint_server_sdk/models/incremental_identification_status.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class IncrementalIdentificationStatus(str, Enum): """ - Only included for requests using incremental identification. - `partially_completed` - Indicates this event corresponds to a 'minimal' request. Smart Signals, even if included in your plan, are not computed; hence, their values must be ignored. - `completed` - Indicates this event corresponds to a 'complete' request. Smart Signals, if included in your plan, are computed; hence, their values are valid and relevant. + Only included for requests using incremental identification. - `partially_completed` - Indicates this event corresponds to a 'minimal' request. Smart Signals, even if included in your plan, are not computed; hence, their values must be ignored. - `completed` - Indicates this event corresponds to a 'complete' request. Smart Signals, if included in your plan, are computed; hence, their values are valid and relevant. """ """ @@ -39,7 +37,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/integration.py b/fingerprint_server_sdk/models/integration.py index 14174ea3..319dcf9f 100644 --- a/fingerprint_server_sdk/models/integration.py +++ b/fingerprint_server_sdk/models/integration.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.integration_subintegration import IntegrationSubintegration +from typing_extensions import Self class Integration(BaseModel): @@ -29,12 +29,8 @@ class Integration(BaseModel): Integration """ - name: Optional[StrictStr] = Field( - default=None, description='The name of the specific integration.' - ) - version: Optional[StrictStr] = Field( - default=None, description='The version of the specific integration.' - ) + name: Optional[StrictStr] = Field(default=None, description="The name of the specific integration.") + version: Optional[StrictStr] = Field(default=None, description="The version of the specific integration.") subintegration: Optional[IntegrationSubintegration] = None __properties: ClassVar[list[str]] = ['name', 'version', 'subintegration'] @@ -68,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -89,13 +86,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'name': obj.get('name'), - 'version': obj.get('version'), - 'subintegration': IntegrationSubintegration.from_dict(obj['subintegration']) - if obj.get('subintegration') is not None - else None, - } - ) + _obj = cls.model_validate({ + "name": obj.get("name"), + "version": obj.get("version"), + "subintegration": IntegrationSubintegration.from_dict(obj["subintegration"]) if obj.get("subintegration") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/integration_subintegration.py b/fingerprint_server_sdk/models/integration_subintegration.py index a9251237..30974d3c 100644 --- a/fingerprint_server_sdk/models/integration_subintegration.py +++ b/fingerprint_server_sdk/models/integration_subintegration.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -27,12 +28,8 @@ class IntegrationSubintegration(BaseModel): IntegrationSubintegration """ - name: Optional[StrictStr] = Field( - default=None, description='The name of the specific subintegration.' - ) - version: Optional[StrictStr] = Field( - default=None, description='The version of the specific subintegration.' - ) + name: Optional[StrictStr] = Field(default=None, description="The name of the specific subintegration.") + version: Optional[StrictStr] = Field(default=None, description="The version of the specific subintegration.") __properties: ClassVar[list[str]] = ['name', 'version'] model_config = ConfigDict( @@ -65,7 +62,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -83,5 +81,10 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({'name': obj.get('name'), 'version': obj.get('version')}) + _obj = cls.model_validate({ + "name": obj.get("name"), + "version": obj.get("version") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/ip_block_list.py b/fingerprint_server_sdk/models/ip_block_list.py index dff11f73..6d496010 100644 --- a/fingerprint_server_sdk/models/ip_block_list.py +++ b/fingerprint_server_sdk/models/ip_block_list.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -27,15 +28,9 @@ class IPBlockList(BaseModel): IPBlockList """ - email_spam: Optional[StrictBool] = Field( - default=None, description='IP address was part of a known email spam attack (SMTP).' - ) - attack_source: Optional[StrictBool] = Field( - default=None, description='IP address was part of a known network attack (SSH/HTTPS).' - ) - tor_node: Optional[StrictBool] = Field( - default=None, description='IP address was part of known TOR network activity.' - ) + email_spam: Optional[StrictBool] = Field(default=None, description="IP address was part of a known email spam attack (SMTP).") + attack_source: Optional[StrictBool] = Field(default=None, description="IP address was part of a known network attack (SSH/HTTPS).") + tor_node: Optional[StrictBool] = Field(default=None, description="IP address was part of known TOR network activity.") __properties: ClassVar[list[str]] = ['email_spam', 'attack_source', 'tor_node'] model_config = ConfigDict( @@ -68,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -86,11 +82,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'email_spam': obj.get('email_spam'), - 'attack_source': obj.get('attack_source'), - 'tor_node': obj.get('tor_node'), - } - ) + _obj = cls.model_validate({ + "email_spam": obj.get("email_spam"), + "attack_source": obj.get("attack_source"), + "tor_node": obj.get("tor_node") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/ip_info.py b/fingerprint_server_sdk/models/ip_info.py index 0e885640..a32b063c 100644 --- a/fingerprint_server_sdk/models/ip_info.py +++ b/fingerprint_server_sdk/models/ip_info.py @@ -19,10 +19,10 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.ip_info_v4 import IPInfoV4 from fingerprint_server_sdk.models.ip_info_v6 import IPInfoV6 +from typing_extensions import Self class IPInfo(BaseModel): @@ -64,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -88,10 +89,10 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'v4': IPInfoV4.from_dict(obj['v4']) if obj.get('v4') is not None else None, - 'v6': IPInfoV6.from_dict(obj['v6']) if obj.get('v6') is not None else None, - } - ) + _obj = cls.model_validate({ + "v4": IPInfoV4.from_dict(obj["v4"]) if obj.get("v4") is not None else None, + "v6": IPInfoV6.from_dict(obj["v6"]) if obj.get("v6") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/ip_info_v4.py b/fingerprint_server_sdk/models/ip_info_v4.py index 3a04b812..93bda184 100644 --- a/fingerprint_server_sdk/models/ip_info_v4.py +++ b/fingerprint_server_sdk/models/ip_info_v4.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.geolocation import Geolocation +from typing_extensions import Self class IPInfoV4(BaseModel): @@ -35,20 +35,9 @@ class IPInfoV4(BaseModel): asn_name: Optional[StrictStr] = None asn_network: Optional[StrictStr] = None asn_type: Optional[StrictStr] = None - datacenter_result: Optional[StrictBool] = Field( - default=None, description='When true, the request originated from a datacenter.' - ) + datacenter_result: Optional[StrictBool] = Field(default=None, description="When true, the request originated from a datacenter.") datacenter_name: Optional[StrictStr] = None - __properties: ClassVar[list[str]] = [ - 'address', - 'geolocation', - 'asn', - 'asn_name', - 'asn_network', - 'asn_type', - 'datacenter_result', - 'datacenter_name', - ] + __properties: ClassVar[list[str]] = ['address', 'geolocation', 'asn', 'asn_name', 'asn_network', 'asn_type', 'datacenter_result', 'datacenter_name'] model_config = ConfigDict( populate_by_name=True, @@ -80,7 +69,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -101,18 +91,16 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'address': obj.get('address'), - 'geolocation': Geolocation.from_dict(obj['geolocation']) - if obj.get('geolocation') is not None - else None, - 'asn': obj.get('asn'), - 'asn_name': obj.get('asn_name'), - 'asn_network': obj.get('asn_network'), - 'asn_type': obj.get('asn_type'), - 'datacenter_result': obj.get('datacenter_result'), - 'datacenter_name': obj.get('datacenter_name'), - } - ) + _obj = cls.model_validate({ + "address": obj.get("address"), + "geolocation": Geolocation.from_dict(obj["geolocation"]) if obj.get("geolocation") is not None else None, + "asn": obj.get("asn"), + "asn_name": obj.get("asn_name"), + "asn_network": obj.get("asn_network"), + "asn_type": obj.get("asn_type"), + "datacenter_result": obj.get("datacenter_result"), + "datacenter_name": obj.get("datacenter_name") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/ip_info_v6.py b/fingerprint_server_sdk/models/ip_info_v6.py index 04a736ca..17b580cb 100644 --- a/fingerprint_server_sdk/models/ip_info_v6.py +++ b/fingerprint_server_sdk/models/ip_info_v6.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.geolocation import Geolocation +from typing_extensions import Self class IPInfoV6(BaseModel): @@ -35,20 +35,9 @@ class IPInfoV6(BaseModel): asn_name: Optional[StrictStr] = None asn_network: Optional[StrictStr] = None asn_type: Optional[StrictStr] = None - datacenter_result: Optional[StrictBool] = Field( - default=None, description='When true, the request originated from a datacenter.' - ) + datacenter_result: Optional[StrictBool] = Field(default=None, description="When true, the request originated from a datacenter.") datacenter_name: Optional[StrictStr] = None - __properties: ClassVar[list[str]] = [ - 'address', - 'geolocation', - 'asn', - 'asn_name', - 'asn_network', - 'asn_type', - 'datacenter_result', - 'datacenter_name', - ] + __properties: ClassVar[list[str]] = ['address', 'geolocation', 'asn', 'asn_name', 'asn_network', 'asn_type', 'datacenter_result', 'datacenter_name'] model_config = ConfigDict( populate_by_name=True, @@ -80,7 +69,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -101,18 +91,16 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'address': obj.get('address'), - 'geolocation': Geolocation.from_dict(obj['geolocation']) - if obj.get('geolocation') is not None - else None, - 'asn': obj.get('asn'), - 'asn_name': obj.get('asn_name'), - 'asn_network': obj.get('asn_network'), - 'asn_type': obj.get('asn_type'), - 'datacenter_result': obj.get('datacenter_result'), - 'datacenter_name': obj.get('datacenter_name'), - } - ) + _obj = cls.model_validate({ + "address": obj.get("address"), + "geolocation": Geolocation.from_dict(obj["geolocation"]) if obj.get("geolocation") is not None else None, + "asn": obj.get("asn"), + "asn_name": obj.get("asn_name"), + "asn_network": obj.get("asn_network"), + "asn_type": obj.get("asn_type"), + "datacenter_result": obj.get("datacenter_result"), + "datacenter_name": obj.get("datacenter_name") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/labels_inner.py b/fingerprint_server_sdk/models/labels_inner.py index ab78a903..689c96d2 100644 --- a/fingerprint_server_sdk/models/labels_inner.py +++ b/fingerprint_server_sdk/models/labels_inner.py @@ -16,9 +16,11 @@ import json import pprint import re # noqa: F401 -from typing import Annotated, Any, ClassVar, Optional, Union +from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated from typing_extensions import Self @@ -29,12 +31,7 @@ class LabelsInner(BaseModel): label: StrictStr prediction: Optional[StrictBool] = None - ml_score: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = None + ml_score: Optional[Union[Annotated[float, Field(le=1, strict=True, ge=0)], Annotated[int, Field(le=1, strict=True, ge=0)]]] = None __properties: ClassVar[list[str]] = ['label', 'prediction', 'ml_score'] model_config = ConfigDict( @@ -67,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -85,11 +83,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'label': obj.get('label'), - 'prediction': obj.get('prediction'), - 'ml_score': obj.get('ml_score'), - } - ) + _obj = cls.model_validate({ + "label": obj.get("label"), + "prediction": obj.get("prediction"), + "ml_score": obj.get("ml_score") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/plugins_inner.py b/fingerprint_server_sdk/models/plugins_inner.py index c0e110d9..a1e3bdaa 100644 --- a/fingerprint_server_sdk/models/plugins_inner.py +++ b/fingerprint_server_sdk/models/plugins_inner.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.plugins_inner_mime_types_inner import PluginsInnerMimeTypesInner +from typing_extensions import Self class PluginsInner(BaseModel): @@ -31,7 +31,7 @@ class PluginsInner(BaseModel): name: StrictStr description: Optional[StrictStr] = None - mime_types: Optional[list[PluginsInnerMimeTypesInner]] = Field(default=None, alias='mimeTypes') + mime_types: Optional[List[PluginsInnerMimeTypesInner]] = Field(default=None, alias="mimeTypes") __properties: ClassVar[list[str]] = ['name', 'description', 'mimeTypes'] model_config = ConfigDict( @@ -64,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -89,15 +90,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'name': obj.get('name'), - 'description': obj.get('description'), - 'mimeTypes': [ - PluginsInnerMimeTypesInner.from_dict(_item) for _item in obj['mimeTypes'] - ] - if obj.get('mimeTypes') is not None - else None, - } - ) + _obj = cls.model_validate({ + "name": obj.get("name"), + "description": obj.get("description"), + "mimeTypes": [PluginsInnerMimeTypesInner.from_dict(_item) for _item in obj["mimeTypes"]] if obj.get("mimeTypes") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/plugins_inner_mime_types_inner.py b/fingerprint_server_sdk/models/plugins_inner_mime_types_inner.py index 0c950e01..f6688765 100644 --- a/fingerprint_server_sdk/models/plugins_inner_mime_types_inner.py +++ b/fingerprint_server_sdk/models/plugins_inner_mime_types_inner.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -62,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -80,11 +82,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'type': obj.get('type'), - 'suffixes': obj.get('suffixes'), - 'description': obj.get('description'), - } - ) + _obj = cls.model_validate({ + "type": obj.get("type"), + "suffixes": obj.get("suffixes"), + "description": obj.get("description") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/proximity.py b/fingerprint_server_sdk/models/proximity.py index 63285165..877afd49 100644 --- a/fingerprint_server_sdk/models/proximity.py +++ b/fingerprint_server_sdk/models/proximity.py @@ -16,29 +16,22 @@ import json import pprint import re # noqa: F401 -from typing import Annotated, Any, ClassVar, Optional, Union +from typing import Any, ClassVar, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Union +from typing_extensions import Annotated from typing_extensions import Self class Proximity(BaseModel): """ - Proximity ID represents a fixed geographical zone in a discrete global grid within which the device is observed. + Proximity ID represents a fixed geographical zone in a discrete global grid within which the device is observed. """ - id: StrictStr = Field( - description='A stable privacy-preserving identifier for a given proximity zone. ' - ) - precision_radius: StrictInt = Field( - description='The radius of the proximity zone’s precision level, in meters. ' - ) - confidence: Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] = Field( - description='A value between `0` and `1` representing the likelihood that the true device location lies within the mapped proximity zone. * Scores closer to `1` indicate high confidence that the location is inside the mapped proximity zone. * Scores closer to `0` indicate lower confidence, suggesting the true location may fall in an adjacent zone. ' - ) + id: StrictStr = Field(description="A stable privacy-preserving identifier for a given proximity zone. ") + precision_radius: StrictInt = Field(description="The radius of the proximity zone’s precision level, in meters. ") + confidence: Union[Annotated[float, Field(le=1, strict=True, ge=0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="A value between `0` and `1` representing the likelihood that the true device location lies within the mapped proximity zone. * Scores closer to `1` indicate high confidence that the location is inside the mapped proximity zone. * Scores closer to `0` indicate lower confidence, suggesting the true location may fall in an adjacent zone. ") __properties: ClassVar[list[str]] = ['id', 'precision_radius', 'confidence'] model_config = ConfigDict( @@ -71,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -89,11 +83,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'id': obj.get('id'), - 'precision_radius': obj.get('precision_radius'), - 'confidence': obj.get('confidence'), - } - ) + _obj = cls.model_validate({ + "id": obj.get("id"), + "precision_radius": obj.get("precision_radius"), + "confidence": obj.get("confidence") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/proxy_confidence.py b/fingerprint_server_sdk/models/proxy_confidence.py index bcbd65a5..6d27d9d4 100644 --- a/fingerprint_server_sdk/models/proxy_confidence.py +++ b/fingerprint_server_sdk/models/proxy_confidence.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class ProxyConfidence(str, Enum): """ - Confidence level of the proxy detection. If a proxy is not detected, confidence is \"high\". If it's detected, can be \"low\", \"medium\", or \"high\". + Confidence level of the proxy detection. If a proxy is not detected, confidence is \"high\". If it's detected, can be \"low\", \"medium\", or \"high\". """ """ @@ -40,7 +38,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/proxy_details.py b/fingerprint_server_sdk/models/proxy_details.py index ad2ae8ff..7663f9b8 100644 --- a/fingerprint_server_sdk/models/proxy_details.py +++ b/fingerprint_server_sdk/models/proxy_details.py @@ -18,7 +18,8 @@ import re # noqa: F401 from typing import Any, ClassVar, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -27,17 +28,9 @@ class ProxyDetails(BaseModel): Proxy detection details (present if `proxy` is `true`) """ - proxy_type: StrictStr = Field( - description='Proxy type: * `residential` - proxies that route through residential and telecom IP addresses to appear as legitimate traffic * `data_center` - proxies which route through data centers * `unknown` - reported when a proxy is detected solely by the ML model and the IP sources did not determine a specific type ' - ) - last_seen_at: Optional[StrictInt] = Field( - default=None, - description='Unix millisecond timestamp with hourly resolution of when this IP was last seen as a proxy ', - ) - provider: Optional[StrictStr] = Field( - default=None, - description='String representing the last proxy service provider detected when this IP was synced. An IP can be shared by multiple service providers. ', - ) + proxy_type: StrictStr = Field(description="Proxy type: * `residential` - proxies that route through residential and telecom IP addresses to appear as legitimate traffic * `data_center` - proxies which route through data centers * `unknown` - reported when a proxy is detected solely by the ML model and the IP sources did not determine a specific type ") + last_seen_at: Optional[StrictInt] = Field(default=None, description="Unix millisecond timestamp with hourly resolution of when this IP was last seen as a proxy ") + provider: Optional[StrictStr] = Field(default=None, description="String representing the last proxy service provider detected when this IP was synced. An IP can be shared by multiple service providers. ") __properties: ClassVar[list[str]] = ['proxy_type', 'last_seen_at', 'provider'] model_config = ConfigDict( @@ -70,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -88,11 +82,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'proxy_type': obj.get('proxy_type'), - 'last_seen_at': obj.get('last_seen_at'), - 'provider': obj.get('provider'), - } - ) + _obj = cls.model_validate({ + "proxy_type": obj.get("proxy_type"), + "last_seen_at": obj.get("last_seen_at"), + "provider": obj.get("provider") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py index ebfad2d7..1010f5b1 100644 --- a/fingerprint_server_sdk/models/rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/rare_device_percentile_bucket.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class RareDevicePercentileBucket(str, Enum): """ - The rarity percentile bucket of the device, indicating how uncommon the device configuration is compared to all observed devices. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). + The rarity percentile bucket of the device, indicating how uncommon the device configuration is compared to all observed devices. > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). """ """ @@ -43,7 +41,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/raw_device_attributes.py b/fingerprint_server_sdk/models/raw_device_attributes.py index 424f9528..3525ac5a 100644 --- a/fingerprint_server_sdk/models/raw_device_attributes.py +++ b/fingerprint_server_sdk/models/raw_device_attributes.py @@ -16,11 +16,11 @@ import json import pprint import re # noqa: F401 -from typing import Annotated, Any, ClassVar, Optional, Union +from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated from fingerprint_server_sdk.models.canvas import Canvas from fingerprint_server_sdk.models.emoji import Emoji from fingerprint_server_sdk.models.font_preferences import FontPreferences @@ -28,148 +28,49 @@ from fingerprint_server_sdk.models.touch_support import TouchSupport from fingerprint_server_sdk.models.web_gl_basics import WebGlBasics from fingerprint_server_sdk.models.web_gl_extensions import WebGlExtensions +from typing_extensions import Self class RawDeviceAttributes(BaseModel): """ - A curated subset of raw browser/device attributes that the API surface exposes. Each property contains a value or object with the data for the collected signal. + A curated subset of raw browser/device attributes that the API surface exposes. Each property contains a value or object with the data for the collected signal. """ font_preferences: Optional[FontPreferences] = None emoji: Optional[Emoji] = None - fonts: Optional[list[StrictStr]] = Field( - default=None, description='List of fonts detected on the device.' - ) - device_memory: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( - default=None, - description='Rounded amount of RAM in gigabytes. Available for browsers, Android, and iOS devices.', - ) - timezone: Optional[StrictStr] = Field( - default=None, description='Timezone identifier detected on the client.' - ) + fonts: Optional[List[StrictStr]] = Field(default=None, description="List of fonts detected on the device.") + device_memory: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=None, description="Rounded amount of RAM in gigabytes. Available for browsers, Android, and iOS devices.") + timezone: Optional[StrictStr] = Field(default=None, description="Timezone identifier detected on the client.") canvas: Optional[Canvas] = None - languages: Optional[list[list[StrictStr]]] = Field( - default=None, - description='Navigator languages reported by the agent including fallbacks. Each inner array represents ordered language preferences reported by different APIs. Available for browsers, iOS, and Android devices. ', - ) + languages: Optional[List[List[StrictStr]]] = Field(default=None, description="Navigator languages reported by the agent including fallbacks. Each inner array represents ordered language preferences reported by different APIs. Available for browsers, iOS, and Android devices. ") webgl_extensions: Optional[WebGlExtensions] = None webgl_basics: Optional[WebGlBasics] = None - screen_resolution: Optional[Annotated[list[StrictInt], Field(min_length=2, max_length=2)]] = ( - Field( - default=None, - description='Current screen resolution. Available for both browsers and iOS devices', - ) - ) + screen_resolution: Optional[Annotated[List[StrictInt], Field(min_length=2, max_length=2)]] = Field(default=None, description="Current screen resolution. Available for both browsers and iOS devices") touch_support: Optional[TouchSupport] = None - oscpu: Optional[StrictStr] = Field(default=None, description='Navigator `oscpu` string.') - architecture: Optional[StrictInt] = Field( - default=None, - description='Integer representing the CPU architecture exposed by the browser.', - ) - cookies_enabled: Optional[StrictBool] = Field( - default=None, description='Whether the cookies are enabled in the browser.' - ) - hardware_concurrency: Optional[StrictInt] = Field( - default=None, description='Number of logical CPU cores reported by the browser.' - ) - date_time_locale: Optional[StrictStr] = Field( - default=None, - description='Locale derived from the Intl.DateTimeFormat API. Negative values indicate known error states. The negative statuses can be: - "-1": A permanent status for browsers that don\'t support Intl API. - "-2": A permanent status for browsers that don\'t supportDateTimeFormat constructor. - "-3": A permanent status for browsers in which DateTimeFormat locale is undefined or null. ', - ) - vendor: Optional[StrictStr] = Field(default=None, description='Navigator vendor string.') - color_depth: Optional[StrictInt] = Field( - default=None, description='Screen color depth in bits.' - ) - platform: Optional[StrictStr] = Field(default=None, description='Navigator platform string.') - session_storage: Optional[StrictBool] = Field( - default=None, description='Whether sessionStorage is available.' - ) - local_storage: Optional[StrictBool] = Field( - default=None, description='Whether localStorage is available.' - ) - audio: Optional[Union[StrictFloat, StrictInt]] = Field( - default=None, - description="AudioContext fingerprint or negative status when unavailable. The negative statuses can be: - -1: A permanent status for those browsers which are known to always suspend audio context - -2: A permanent status for browsers that don't support the signal - -3: A temporary status that means that an unexpected timeout has happened ", - ) - plugins: Optional[list[PluginsInner]] = Field( - default=None, description='Browser plugins reported by `navigator.plugins`.' - ) - indexed_db: Optional[StrictBool] = Field( - default=None, description='Whether IndexedDB is available.' - ) - math: Optional[StrictStr] = Field( - default=None, description='Hash of Math APIs used for entropy collection.' - ) - device_model: Optional[StrictStr] = Field( - default=None, - description='Device model string. Available only for Android and iOS devices.', - ) - device_manufacturer: Optional[StrictStr] = Field( - default=None, - description='Device manufacturer string. Available only for Android and iOS devices.', - ) - font_hash: Optional[StrictStr] = Field( - default=None, description='Unique identifier for the user’s installed fonts.' - ) - timezone_offset: Optional[StrictStr] = Field( - default=None, - description='UTC offset in "±HH:MM" format derived from the detected IANA timezone.', - ) - battery_level: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = Field( - default=None, - description='Battery charge level as a percentage (0-100). Available for Android, iOS, and web devices. On web, only available in Chromium-based browsers.', - ) - battery_charging: Optional[StrictBool] = Field( - default=None, - description='When `true`, the device is currently charging. Available only for web devices on Chromium-based browsers.', - ) - battery_low_power_mode: Optional[StrictBool] = Field( - default=None, - description="Whether the device's low power mode is enabled. Available only for Android and iOS devices.", - ) - keyboard_layout_hash: Optional[StrictStr] = Field( - default=None, description="Unique identifier for the user's keyboard layout." - ) - keyboard_layout_name: Optional[StrictStr] = Field( - default=None, - description="Name of the user's configured keyboard layout as a BCP 47-style identifier. Only available in Chromium-based browsers, omitted otherwise.", - ) - __properties: ClassVar[list[str]] = [ - 'font_preferences', - 'emoji', - 'fonts', - 'device_memory', - 'timezone', - 'canvas', - 'languages', - 'webgl_extensions', - 'webgl_basics', - 'screen_resolution', - 'touch_support', - 'oscpu', - 'architecture', - 'cookies_enabled', - 'hardware_concurrency', - 'date_time_locale', - 'vendor', - 'color_depth', - 'platform', - 'session_storage', - 'local_storage', - 'audio', - 'plugins', - 'indexed_db', - 'math', - 'device_model', - 'device_manufacturer', - 'font_hash', - 'timezone_offset', - 'battery_level', - 'battery_charging', - 'battery_low_power_mode', - 'keyboard_layout_hash', - 'keyboard_layout_name', - ] + oscpu: Optional[StrictStr] = Field(default=None, description="Navigator `oscpu` string.") + architecture: Optional[StrictInt] = Field(default=None, description="Integer representing the CPU architecture exposed by the browser.") + cookies_enabled: Optional[StrictBool] = Field(default=None, description="Whether the cookies are enabled in the browser.") + hardware_concurrency: Optional[StrictInt] = Field(default=None, description="Number of logical CPU cores reported by the browser.") + date_time_locale: Optional[StrictStr] = Field(default=None, description="Locale derived from the Intl.DateTimeFormat API. Negative values indicate known error states. The negative statuses can be: - \"-1\": A permanent status for browsers that don't support Intl API. - \"-2\": A permanent status for browsers that don't supportDateTimeFormat constructor. - \"-3\": A permanent status for browsers in which DateTimeFormat locale is undefined or null. ") + vendor: Optional[StrictStr] = Field(default=None, description="Navigator vendor string.") + color_depth: Optional[StrictInt] = Field(default=None, description="Screen color depth in bits.") + platform: Optional[StrictStr] = Field(default=None, description="Navigator platform string.") + session_storage: Optional[StrictBool] = Field(default=None, description="Whether sessionStorage is available.") + local_storage: Optional[StrictBool] = Field(default=None, description="Whether localStorage is available.") + audio: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="AudioContext fingerprint or negative status when unavailable. The negative statuses can be: - -1: A permanent status for those browsers which are known to always suspend audio context - -2: A permanent status for browsers that don't support the signal - -3: A temporary status that means that an unexpected timeout has happened ") + plugins: Optional[List[PluginsInner]] = Field(default=None, description="Browser plugins reported by `navigator.plugins`.") + indexed_db: Optional[StrictBool] = Field(default=None, description="Whether IndexedDB is available.") + math: Optional[StrictStr] = Field(default=None, description="Hash of Math APIs used for entropy collection.") + device_model: Optional[StrictStr] = Field(default=None, description="Device model string. Available only for Android and iOS devices.") + device_manufacturer: Optional[StrictStr] = Field(default=None, description="Device manufacturer string. Available only for Android and iOS devices.") + font_hash: Optional[StrictStr] = Field(default=None, description="Unique identifier for the user’s installed fonts.") + timezone_offset: Optional[StrictStr] = Field(default=None, description="UTC offset in \"±HH:MM\" format derived from the detected IANA timezone.") + battery_level: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = Field(default=None, description="Battery charge level as a percentage (0-100). Available for Android, iOS, and web devices. On web, only available in Chromium-based browsers.") + battery_charging: Optional[StrictBool] = Field(default=None, description="When `true`, the device is currently charging. Available only for web devices on Chromium-based browsers.") + battery_low_power_mode: Optional[StrictBool] = Field(default=None, description="Whether the device's low power mode is enabled. Available only for Android and iOS devices.") + keyboard_layout_hash: Optional[StrictStr] = Field(default=None, description="Unique identifier for the user's keyboard layout.") + keyboard_layout_name: Optional[StrictStr] = Field(default=None, description="Name of the user's configured keyboard layout as a BCP 47-style identifier. Only available in Chromium-based browsers, omitted otherwise.") + __properties: ClassVar[list[str]] = ['font_preferences', 'emoji', 'fonts', 'device_memory', 'timezone', 'canvas', 'languages', 'webgl_extensions', 'webgl_basics', 'screen_resolution', 'touch_support', 'oscpu', 'architecture', 'cookies_enabled', 'hardware_concurrency', 'date_time_locale', 'vendor', 'color_depth', 'platform', 'session_storage', 'local_storage', 'audio', 'plugins', 'indexed_db', 'math', 'device_model', 'device_manufacturer', 'font_hash', 'timezone_offset', 'battery_level', 'battery_charging', 'battery_low_power_mode', 'keyboard_layout_hash', 'keyboard_layout_name'] model_config = ConfigDict( populate_by_name=True, @@ -201,7 +102,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -244,54 +146,42 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'font_preferences': FontPreferences.from_dict(obj['font_preferences']) - if obj.get('font_preferences') is not None - else None, - 'emoji': Emoji.from_dict(obj['emoji']) if obj.get('emoji') is not None else None, - 'fonts': obj.get('fonts'), - 'device_memory': obj.get('device_memory'), - 'timezone': obj.get('timezone'), - 'canvas': Canvas.from_dict(obj['canvas']) - if obj.get('canvas') is not None - else None, - 'languages': obj.get('languages'), - 'webgl_extensions': WebGlExtensions.from_dict(obj['webgl_extensions']) - if obj.get('webgl_extensions') is not None - else None, - 'webgl_basics': WebGlBasics.from_dict(obj['webgl_basics']) - if obj.get('webgl_basics') is not None - else None, - 'screen_resolution': obj.get('screen_resolution'), - 'touch_support': TouchSupport.from_dict(obj['touch_support']) - if obj.get('touch_support') is not None - else None, - 'oscpu': obj.get('oscpu'), - 'architecture': obj.get('architecture'), - 'cookies_enabled': obj.get('cookies_enabled'), - 'hardware_concurrency': obj.get('hardware_concurrency'), - 'date_time_locale': obj.get('date_time_locale'), - 'vendor': obj.get('vendor'), - 'color_depth': obj.get('color_depth'), - 'platform': obj.get('platform'), - 'session_storage': obj.get('session_storage'), - 'local_storage': obj.get('local_storage'), - 'audio': obj.get('audio'), - 'plugins': [PluginsInner.from_dict(_item) for _item in obj['plugins']] - if obj.get('plugins') is not None - else None, - 'indexed_db': obj.get('indexed_db'), - 'math': obj.get('math'), - 'device_model': obj.get('device_model'), - 'device_manufacturer': obj.get('device_manufacturer'), - 'font_hash': obj.get('font_hash'), - 'timezone_offset': obj.get('timezone_offset'), - 'battery_level': obj.get('battery_level'), - 'battery_charging': obj.get('battery_charging'), - 'battery_low_power_mode': obj.get('battery_low_power_mode'), - 'keyboard_layout_hash': obj.get('keyboard_layout_hash'), - 'keyboard_layout_name': obj.get('keyboard_layout_name'), - } - ) + _obj = cls.model_validate({ + "font_preferences": FontPreferences.from_dict(obj["font_preferences"]) if obj.get("font_preferences") is not None else None, + "emoji": Emoji.from_dict(obj["emoji"]) if obj.get("emoji") is not None else None, + "fonts": obj.get("fonts"), + "device_memory": obj.get("device_memory"), + "timezone": obj.get("timezone"), + "canvas": Canvas.from_dict(obj["canvas"]) if obj.get("canvas") is not None else None, + "languages": obj.get("languages"), + "webgl_extensions": WebGlExtensions.from_dict(obj["webgl_extensions"]) if obj.get("webgl_extensions") is not None else None, + "webgl_basics": WebGlBasics.from_dict(obj["webgl_basics"]) if obj.get("webgl_basics") is not None else None, + "screen_resolution": obj.get("screen_resolution"), + "touch_support": TouchSupport.from_dict(obj["touch_support"]) if obj.get("touch_support") is not None else None, + "oscpu": obj.get("oscpu"), + "architecture": obj.get("architecture"), + "cookies_enabled": obj.get("cookies_enabled"), + "hardware_concurrency": obj.get("hardware_concurrency"), + "date_time_locale": obj.get("date_time_locale"), + "vendor": obj.get("vendor"), + "color_depth": obj.get("color_depth"), + "platform": obj.get("platform"), + "session_storage": obj.get("session_storage"), + "local_storage": obj.get("local_storage"), + "audio": obj.get("audio"), + "plugins": [PluginsInner.from_dict(_item) for _item in obj["plugins"]] if obj.get("plugins") is not None else None, + "indexed_db": obj.get("indexed_db"), + "math": obj.get("math"), + "device_model": obj.get("device_model"), + "device_manufacturer": obj.get("device_manufacturer"), + "font_hash": obj.get("font_hash"), + "timezone_offset": obj.get("timezone_offset"), + "battery_level": obj.get("battery_level"), + "battery_charging": obj.get("battery_charging"), + "battery_low_power_mode": obj.get("battery_low_power_mode"), + "keyboard_layout_hash": obj.get("keyboard_layout_hash"), + "keyboard_layout_name": obj.get("keyboard_layout_name") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/request_header_modifications.py b/fingerprint_server_sdk/models/request_header_modifications.py index 5a8f45f7..67fd76d7 100644 --- a/fingerprint_server_sdk/models/request_header_modifications.py +++ b/fingerprint_server_sdk/models/request_header_modifications.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.rule_action_header_field import RuleActionHeaderField +from typing_extensions import Self class RequestHeaderModifications(BaseModel): @@ -29,16 +29,9 @@ class RequestHeaderModifications(BaseModel): The set of header modifications to apply, in the following order: remove, set, append. """ - remove: Optional[list[StrictStr]] = Field( - default=None, description='The list of headers to remove.' - ) - set: Optional[list[RuleActionHeaderField]] = Field( - default=None, - description='The list of headers to set, overwriting any existing headers with the same name.', - ) - append: Optional[list[RuleActionHeaderField]] = Field( - default=None, description='The list of headers to append.' - ) + remove: Optional[List[StrictStr]] = Field(default=None, description="The list of headers to remove.") + set: Optional[List[RuleActionHeaderField]] = Field(default=None, description="The list of headers to set, overwriting any existing headers with the same name.") + append: Optional[List[RuleActionHeaderField]] = Field(default=None, description="The list of headers to append.") __properties: ClassVar[list[str]] = ['remove', 'set', 'append'] model_config = ConfigDict( @@ -71,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -103,15 +97,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'remove': obj.get('remove'), - 'set': [RuleActionHeaderField.from_dict(_item) for _item in obj['set']] - if obj.get('set') is not None - else None, - 'append': [RuleActionHeaderField.from_dict(_item) for _item in obj['append']] - if obj.get('append') is not None - else None, - } - ) + _obj = cls.model_validate({ + "remove": obj.get("remove"), + "set": [RuleActionHeaderField.from_dict(_item) for _item in obj["set"]] if obj.get("set") is not None else None, + "append": [RuleActionHeaderField.from_dict(_item) for _item in obj["append"]] if obj.get("append") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/rule_action_header_field.py b/fingerprint_server_sdk/models/rule_action_header_field.py index 43f71cdf..9b9bbfa2 100644 --- a/fingerprint_server_sdk/models/rule_action_header_field.py +++ b/fingerprint_server_sdk/models/rule_action_header_field.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List from typing_extensions import Self @@ -27,8 +28,8 @@ class RuleActionHeaderField(BaseModel): RuleActionHeaderField """ - name: StrictStr = Field(description='The header field name.') - value: StrictStr = Field(description='The value of the header field.') + name: StrictStr = Field(description="The header field name.") + value: StrictStr = Field(description="The value of the header field.") __properties: ClassVar[list[str]] = ['name', 'value'] model_config = ConfigDict( @@ -61,7 +62,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -79,5 +81,10 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate({'name': obj.get('name'), 'value': obj.get('value')}) + _obj = cls.model_validate({ + "name": obj.get("name"), + "value": obj.get("value") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/rule_action_type.py b/fingerprint_server_sdk/models/rule_action_type.py index ee3171df..f3baa390 100644 --- a/fingerprint_server_sdk/models/rule_action_type.py +++ b/fingerprint_server_sdk/models/rule_action_type.py @@ -12,10 +12,8 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self @@ -39,7 +37,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/sdk.py b/fingerprint_server_sdk/models/sdk.py index 0cae436a..526c0473 100644 --- a/fingerprint_server_sdk/models/sdk.py +++ b/fingerprint_server_sdk/models/sdk.py @@ -18,10 +18,10 @@ import re # noqa: F401 from typing import Any, ClassVar, Optional -from pydantic import BaseModel, ConfigDict, Field, StrictStr -from typing_extensions import Self - +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.integration import Integration +from typing_extensions import Self class SDK(BaseModel): @@ -29,13 +29,9 @@ class SDK(BaseModel): Contains information about the SDK used to perform the request. """ - platform: StrictStr = Field( - description='Platform of the SDK used for the identification request.' - ) - version: StrictStr = Field( - description='Version string of the SDK used for the identification request.' - ) - integrations: Optional[list[Integration]] = None + platform: StrictStr = Field(description="Platform of the SDK used for the identification request.") + version: StrictStr = Field(description="Version string of the SDK used for the identification request.") + integrations: Optional[List[Integration]] = None __properties: ClassVar[list[str]] = ['platform', 'version', 'integrations'] model_config = ConfigDict( @@ -68,7 +64,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -93,13 +90,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'platform': obj.get('platform'), - 'version': obj.get('version'), - 'integrations': [Integration.from_dict(_item) for _item in obj['integrations']] - if obj.get('integrations') is not None - else None, - } - ) + _obj = cls.model_validate({ + "platform": obj.get("platform"), + "version": obj.get("version"), + "integrations": [Integration.from_dict(_item) for _item in obj["integrations"]] if obj.get("integrations") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/search_events_bot.py b/fingerprint_server_sdk/models/search_events_bot.py index 1b282d02..25fa09ae 100644 --- a/fingerprint_server_sdk/models/search_events_bot.py +++ b/fingerprint_server_sdk/models/search_events_bot.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class SearchEventsBot(str, Enum): """ - Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. + Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. """ """ @@ -41,7 +39,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/search_events_bot_info.py b/fingerprint_server_sdk/models/search_events_bot_info.py index b281dc37..95baf606 100644 --- a/fingerprint_server_sdk/models/search_events_bot_info.py +++ b/fingerprint_server_sdk/models/search_events_bot_info.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class SearchEventsBotInfo(str, Enum): """ - Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. + Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. """ """ @@ -39,7 +37,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/search_events_end_parameter.py b/fingerprint_server_sdk/models/search_events_end_parameter.py index 13ed0176..4062cac5 100644 --- a/fingerprint_server_sdk/models/search_events_end_parameter.py +++ b/fingerprint_server_sdk/models/search_events_end_parameter.py @@ -12,7 +12,6 @@ """ # noqa: E501 from typing import Union - from pydantic import AwareDatetime +SearchEventsEndParameter = Union[AwareDatetime,int] -SearchEventsEndParameter = Union[AwareDatetime, int] diff --git a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py index b0efd6f6..c9dc7a6c 100644 --- a/fingerprint_server_sdk/models/search_events_incremental_identification_status.py +++ b/fingerprint_server_sdk/models/search_events_incremental_identification_status.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class SearchEventsIncrementalIdentificationStatus(str, Enum): """ - Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. + Filter events by their incremental identification status (`incremental_identification_status` property). Non incremental identification events are left out of the response. """ """ @@ -39,7 +37,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py index 3034858a..18eefed7 100644 --- a/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py +++ b/fingerprint_server_sdk/models/search_events_rare_device_percentile_bucket.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class SearchEventsRareDevicePercentileBucket(str, Enum): """ - Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). + Filter events by Device Rarity percentile bucket. ` This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). """ """ @@ -43,7 +41,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/search_events_sdk_platform.py b/fingerprint_server_sdk/models/search_events_sdk_platform.py index ed24dab3..60829da7 100644 --- a/fingerprint_server_sdk/models/search_events_sdk_platform.py +++ b/fingerprint_server_sdk/models/search_events_sdk_platform.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class SearchEventsSdkPlatform(str, Enum): """ - Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. + Filter events by the SDK Platform associated with the identification event (`sdk.platform` property) . `js` - Javascript agent (Web). `ios` - Apple iOS based devices. `android` - Android based devices. """ """ @@ -40,7 +38,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/search_events_source.py b/fingerprint_server_sdk/models/search_events_source.py index 9e68ba81..134b2ad6 100644 --- a/fingerprint_server_sdk/models/search_events_source.py +++ b/fingerprint_server_sdk/models/search_events_source.py @@ -12,10 +12,8 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self @@ -38,7 +36,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/search_events_start_parameter.py b/fingerprint_server_sdk/models/search_events_start_parameter.py index a3a4f4b0..d633b962 100644 --- a/fingerprint_server_sdk/models/search_events_start_parameter.py +++ b/fingerprint_server_sdk/models/search_events_start_parameter.py @@ -12,7 +12,6 @@ """ # noqa: E501 from typing import Union - from pydantic import AwareDatetime +SearchEventsStartParameter = Union[AwareDatetime,int] -SearchEventsStartParameter = Union[AwareDatetime, int] diff --git a/fingerprint_server_sdk/models/search_events_vpn_confidence.py b/fingerprint_server_sdk/models/search_events_vpn_confidence.py index 9241c5ab..31e23082 100644 --- a/fingerprint_server_sdk/models/search_events_vpn_confidence.py +++ b/fingerprint_server_sdk/models/search_events_vpn_confidence.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class SearchEventsVpnConfidence(str, Enum): """ - Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. + Filter events by VPN Detection result confidence level. `high` - events with high VPN Detection confidence. `medium` - events with medium VPN Detection confidence. `low` - events with low VPN Detection confidence. > Note: When using this parameter, only events with the `vpn.confidence` property set to a valid value are returned. Events without a `vpn` Smart Signal result are left out of the response. """ """ @@ -40,7 +38,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/supplementary_id_high_recall.py b/fingerprint_server_sdk/models/supplementary_id_high_recall.py index a1a99238..230e265c 100644 --- a/fingerprint_server_sdk/models/supplementary_id_high_recall.py +++ b/fingerprint_server_sdk/models/supplementary_id_high_recall.py @@ -19,9 +19,9 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.identification_confidence import IdentificationConfidence +from typing_extensions import Self class SupplementaryIDHighRecall(BaseModel): @@ -29,28 +29,12 @@ class SupplementaryIDHighRecall(BaseModel): The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. """ - visitor_id: StrictStr = Field( - description="The High Recall identifier for the visitor's browser. It is an alphanumeric string with a maximum length of 25 characters." - ) - visitor_found: StrictBool = Field( - description='True if this is a returning browser and has been previously identified. Otherwise, false.' - ) + visitor_id: StrictStr = Field(description="The High Recall identifier for the visitor's browser. It is an alphanumeric string with a maximum length of 25 characters.") + visitor_found: StrictBool = Field(description="True if this is a returning browser and has been previously identified. Otherwise, false.") confidence: Optional[IdentificationConfidence] = None - first_seen_at: Optional[StrictInt] = Field( - default=None, - description='Unix epoch timestamp (in milliseconds) indicating when the browser was first identified. example: `1758069706642` - Corresponding to Wed Sep 17 2025 00:41:46 GMT+0000 ', - ) - last_seen_at: Optional[StrictInt] = Field( - default=None, - description='Unix epoch timestamp (in milliseconds) corresponding to the most recent visit by this browser. example: `1758069706642` - Corresponding to Wed Sep 17 2025 00:41:46 GMT+0000 ', - ) - __properties: ClassVar[list[str]] = [ - 'visitor_id', - 'visitor_found', - 'confidence', - 'first_seen_at', - 'last_seen_at', - ] + first_seen_at: Optional[StrictInt] = Field(default=None, description="Unix epoch timestamp (in milliseconds) indicating when the browser was first identified. example: `1758069706642` - Corresponding to Wed Sep 17 2025 00:41:46 GMT+0000 ") + last_seen_at: Optional[StrictInt] = Field(default=None, description="Unix epoch timestamp (in milliseconds) corresponding to the most recent visit by this browser. example: `1758069706642` - Corresponding to Wed Sep 17 2025 00:41:46 GMT+0000 ") + __properties: ClassVar[list[str]] = ['visitor_id', 'visitor_found', 'confidence', 'first_seen_at', 'last_seen_at'] model_config = ConfigDict( populate_by_name=True, @@ -82,7 +66,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -103,15 +88,13 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'visitor_id': obj.get('visitor_id'), - 'visitor_found': obj.get('visitor_found'), - 'confidence': IdentificationConfidence.from_dict(obj['confidence']) - if obj.get('confidence') is not None - else None, - 'first_seen_at': obj.get('first_seen_at'), - 'last_seen_at': obj.get('last_seen_at'), - } - ) + _obj = cls.model_validate({ + "visitor_id": obj.get("visitor_id"), + "visitor_found": obj.get("visitor_found"), + "confidence": IdentificationConfidence.from_dict(obj["confidence"]) if obj.get("confidence") is not None else None, + "first_seen_at": obj.get("first_seen_at"), + "last_seen_at": obj.get("last_seen_at") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/tampering_confidence.py b/fingerprint_server_sdk/models/tampering_confidence.py index c2d06eb2..2c32df7d 100644 --- a/fingerprint_server_sdk/models/tampering_confidence.py +++ b/fingerprint_server_sdk/models/tampering_confidence.py @@ -12,16 +12,14 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self class TamperingConfidence(str, Enum): """ - The confidence level indicates how certain Fingerprint is that the current request involves browser tampering. This confidence level is determined by evaluating multiple factors, such as heuristic rules, probabilistic anomaly detection, an anti detect browser ml model, and other relevant methods. It is conveyed as a string with possible values such as high, medium, or low In case of tampering: `true` * **High confidence**: heuristic anti detect browser signals and the ml model are triggered, or all of the methods are triggered. * **Medium confidence**: either the ml model triggers alone, the anomaly score triggers alone with or without the heuristic anti detect browser methods trigger. * **Low confidence**: only the heuristic anti detect methods are triggered. In case of tampering: `false` * **High confidence:** Strong signals suggest the user is not tampering with their request. + The confidence level indicates how certain Fingerprint is that the current request involves browser tampering. This confidence level is determined by evaluating multiple factors, such as heuristic rules, probabilistic anomaly detection, an anti detect browser ml model, and other relevant methods. It is conveyed as a string with possible values such as high, medium, or low In case of tampering: `true` * **High confidence**: heuristic anti detect browser signals and the ml model are triggered, or all of the methods are triggered. * **Medium confidence**: either the ml model triggers alone, the anomaly score triggers alone with or without the heuristic anti detect browser methods trigger. * **Low confidence**: only the heuristic anti detect methods are triggered. In case of tampering: `false` * **High confidence:** Strong signals suggest the user is not tampering with their request. """ """ @@ -40,7 +38,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/tampering_details.py b/fingerprint_server_sdk/models/tampering_details.py index 021ec7cd..8f9b80d9 100644 --- a/fingerprint_server_sdk/models/tampering_details.py +++ b/fingerprint_server_sdk/models/tampering_details.py @@ -16,9 +16,11 @@ import json import pprint import re # noqa: F401 -from typing import Annotated, Any, ClassVar, Optional, Union +from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated from typing_extensions import Self @@ -27,19 +29,8 @@ class TamperingDetails(BaseModel): TamperingDetails """ - anomaly_score: Optional[ - Union[ - Annotated[float, Field(le=1, strict=True, ge=0)], - Annotated[int, Field(le=1, strict=True, ge=0)], - ] - ] = Field( - default=None, - description="The output of this model is captured as anomaly_score, a statistical score indicating how rare the visitor's browser signature is compared to the overall population. Values close to 1 signify highly anomalous browsers and we consider anything above the threshold of 0.5 to be actionable (the result field conveniently captures that fact). ", - ) - anti_detect_browser: Optional[StrictBool] = Field( - default=None, - description='Detects whether the request shows evidence of anti-detect browser usage. This field may be triggered by: * heuristic detection of known anti-detect browser behavior * machine learning detection of anti-detect browser patterns Examples of anti-detect browsers include tools such as AdsPower, DolphinAnty, OctoBrowser, and GoLogin. ', - ) + anomaly_score: Optional[Union[Annotated[float, Field(le=1, strict=True, ge=0)], Annotated[int, Field(le=1, strict=True, ge=0)]]] = Field(default=None, description="The output of this model is captured as anomaly_score, a statistical score indicating how rare the visitor's browser signature is compared to the overall population. Values close to 1 signify highly anomalous browsers and we consider anything above the threshold of 0.5 to be actionable (the result field conveniently captures that fact). ") + anti_detect_browser: Optional[StrictBool] = Field(default=None, description="Detects whether the request shows evidence of anti-detect browser usage. This field may be triggered by: * heuristic detection of known anti-detect browser behavior * machine learning detection of anti-detect browser patterns Examples of anti-detect browsers include tools such as AdsPower, DolphinAnty, OctoBrowser, and GoLogin. ") __properties: ClassVar[list[str]] = ['anomaly_score', 'anti_detect_browser'] model_config = ConfigDict( @@ -72,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -90,10 +82,10 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'anomaly_score': obj.get('anomaly_score'), - 'anti_detect_browser': obj.get('anti_detect_browser'), - } - ) + _obj = cls.model_validate({ + "anomaly_score": obj.get("anomaly_score"), + "anti_detect_browser": obj.get("anti_detect_browser") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/touch_support.py b/fingerprint_server_sdk/models/touch_support.py index b3e5e467..477a77c1 100644 --- a/fingerprint_server_sdk/models/touch_support.py +++ b/fingerprint_server_sdk/models/touch_support.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, StrictBool, StrictInt +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -62,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -80,11 +82,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'touch_event': obj.get('touch_event'), - 'touch_start': obj.get('touch_start'), - 'max_touch_points': obj.get('max_touch_points'), - } - ) + _obj = cls.model_validate({ + "touch_event": obj.get("touch_event"), + "touch_start": obj.get("touch_start"), + "max_touch_points": obj.get("max_touch_points") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/velocity.py b/fingerprint_server_sdk/models/velocity.py index ad056ea2..b7eab687 100644 --- a/fingerprint_server_sdk/models/velocity.py +++ b/fingerprint_server_sdk/models/velocity.py @@ -19,14 +19,14 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict -from typing_extensions import Self - +from typing import Any, ClassVar, Dict, List, Optional from fingerprint_server_sdk.models.velocity_data import VelocityData +from typing_extensions import Self class Velocity(BaseModel): """ - Sums key data points for a specific `visitor_id`, `ip_address` and `linked_id` at three distinct time intervals: 5 minutes, 1 hour, and 24 hours as follows: - Number of distinct IP addresses associated to the visitor Id. - Number of distinct linked Ids associated with the visitor Id. - Number of distinct countries associated with the visitor Id. - Number of identification events associated with the visitor Id. - Number of identification events associated with the detected IP address. - Number of distinct IP addresses associated with the provided linked Id. - Number of distinct visitor Ids associated with the provided linked Id. The `24_hours` interval of `distinct_ip`, `distinct_linked_id`, `distinct_country`, `distinct_ip_by_linked_id` and `distinct_visitor_id_by_linked_id` will be omitted if the number of `events` for the visitor Id in the last 24 hours (`events.['24_hours']`) is higher than 20.000. All will not necessarily be returned in a response, some may be omitted if the associated event does not have the required data, such as a linked_id. + Sums key data points for a specific `visitor_id`, `ip_address` and `linked_id` at three distinct time intervals: 5 minutes, 1 hour, and 24 hours as follows: - Number of distinct IP addresses associated to the visitor Id. - Number of distinct linked Ids associated with the visitor Id. - Number of distinct countries associated with the visitor Id. - Number of identification events associated with the visitor Id. - Number of identification events associated with the detected IP address. - Number of distinct IP addresses associated with the provided linked Id. - Number of distinct visitor Ids associated with the provided linked Id. The `24_hours` interval of `distinct_ip`, `distinct_linked_id`, `distinct_country`, `distinct_ip_by_linked_id` and `distinct_visitor_id_by_linked_id` will be omitted if the number of `events` for the visitor Id in the last 24 hours (`events.['24_hours']`) is higher than 20.000. All will not necessarily be returned in a response, some may be omitted if the associated event does not have the required data, such as a linked_id. """ distinct_ip: Optional[VelocityData] = None @@ -36,15 +36,7 @@ class Velocity(BaseModel): ip_events: Optional[VelocityData] = None distinct_ip_by_linked_id: Optional[VelocityData] = None distinct_visitor_id_by_linked_id: Optional[VelocityData] = None - __properties: ClassVar[list[str]] = [ - 'distinct_ip', - 'distinct_linked_id', - 'distinct_country', - 'events', - 'ip_events', - 'distinct_ip_by_linked_id', - 'distinct_visitor_id_by_linked_id', - ] + __properties: ClassVar[list[str]] = ['distinct_ip', 'distinct_linked_id', 'distinct_country', 'events', 'ip_events', 'distinct_ip_by_linked_id', 'distinct_visitor_id_by_linked_id'] model_config = ConfigDict( populate_by_name=True, @@ -76,7 +68,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -103,9 +96,7 @@ def to_dict(self) -> dict[str, Any]: _dict['distinct_ip_by_linked_id'] = self.distinct_ip_by_linked_id.to_dict() # override the default output from pydantic by calling `to_dict()` of distinct_visitor_id_by_linked_id if self.distinct_visitor_id_by_linked_id: - _dict['distinct_visitor_id_by_linked_id'] = ( - self.distinct_visitor_id_by_linked_id.to_dict() - ) + _dict['distinct_visitor_id_by_linked_id'] = self.distinct_visitor_id_by_linked_id.to_dict() return _dict @classmethod @@ -117,31 +108,15 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'distinct_ip': VelocityData.from_dict(obj['distinct_ip']) - if obj.get('distinct_ip') is not None - else None, - 'distinct_linked_id': VelocityData.from_dict(obj['distinct_linked_id']) - if obj.get('distinct_linked_id') is not None - else None, - 'distinct_country': VelocityData.from_dict(obj['distinct_country']) - if obj.get('distinct_country') is not None - else None, - 'events': VelocityData.from_dict(obj['events']) - if obj.get('events') is not None - else None, - 'ip_events': VelocityData.from_dict(obj['ip_events']) - if obj.get('ip_events') is not None - else None, - 'distinct_ip_by_linked_id': VelocityData.from_dict(obj['distinct_ip_by_linked_id']) - if obj.get('distinct_ip_by_linked_id') is not None - else None, - 'distinct_visitor_id_by_linked_id': VelocityData.from_dict( - obj['distinct_visitor_id_by_linked_id'] - ) - if obj.get('distinct_visitor_id_by_linked_id') is not None - else None, - } - ) + _obj = cls.model_validate({ + "distinct_ip": VelocityData.from_dict(obj["distinct_ip"]) if obj.get("distinct_ip") is not None else None, + "distinct_linked_id": VelocityData.from_dict(obj["distinct_linked_id"]) if obj.get("distinct_linked_id") is not None else None, + "distinct_country": VelocityData.from_dict(obj["distinct_country"]) if obj.get("distinct_country") is not None else None, + "events": VelocityData.from_dict(obj["events"]) if obj.get("events") is not None else None, + "ip_events": VelocityData.from_dict(obj["ip_events"]) if obj.get("ip_events") is not None else None, + "distinct_ip_by_linked_id": VelocityData.from_dict(obj["distinct_ip_by_linked_id"]) if obj.get("distinct_ip_by_linked_id") is not None else None, + "distinct_visitor_id_by_linked_id": VelocityData.from_dict(obj["distinct_visitor_id_by_linked_id"]) if obj.get("distinct_visitor_id_by_linked_id") is not None else None + }) return _obj + + diff --git a/fingerprint_server_sdk/models/velocity_data.py b/fingerprint_server_sdk/models/velocity_data.py index ac74cd62..e910e702 100644 --- a/fingerprint_server_sdk/models/velocity_data.py +++ b/fingerprint_server_sdk/models/velocity_data.py @@ -19,27 +19,18 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictInt +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self class VelocityData(BaseModel): """ - Is absent if the velocity data could not be generated for the visitor Id. + Is absent if the velocity data could not be generated for the visitor Id. """ - var_5_minutes: StrictInt = Field( - description='Count for the last 5 minutes of velocity data, from the time of the event. ', - alias='5_minutes', - ) - var_1_hour: StrictInt = Field( - description='Count for the last 1 hour of velocity data, from the time of the event. ', - alias='1_hour', - ) - var_24_hours: Optional[StrictInt] = Field( - default=None, - description='Count for the last 24 hours of velocity data, from the time of the event. ', - alias='24_hours', - ) + var_5_minutes: StrictInt = Field(description="Count for the last 5 minutes of velocity data, from the time of the event. ", alias="5_minutes") + var_1_hour: StrictInt = Field(description="Count for the last 1 hour of velocity data, from the time of the event. ", alias="1_hour") + var_24_hours: Optional[StrictInt] = Field(default=None, description="Count for the last 24 hours of velocity data, from the time of the event. ", alias="24_hours") __properties: ClassVar[list[str]] = ['5_minutes', '1_hour', '24_hours'] model_config = ConfigDict( @@ -72,7 +63,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -90,11 +82,11 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - '5_minutes': obj.get('5_minutes'), - '1_hour': obj.get('1_hour'), - '24_hours': obj.get('24_hours'), - } - ) + _obj = cls.model_validate({ + "5_minutes": obj.get("5_minutes"), + "1_hour": obj.get("1_hour"), + "24_hours": obj.get("24_hours") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/vpn_confidence.py b/fingerprint_server_sdk/models/vpn_confidence.py index 606e7820..62be9238 100644 --- a/fingerprint_server_sdk/models/vpn_confidence.py +++ b/fingerprint_server_sdk/models/vpn_confidence.py @@ -12,10 +12,8 @@ """ # noqa: E501 from __future__ import annotations - import json from enum import Enum - from typing_extensions import Self @@ -40,7 +38,7 @@ def from_json(cls, json_str: str) -> Self: def _missing_(cls, value: object) -> Self: """Accept unknown enum values gracefully.""" if not isinstance(value, str): - raise ValueError(f'{value!r} is not a valid {cls.__name__}') + raise ValueError(f"{value!r} is not a valid {cls.__name__}") obj = str.__new__(cls, value) obj._name_ = str(value) obj._value_ = value diff --git a/fingerprint_server_sdk/models/vpn_methods.py b/fingerprint_server_sdk/models/vpn_methods.py index ccd783c0..d93e1dea 100644 --- a/fingerprint_server_sdk/models/vpn_methods.py +++ b/fingerprint_server_sdk/models/vpn_methods.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, Field, StrictBool +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -27,38 +28,13 @@ class VpnMethods(BaseModel): VpnMethods """ - timezone_mismatch: Optional[StrictBool] = Field( - default=None, - description="The browser timezone doesn't match the timezone inferred from the request IP address.", - ) - public_vpn: Optional[StrictBool] = Field( - default=None, - description='Request IP address is owned and used by a public VPN service provider.', - ) - auxiliary_mobile: Optional[StrictBool] = Field( - default=None, - description='This method applies to mobile devices only. Indicates the result of additional methods used to detect a VPN in mobile devices.', - ) - os_mismatch: Optional[StrictBool] = Field( - default=None, - description='The browser runs on a different operating system than the operating system inferred from the request network signature.', - ) - relay: Optional[StrictBool] = Field( - default=None, - description="Request IP address belongs to a relay service provider, indicating the use of relay services like [Apple Private relay](https://support.apple.com/en-us/102602) or [Cloudflare Warp](https://developers.cloudflare.com/warp-client/). * Like VPNs, relay services anonymize the visitor's true IP address. * Unlike traditional VPNs, relay services don't let visitors spoof their location by choosing an exit node in a different country. This field allows you to differentiate VPN users and relay service users in your fraud prevention logic. ", - ) - ml_prediction: Optional[StrictBool] = Field( - default=None, - description='`true` if the request came from a device running a VPN, `false` otherwise. ', - ) - __properties: ClassVar[list[str]] = [ - 'timezone_mismatch', - 'public_vpn', - 'auxiliary_mobile', - 'os_mismatch', - 'relay', - 'ml_prediction', - ] + timezone_mismatch: Optional[StrictBool] = Field(default=None, description="The browser timezone doesn't match the timezone inferred from the request IP address.") + public_vpn: Optional[StrictBool] = Field(default=None, description="Request IP address is owned and used by a public VPN service provider.") + auxiliary_mobile: Optional[StrictBool] = Field(default=None, description="This method applies to mobile devices only. Indicates the result of additional methods used to detect a VPN in mobile devices.") + os_mismatch: Optional[StrictBool] = Field(default=None, description="The browser runs on a different operating system than the operating system inferred from the request network signature.") + relay: Optional[StrictBool] = Field(default=None, description="Request IP address belongs to a relay service provider, indicating the use of relay services like [Apple Private relay](https://support.apple.com/en-us/102602) or [Cloudflare Warp](https://developers.cloudflare.com/warp-client/). * Like VPNs, relay services anonymize the visitor's true IP address. * Unlike traditional VPNs, relay services don't let visitors spoof their location by choosing an exit node in a different country. This field allows you to differentiate VPN users and relay service users in your fraud prevention logic. ") + ml_prediction: Optional[StrictBool] = Field(default=None, description="`true` if the request came from a device running a VPN, `false` otherwise. ") + __properties: ClassVar[list[str]] = ['timezone_mismatch', 'public_vpn', 'auxiliary_mobile', 'os_mismatch', 'relay', 'ml_prediction'] model_config = ConfigDict( populate_by_name=True, @@ -90,7 +66,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -108,14 +85,14 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'timezone_mismatch': obj.get('timezone_mismatch'), - 'public_vpn': obj.get('public_vpn'), - 'auxiliary_mobile': obj.get('auxiliary_mobile'), - 'os_mismatch': obj.get('os_mismatch'), - 'relay': obj.get('relay'), - 'ml_prediction': obj.get('ml_prediction'), - } - ) + _obj = cls.model_validate({ + "timezone_mismatch": obj.get("timezone_mismatch"), + "public_vpn": obj.get("public_vpn"), + "auxiliary_mobile": obj.get("auxiliary_mobile"), + "os_mismatch": obj.get("os_mismatch"), + "relay": obj.get("relay"), + "ml_prediction": obj.get("ml_prediction") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/web_gl_basics.py b/fingerprint_server_sdk/models/web_gl_basics.py index fb7feb18..0112b590 100644 --- a/fingerprint_server_sdk/models/web_gl_basics.py +++ b/fingerprint_server_sdk/models/web_gl_basics.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -33,14 +34,7 @@ class WebGlBasics(BaseModel): renderer: Optional[StrictStr] = None renderer_unmasked: Optional[StrictStr] = None shading_language_version: Optional[StrictStr] = None - __properties: ClassVar[list[str]] = [ - 'version', - 'vendor', - 'vendor_unmasked', - 'renderer', - 'renderer_unmasked', - 'shading_language_version', - ] + __properties: ClassVar[list[str]] = ['version', 'vendor', 'vendor_unmasked', 'renderer', 'renderer_unmasked', 'shading_language_version'] model_config = ConfigDict( populate_by_name=True, @@ -72,7 +66,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -90,14 +85,14 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'version': obj.get('version'), - 'vendor': obj.get('vendor'), - 'vendor_unmasked': obj.get('vendor_unmasked'), - 'renderer': obj.get('renderer'), - 'renderer_unmasked': obj.get('renderer_unmasked'), - 'shading_language_version': obj.get('shading_language_version'), - } - ) + _obj = cls.model_validate({ + "version": obj.get("version"), + "vendor": obj.get("vendor"), + "vendor_unmasked": obj.get("vendor_unmasked"), + "renderer": obj.get("renderer"), + "renderer_unmasked": obj.get("renderer_unmasked"), + "shading_language_version": obj.get("shading_language_version") + }) return _obj + + diff --git a/fingerprint_server_sdk/models/web_gl_extensions.py b/fingerprint_server_sdk/models/web_gl_extensions.py index b8dec87d..75dd9e35 100644 --- a/fingerprint_server_sdk/models/web_gl_extensions.py +++ b/fingerprint_server_sdk/models/web_gl_extensions.py @@ -19,6 +19,7 @@ from typing import Any, ClassVar, Optional from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Self @@ -32,15 +33,8 @@ class WebGlExtensions(BaseModel): shader_precisions: Optional[StrictStr] = None extensions: Optional[StrictStr] = None extension_parameters: Optional[StrictStr] = None - unsupported_extensions: Optional[list[StrictStr]] = None - __properties: ClassVar[list[str]] = [ - 'context_attributes', - 'parameters', - 'shader_precisions', - 'extensions', - 'extension_parameters', - 'unsupported_extensions', - ] + unsupported_extensions: Optional[List[StrictStr]] = None + __properties: ClassVar[list[str]] = ['context_attributes', 'parameters', 'shader_precisions', 'extensions', 'extension_parameters', 'unsupported_extensions'] model_config = ConfigDict( populate_by_name=True, @@ -72,7 +66,8 @@ def to_dict(self) -> dict[str, Any]: were set at model initialization. Other fields with value `None` are ignored. """ - excluded_fields: set[str] = set([]) + excluded_fields: set[str] = set([ + ]) _dict = self.model_dump( by_alias=True, @@ -90,14 +85,14 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: if not isinstance(obj, dict): return cls.model_validate(obj) - _obj = cls.model_validate( - { - 'context_attributes': obj.get('context_attributes'), - 'parameters': obj.get('parameters'), - 'shader_precisions': obj.get('shader_precisions'), - 'extensions': obj.get('extensions'), - 'extension_parameters': obj.get('extension_parameters'), - 'unsupported_extensions': obj.get('unsupported_extensions'), - } - ) + _obj = cls.model_validate({ + "context_attributes": obj.get("context_attributes"), + "parameters": obj.get("parameters"), + "shader_precisions": obj.get("shader_precisions"), + "extensions": obj.get("extensions"), + "extension_parameters": obj.get("extension_parameters"), + "unsupported_extensions": obj.get("unsupported_extensions") + }) return _obj + + diff --git a/fingerprint_server_sdk/rest.py b/fingerprint_server_sdk/rest.py index 3151bd45..1059deae 100644 --- a/fingerprint_server_sdk/rest.py +++ b/fingerprint_server_sdk/rest.py @@ -10,7 +10,6 @@ Do not edit the class manually. """ # noqa: E501 - from __future__ import annotations import io @@ -33,7 +32,7 @@ def is_socks_proxy_url(url: Optional[str]) -> bool: if url is None: return False - split_section = url.split('://') + split_section = url.split("://") if len(split_section) < 2: return False else: @@ -80,14 +79,16 @@ def __init__(self, configuration: Configuration) -> None: cert_reqs = ssl.CERT_NONE pool_args: dict[str, Any] = { - 'cert_reqs': cert_reqs, - 'ca_certs': configuration.ssl_ca_cert, - 'cert_file': configuration.cert_file, - 'key_file': configuration.key_file, - 'ca_cert_data': configuration.ca_cert_data, + "cert_reqs": cert_reqs, + "ca_certs": configuration.ssl_ca_cert, + "cert_file": configuration.cert_file, + "key_file": configuration.key_file, + "ca_cert_data": configuration.ca_cert_data, } if configuration.assert_hostname is not None: - pool_args['assert_hostname'] = configuration.assert_hostname + pool_args['assert_hostname'] = ( + configuration.assert_hostname + ) if configuration.retries is not None: pool_args['retries'] = configuration.retries @@ -95,6 +96,7 @@ def __init__(self, configuration: Configuration) -> None: if configuration.tls_server_name: pool_args['server_hostname'] = configuration.tls_server_name + if configuration.socket_options is not None: pool_args['socket_options'] = configuration.socket_options @@ -107,13 +109,12 @@ def __init__(self, configuration: Configuration) -> None: if configuration.proxy: if is_socks_proxy_url(configuration.proxy): from urllib3.contrib.socks import SOCKSProxyManager - - pool_args['proxy_url'] = configuration.proxy - pool_args['headers'] = configuration.proxy_headers + pool_args["proxy_url"] = configuration.proxy + pool_args["headers"] = configuration.proxy_headers self.pool_manager = SOCKSProxyManager(**pool_args) else: - pool_args['proxy_url'] = configuration.proxy - pool_args['proxy_headers'] = configuration.proxy_headers + pool_args["proxy_url"] = configuration.proxy + pool_args["proxy_headers"] = configuration.proxy_headers self.pool_manager = urllib3.ProxyManager(**pool_args) else: self.pool_manager = urllib3.PoolManager(**pool_args) @@ -142,10 +143,20 @@ def request( (connection, read) timeouts. """ method = method.upper() - assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH', 'OPTIONS'] + assert method in [ + 'GET', + 'HEAD', + 'DELETE', + 'POST', + 'PUT', + 'PATCH', + 'OPTIONS' + ] if post_params and body: - raise ApiValueError('body parameter cannot be used with post_params parameter.') + raise ApiValueError( + "body parameter cannot be used with post_params parameter." + ) post_params = post_params or [] headers = headers or {} @@ -154,15 +165,25 @@ def request( if _request_timeout: if isinstance(_request_timeout, (int, float)): timeout = urllib3.Timeout(total=_request_timeout) - elif isinstance(_request_timeout, tuple) and len(_request_timeout) == 2: - timeout = urllib3.Timeout(connect=_request_timeout[0], read=_request_timeout[1]) + elif ( + isinstance(_request_timeout, tuple) + and len(_request_timeout) == 2 + ): + timeout = urllib3.Timeout( + connect=_request_timeout[0], + read=_request_timeout[1] + ) try: # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: + # no content type provided or payload is json content_type = headers.get('Content-Type') - if not content_type or re.search('json', content_type, re.IGNORECASE): + if ( + not content_type + or re.search('json', content_type, re.IGNORECASE) + ): request_body = None if body is not None: request_body = json.dumps(body) @@ -172,7 +193,7 @@ def request( body=request_body, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) elif content_type == 'application/x-www-form-urlencoded': r = self.pool_manager.request( @@ -182,7 +203,7 @@ def request( encode_multipart=False, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) elif content_type == 'multipart/form-data': # must del headers['Content-Type'], or the correct @@ -190,10 +211,7 @@ def request( # overwritten. del headers['Content-Type'] # Ensures that dict objects are serialized - post_params = [ - (a, json.dumps(b)) if isinstance(b, dict) else (a, b) - for a, b in post_params - ] + post_params = [(a, json.dumps(b)) if isinstance(b, dict) else (a,b) for a, b in post_params] r = self.pool_manager.request( method, url, @@ -201,7 +219,7 @@ def request( encode_multipart=True, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) # Pass a `string` parameter directly in the body to support # other content types than JSON when `body` argument is @@ -213,18 +231,17 @@ def request( body=body, timeout=timeout, headers=headers, - preload_content=False, + preload_content=False ) elif headers['Content-Type'].startswith('text/') and isinstance(body, bool): - request_body = 'true' if body else 'false' + request_body = "true" if body else "false" r = self.pool_manager.request( method, url, body=request_body, preload_content=False, timeout=timeout, - headers=headers, - ) + headers=headers) else: # Cannot generate the request from given parameters msg = """Cannot prepare a request message for provided @@ -234,10 +251,15 @@ def request( # For `GET`, `HEAD` else: r = self.pool_manager.request( - method, url, fields={}, timeout=timeout, headers=headers, preload_content=False + method, + url, + fields={}, + timeout=timeout, + headers=headers, + preload_content=False ) except urllib3.exceptions.SSLError as e: - msg = '\n'.join([type(e).__name__, str(e)]) + msg = "\n".join([type(e).__name__, str(e)]) raise ApiException(status=0, reason=msg) from e return RESTResponse(r) # type: ignore[arg-type] diff --git a/fingerprint_server_sdk/sealed.py b/fingerprint_server_sdk/sealed.py index 7f8ef22d..899f4ca7 100644 --- a/fingerprint_server_sdk/sealed.py +++ b/fingerprint_server_sdk/sealed.py @@ -5,7 +5,7 @@ from fingerprint_server_sdk.models.event import Event -SEALED_HEADER = bytes([0x9E, 0x85, 0xDC, 0xED]) +SEALED_HEADER = bytes([0x9e, 0x85, 0xdc, 0xed]) DecryptionAlgorithm = { 'Aes256Gcm': 'aes-256-gcm', } @@ -13,7 +13,6 @@ class DecryptionKey: """Key for decryption of sealed data.""" - key: bytes algorithm: str @@ -24,7 +23,6 @@ def __init__(self, key: bytes, algorithm: str): class UnsealError(Exception): """Error during unsealing.""" - exception: Exception key: DecryptionKey @@ -35,12 +33,11 @@ def __init__(self, exception: Exception, key: DecryptionKey): class UnsealAggregateError(Exception): """Aggregated error during unsealing.""" - errors: list[UnsealError] def __init__(self, errors: list[UnsealError]): self.errors = errors - super().__init__('Unable to decrypt sealed data') + super().__init__("Unable to decrypt sealed data") def unseal_event_response(sealed_data: bytes, decryption_keys: list[DecryptionKey]) -> Event: @@ -56,6 +53,9 @@ def __parse_event_response(unsealed: str) -> Event: if 'event_id' not in json_data: raise ValueError('Sealed data is not valid event response') + # SPIKE INTER-2457 — RUNTIME BREAK. Event.from_dict requires `source` and + # returns a oneOf wrapper. Callers of unseal_event_response that then read + # `.identification` raise AttributeError. result = Event.from_dict(json_data) if result is None: raise ValueError('Failed to parse event response') @@ -64,7 +64,7 @@ def __parse_event_response(unsealed: str) -> Event: def __unseal(sealed_data: bytes, decryption_keys: list[DecryptionKey]) -> str: """Unseal data with one of the provided keys.""" - if sealed_data[: len(SEALED_HEADER)].hex() != SEALED_HEADER.hex(): + if sealed_data[:len(SEALED_HEADER)].hex() != SEALED_HEADER.hex(): raise ValueError('Invalid sealed data header') errors = [] @@ -76,7 +76,7 @@ def __unseal(sealed_data: bytes, decryption_keys: list[DecryptionKey]) -> str: errors.append(UnsealError(e, decryption_key)) continue else: - raise ValueError(f'Unsupported decryption algorithm: {decryption_key.algorithm}') + raise ValueError(f"Unsupported decryption algorithm: {decryption_key.algorithm}") raise UnsealAggregateError(errors) @@ -84,14 +84,17 @@ def __unseal(sealed_data: bytes, decryption_keys: list[DecryptionKey]) -> str: def __unseal_aes256gcm(sealed_data: bytes, decryption_key: bytes) -> str: """Unseal data with AES-256-GCM.""" nonce_length = 12 - nonce = sealed_data[len(SEALED_HEADER) : len(SEALED_HEADER) + nonce_length] + nonce = sealed_data[len(SEALED_HEADER):len(SEALED_HEADER) + nonce_length] auth_tag_length = 16 auth_tag = sealed_data[-auth_tag_length:] - ciphertext = sealed_data[len(SEALED_HEADER) + nonce_length : -auth_tag_length] + ciphertext = sealed_data[len(SEALED_HEADER) + nonce_length:-auth_tag_length] - decipher = Cipher(algorithms.AES(decryption_key), modes.GCM(nonce, auth_tag)).decryptor() + decipher = Cipher( + algorithms.AES(decryption_key), + modes.GCM(nonce, auth_tag) + ).decryptor() compressed = decipher.update(ciphertext) + decipher.finalize() diff --git a/generate.sh b/generate.sh index 739fc46b..b3a8e0c4 100755 --- a/generate.sh +++ b/generate.sh @@ -41,6 +41,10 @@ if [ $? -ne 0 ]; then exit 1 fi +# Event source hydrate lives outside generated models so generate can wipe +# fingerprint_server_sdk without losing the oneOf omit→device step. +cp ./scripts/event_source.py ./fingerprint_server_sdk/event_source.py + # Linting and formatting uv run ruff format . uv run ruff check --fix --unsafe-fixes . diff --git a/res/fingerprint-server-api.yaml b/res/fingerprint-server-api.yaml index 5e7a37ba..88835dd7 100644 --- a/res/fingerprint-server-api.yaml +++ b/res/fingerprint-server-api.yaml @@ -37,6 +37,97 @@ servers: security: - bearerAuth: [] paths: + /edge: + post: + tags: + - Fingerprint + operationId: analyzeRequestForAutomationIntelligence + summary: Collect Automation Intelligence. + description: > + The Automation Intelligence API gives you the tools to determine whether + traffic is legitimate and should be accepted by your application. + + + This feature is currently in a Public Preview testing phase. All + feedback is welcome! If you encounter any issues, please [contact our + support team](https://fingerprint.com/support/). + + + The API detects automation tools like AI Agents, AI Assistants, AI + Browsers, and other bots. Additionally, it provides IP intelligence like + geolocation, residential proxy, VPN and data center detection. + + + Automation Intelligence is derived from HTTP request metadata that + reaches your server. It does not require the use of a JavaScript + client-side agent or mobile SDKs to collect device context. + + + The API is fast, with average response times of less than 30ms, making + it a great fit for edge, pre-origin or middleware contexts. The API is + platform-agnostic and can be used with different CDN providers, cloud + platforms, or any server backend. + + + Because this API doesn’t require the use of a client-side device + collection agent, it doesn’t support device identification via + `visitor_id` and a few Smart Signals derived from deep device telemetry. + + + ### Event Retrieval + + + Events created by the Automation Intelligence API can be fetched via the + [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) + API using the `event_id` present in the API response. + + + Fetch all Automation Intelligence API events via the + [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) + API. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EdgeRequest' + responses: + '200': + description: OK. + content: + application/json: + schema: + $ref: '#/components/schemas/EventEdge' + '400': + description: Bad request. The request payload is not valid. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden. Access to this API is denied. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '413': + description: Bad request. The request payload is too large. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '429': + description: Too Many Requests. The request is throttled. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Workspace error. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /events/{event_id}: get: tags: @@ -44,12 +135,15 @@ paths: operationId: getEvent summary: Get an event by event ID description: > - Get a detailed analysis of an individual identification event, including - Smart Signals. + Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + + + Returns `EventDevice` when `source` is `device`, and `EventEdge` when + `source` is `edge`. parameters: - name: event_id in: path @@ -61,7 +155,7 @@ paths: example: 1708102555327.NLOjmg description: >- The unique - [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) + [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). - name: ruleset_id @@ -165,7 +259,7 @@ paths: example: 1708102555327.NLOjmg description: >- The unique event - [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). + [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). requestBody: required: true content: @@ -317,7 +411,7 @@ paths: example: Ibk1527CUFmcnjLwIs4A9 description: > Unique [visitor - identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) + identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. @@ -492,7 +586,7 @@ paths: You can use [linked - Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) + Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated @@ -940,6 +1034,18 @@ paths: > Note: When using this parameter, only events with the `simulator` property set to `true` or `false` are returned. Events without a `simulator` Smart Signal result are left out of the response. + - name: active_call + in: query + schema: + type: boolean + description: > + Filter events by Active Call Detection result on mobile devices. + + + > Note: When using this parameter, only events with the + `active_call` property set to `true` or `false` are returned. Events + without an `active_call` Smart Signal result are left out of the + response. - name: source in: query required: false @@ -963,18 +1069,6 @@ paths: > Note: The Automation Intelligence API is in public preview testing phase. If you encounter any issues, please [contact](https://fingerprint.com/support/) our support team. - - name: active_call - in: query - schema: - type: boolean - description: > - Filter events by Active Call Detection result on mobile devices. - - - > Note: When using this parameter, only events with the - `active_call` property set to `true` or `false` are returned. Events - without an `active_call` Smart Signal result are left out of the - response. responses: '200': description: Events matching the filter(s). @@ -1110,7 +1204,7 @@ paths: example: Ibk1527CUFmcnjLwIs4A9 description: >- The [visitor - ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) + ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. responses: '200': @@ -1163,6 +1257,127 @@ components: identification request or updated later. additionalProperties: true required: [] + EdgeRequest: + type: object + description: >- + HTTP request metadata (including the HTTP method, headers and IP + address) sent by you (your server) to the Fingerprint API for IP and bot + analysis. To improve accuracy, retain as much of the original semantics + of the HTTP request as possible. For example, preserve the order of the + request headers and their capitalization. + + At least one of `ipv4_address` or `ipv6_address` must be provided; a + request with neither is rejected with a `400` error. If both IPv4 and + IPv6 are provided, IP intelligence will be provided for each address. If + an IPv4-mapped IPv6 address is provided in the `ipv6_address` request + property, the IP intelligence will be provided in the `ipv4_address` + property of the response. + required: + - headers + - method + - url + properties: + headers: + type: array + description: > + Ordered header entries from the request made to your server. Each + entry represents one header line. If one header name appears as + multiple lines, send each as a separate item in the array. + + + Headers that contain authentication or session data must still be + included, but with with their value set to an empty string. This + includes headers like `Authorization` and `Cookie`, but may contain + more depending on your specific project, for instance + `Proxy-Authenticate` or `X-Api-Key`. Omitting the headers entirely + changes the shape of the request and can affect detection. Never + forward the real secret values. + + + Whenever possible, we recommend preserving header order and + capitalization to provide the best accuracy, however it’s not a + strict requirement if your runtime does not maintain http header + order or canonicalizes header names. + minItems: 1 + items: + type: object + required: + - name + - value + properties: + name: + type: string + examples: + - User-Agent + description: >- + Header name as forwarded by your server. Headers must be valid + according to RFC 7230 and will be canonicalized according to + RFC 9112. + value: + type: string + examples: + - Mozilla/5.0 + description: >- + Value of a single forwarded header entry. Be careful to + preserve the original encoding and escaping. For example, do + not double escape quotes. + examples: + - - name: Host + value: example.com + - name: User-Agent + value: Mozilla/5.0 + - name: Accept-Language + value: en-US,en;q=0.9 + - - name: Host + value: example.com + - name: User-Agent + value: Mozilla/5.0 + - name: Accept-Encoding + value: gzip + - name: Accept-Encoding + value: deflate + method: + type: string + description: >- + The original HTTP method of the request. If supported in your + runtime, preserve the original casing. + examples: + - GET + - POST + - PUT + - PATCH + - DELETE + url: + type: string + description: >- + Absolute URL of the request, without a \#fragment suffix. Only HTTP + and HTTPS schemes are supported. + format: uri + examples: + - http://example.com + - https://example.com/checkout?method=card + ipv4_address: + type: string + description: Client IPv4 address observed by your server. + format: ipv4 + examples: + - 34.162.244.71 + - 3.208.0.3 + - 173.56.0.4 + ipv6_address: + type: string + description: Client IPv6 address observed by your server. + format: ipv6 + examples: + - 2001:4860:4801:10::1 + - 2600:1f42:abcd:5678:9876:fedc:1357:2468 + - 2001:4868:85f:1a2b:3c4d:5e6f:7890:abcd + - ::ffff:22a2:f447 + - ::ffff:34.162.244.71 + linked_id: + $ref: '#/components/schemas/LinkedId' + tags: + $ref: '#/components/schemas/Tags' EventId: type: string examples: @@ -1176,19 +1391,6 @@ components: format: int64 examples: - 1708102555327 - EventSource: - type: string - description: > - Identifies how the event was generated. - - - `device` - the event was generated by the JS agent or a mobile SDK - running on an end-user device. - - - `edge` - the event was generated by the Automation Intelligence API - (`/edge` endpoint), analyzing a request intercepted at the edge. - enum: - - device - - edge Url: type: string examples: @@ -1596,6 +1798,109 @@ components: description: > `true` if the request came from a device running a VPN, `false` otherwise. + EventSource: + type: string + description: > + Identifies how the event was generated. + + - `device` - the event was generated by the JS agent or a mobile SDK + running on an end-user device. + + - `edge` - the event was generated by the Automation Intelligence API + (`/edge` endpoint), analyzing a request intercepted at the edge. + enum: + - device + - edge + EventEdge: + type: object + description: > + IP and bot analysis for an event generated by the Automation + Intelligence API (`/edge` endpoint). No client-side collection agent is + involved, so Identification (`visitor_id`) and device-telemetry-derived + Smart Signals are not available. + properties: + event_id: + $ref: '#/components/schemas/EventId' + x-platforms: + - android + - ios + - browser + timestamp: + $ref: '#/components/schemas/Timestamp' + x-platforms: + - android + - ios + - browser + linked_id: + $ref: '#/components/schemas/LinkedId' + x-platforms: + - android + - ios + - browser + tags: + $ref: '#/components/schemas/Tags' + x-platforms: + - android + - ios + - browser + url: + $ref: '#/components/schemas/Url' + x-platforms: + - browser + bot_info: + $ref: '#/components/schemas/BotInfo' + x-platforms: + - browser + ip_info: + $ref: '#/components/schemas/IPInfo' + x-platforms: + - android + - ios + - browser + proxy: + $ref: '#/components/schemas/Proxy' + x-platforms: + - android + - ios + - browser + proxy_confidence: + $ref: '#/components/schemas/ProxyConfidence' + x-platforms: + - android + - ios + - browser + proxy_details: + $ref: '#/components/schemas/ProxyDetails' + x-platforms: + - android + - ios + - browser + vpn: + $ref: '#/components/schemas/Vpn' + x-platforms: + - android + - ios + - browser + vpn_confidence: + $ref: '#/components/schemas/VpnConfidence' + x-platforms: + - android + - ios + - browser + vpn_methods: + $ref: '#/components/schemas/VpnMethods' + x-platforms: + - android + - ios + - browser + source: + $ref: '#/components/schemas/EventSource' + const: edge + required: + - event_id + - timestamp + - source + - ip_info ErrorCode: type: string enum: @@ -1715,7 +2020,7 @@ components: description: >- Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event - endpoint](https://docs.fingerprint.com/reference/server-api-v4-update-event). + endpoint](https://docs.fingerprint.com/reference/server-api-update-event). Integration: type: object required: [] @@ -3082,18 +3387,13 @@ components: case. This field is in the beta phase and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). - Event: + EventDevice: type: object - description: >- - Contains results from Fingerprint Identification and all active Smart - Signals. Some Smart Signals are only supported for certain device types, - these fields will be omitted for events not generated from the supported - devices. Consult the [Smart Signals + description: > + Contains results from Fingerprint Identification and Smart Signals + derived from client-side device telemetry. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. - required: - - event_id - - timestamp properties: event_id: $ref: '#/components/schemas/EventId' @@ -3107,22 +3407,79 @@ components: - android - ios - browser - source: - $ref: '#/components/schemas/EventSource' + linked_id: + $ref: '#/components/schemas/LinkedId' x-platforms: - android - ios - browser - incremental_identification_status: - $ref: '#/components/schemas/IncrementalIdentificationStatus' + tags: + $ref: '#/components/schemas/Tags' x-platforms: + - android + - ios - browser - linked_id: - $ref: '#/components/schemas/LinkedId' + url: + $ref: '#/components/schemas/Url' + x-platforms: + - browser + bot_info: + $ref: '#/components/schemas/BotInfo' + x-platforms: + - browser + ip_info: + $ref: '#/components/schemas/IPInfo' + x-platforms: + - android + - ios + - browser + proxy: + $ref: '#/components/schemas/Proxy' + x-platforms: + - android + - ios + - browser + proxy_confidence: + $ref: '#/components/schemas/ProxyConfidence' + x-platforms: + - android + - ios + - browser + proxy_details: + $ref: '#/components/schemas/ProxyDetails' + x-platforms: + - android + - ios + - browser + vpn: + $ref: '#/components/schemas/Vpn' x-platforms: - android - ios - browser + vpn_confidence: + $ref: '#/components/schemas/VpnConfidence' + x-platforms: + - android + - ios + - browser + vpn_methods: + $ref: '#/components/schemas/VpnMethods' + x-platforms: + - android + - ios + - browser + source: + $ref: '#/components/schemas/EventSource' + const: device + x-platforms: + - android + - ios + - browser + incremental_identification_status: + $ref: '#/components/schemas/IncrementalIdentificationStatus' + x-platforms: + - browser environment_id: $ref: '#/components/schemas/EnvironmentId' x-platforms: @@ -3159,16 +3516,6 @@ components: - android - ios - browser - tags: - $ref: '#/components/schemas/Tags' - x-platforms: - - android - - ios - - browser - url: - $ref: '#/components/schemas/Url' - x-platforms: - - browser bundle_id: $ref: '#/components/schemas/BundleId' x-platforms: @@ -3234,10 +3581,6 @@ components: $ref: '#/components/schemas/BotType' x-platforms: - browser - bot_info: - $ref: '#/components/schemas/BotInfo' - x-platforms: - - browser cloned_app: $ref: '#/components/schemas/ClonedApp' x-platforms: @@ -3268,30 +3611,6 @@ components: - android - ios - browser - ip_info: - $ref: '#/components/schemas/IPInfo' - x-platforms: - - android - - ios - - browser - proxy: - $ref: '#/components/schemas/Proxy' - x-platforms: - - android - - ios - - browser - proxy_confidence: - $ref: '#/components/schemas/ProxyConfidence' - x-platforms: - - android - - ios - - browser - proxy_details: - $ref: '#/components/schemas/ProxyDetails' - x-platforms: - - android - - ios - - browser proxy_ml_score: $ref: '#/components/schemas/ProxyMLScore' x-platforms: @@ -3372,18 +3691,6 @@ components: $ref: '#/components/schemas/VirtualMachineMLScore' x-platforms: - browser - vpn: - $ref: '#/components/schemas/Vpn' - x-platforms: - - android - - ios - - browser - vpn_confidence: - $ref: '#/components/schemas/VpnConfidence' - x-platforms: - - android - - ios - - browser vpn_ml_score: $ref: '#/components/schemas/VpnMLScore' x-platforms: @@ -3399,12 +3706,6 @@ components: x-platforms: - android - ios - vpn_methods: - $ref: '#/components/schemas/VpnMethods' - x-platforms: - - android - - ios - - browser high_activity_device: $ref: '#/components/schemas/HighActivity' x-platforms: @@ -3431,6 +3732,32 @@ components: - browser - ios - android + required: + - event_id + - timestamp + - source + Event: + type: object + description: > + An identification event (`source: device`) or an Automation Intelligence + event (`source: edge`). + + + Use `source` to tell them apart. Device events include Identification + and device-derived Smart Signals. Edge events do not. + + + Consult the [Smart Signals + reference](https://docs.fingerprint.com/docs/smart-signals-reference) + for more details. + oneOf: + - $ref: '#/components/schemas/EventDevice' + - $ref: '#/components/schemas/EventEdge' + discriminator: + propertyName: source + mapping: + device: '#/components/schemas/EventDevice' + edge: '#/components/schemas/EventEdge' EventUpdate: type: object required: [] diff --git a/scripts/event_source.py b/scripts/event_source.py new file mode 100644 index 00000000..a350edc0 --- /dev/null +++ b/scripts/event_source.py @@ -0,0 +1,19 @@ +"""Hydrate a missing Event source before oneOf discriminator lookup.""" + +from __future__ import annotations + +import json +from typing import Any + + +def hydrate_event_discriminator(class_name: str, json_str: str, property_name: str) -> tuple[str, Any]: + payload = json.loads(json_str) + data_type = payload.get(property_name) + if class_name != "Event": + return json_str, data_type + if data_type is None or data_type == "": + payload["source"] = "device" + return json.dumps(payload), "device" + if data_type not in ("device", "edge"): + raise ValueError(f"unknown Event source: {data_type!r}") + return json_str, data_type diff --git a/template/model_oneof.mustache b/template/model_oneof.mustache index e04708a0..db38fa7a 100644 --- a/template/model_oneof.mustache +++ b/template/model_oneof.mustache @@ -10,6 +10,7 @@ from typing import Any, Optional, Union {{{.}}} {{/vendorExtensions.x-py-model-imports}} from typing_extensions import Self +from fingerprint_server_sdk.event_source import hydrate_event_discriminator {{#lambda.uppercase}}{{{classname}}}{{/lambda.uppercase}}_ONE_OF_SCHEMAS = [{{#oneOf}}"{{.}}"{{^-last}}, {{/-last}}{{/oneOf}}] @@ -118,8 +119,8 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}} {{#mappedModels}} {{#-first}} # use oneOf discriminator to lookup the data type - _data_type = json.loads(json_str).get("{{{propertyBaseName}}}") - if not _data_type: + json_str, _data_type = hydrate_event_discriminator("{{classname}}", json_str, "{{{propertyBaseName}}}") + if "{{classname}}" != "Event" and not _data_type: raise ValueError("Failed to lookup data type from the field `{{{propertyBaseName}}}` in the input.") {{/-first}} diff --git a/test/test_event_source_hydrate.py b/test/test_event_source_hydrate.py new file mode 100644 index 00000000..a5d1f1aa --- /dev/null +++ b/test/test_event_source_hydrate.py @@ -0,0 +1,63 @@ +import json +import unittest +from pathlib import Path +from typing import Any + +from fingerprint_server_sdk import Event +from fingerprint_server_sdk.models.event_device import EventDevice +from fingerprint_server_sdk.models.event_edge import EventEdge +from fingerprint_server_sdk.models.event_source import EventSource + +MOCK_DIR = Path(__file__).resolve().parent / 'mocks' + + +class TestEventSourceHydrate(unittest.TestCase): + """Omit source hydrates to EventDevice; edge stays EventEdge.""" + + def _load_event_json(self) -> dict[str, Any]: + mock_file = MOCK_DIR / 'events' / 'get_event_200.json' + return json.loads(mock_file.read_text(encoding='utf-8')) + + def test_omit_source_deserializes_event_device(self) -> None: + data = self._load_event_json() + data.pop('source', None) + + event = Event.from_json(json.dumps(data)) + + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.source, EventSource.DEVICE) + + def test_edge_source_stays_event_edge(self) -> None: + data = self._load_event_json() + edge_payload = { + 'event_id': data['event_id'], + 'timestamp': data['timestamp'], + 'ip_info': data['ip_info'], + 'source': 'edge', + } + + event = Event.from_json(json.dumps(edge_payload)) + + self.assertIsInstance(event.actual_instance, EventEdge) + self.assertEqual(event.actual_instance.source, EventSource.EDGE) + self.assertNotEqual(event.actual_instance.source, EventSource.DEVICE) + + def test_empty_source_deserializes_event_device(self) -> None: + data = self._load_event_json() + data['source'] = '' + + event = Event.from_json(json.dumps(data)) + + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.source, EventSource.DEVICE) + + def test_unknown_source_fails(self) -> None: + data = self._load_event_json() + data['source'] = 'webhook' + + with self.assertRaisesRegex(ValueError, 'unknown Event source'): + Event.from_json(json.dumps(data)) + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_fingerprint_api.py b/test/test_fingerprint_api.py index 6ee8c73d..39d93767 100644 --- a/test/test_fingerprint_api.py +++ b/test/test_fingerprint_api.py @@ -238,6 +238,8 @@ def test_get_event_with_unknown_field(self) -> None: event_response = self.api.get_event(event_id) self.assertIsInstance(event_response, Event) + # SPIKE INTER-2457 — RUNTIME BREAK. Event has no `identification`. + # This raises AttributeError. Identification is on EventDevice via actual_instance. self.assertEqual(event_response.identification.visitor_id, 'Ibk1527CUFmcnjLwIs4A9') def test_get_event_bad_request(self) -> None: diff --git a/test/test_unknown_enum_values.py b/test/test_unknown_enum_values.py index 9020f0db..ff8e14f7 100644 --- a/test/test_unknown_enum_values.py +++ b/test/test_unknown_enum_values.py @@ -5,6 +5,8 @@ from fingerprint_server_sdk import Event from fingerprint_server_sdk.models.bot_info import BotInfo +from fingerprint_server_sdk.models.event_device import EventDevice +from fingerprint_server_sdk.models.event_edge import EventEdge from fingerprint_server_sdk.models.event_source import EventSource from fingerprint_server_sdk.models.proxy_details import ProxyDetails from fingerprint_server_sdk.models.sdk import SDK @@ -25,8 +27,8 @@ def test_event_with_unknown_proxy_type(self) -> None: data['proxy_details']['proxy_type'] = 'unknown-value' event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.proxy_details.proxy_type, 'unknown-value') + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.proxy_details.proxy_type, 'unknown-value') def test_event_with_unknown_sdk_platform(self) -> None: """Unknown SDK platform value should be accepted and preserved.""" @@ -34,8 +36,8 @@ def test_event_with_unknown_sdk_platform(self) -> None: data['sdk']['platform'] = 'new-platform' event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.sdk.platform, 'new-platform') + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.sdk.platform, 'new-platform') def test_event_with_unknown_bot_result(self) -> None: """Unknown bot result value should be accepted and preserved.""" @@ -43,8 +45,8 @@ def test_event_with_unknown_bot_result(self) -> None: data['bot'] = 'unknown-value' event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.bot, 'unknown-value') + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.bot, 'unknown-value') def test_event_with_unknown_vpn_confidence(self) -> None: """Unknown vpn_confidence value should be accepted and preserved.""" @@ -53,8 +55,8 @@ def test_event_with_unknown_vpn_confidence(self) -> None: data['vpn_confidence'] = 'unknown-value' event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.vpn_confidence, 'unknown-value') + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.vpn_confidence, 'unknown-value') def test_event_with_unknown_proxy_confidence(self) -> None: """Unknown proxy_confidence value should be accepted and preserved.""" @@ -62,8 +64,8 @@ def test_event_with_unknown_proxy_confidence(self) -> None: data['proxy_confidence'] = 'unknown-value' event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.proxy_confidence, 'unknown-value') + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.proxy_confidence, 'unknown-value') def test_event_with_unknown_tampering_confidence(self) -> None: """Unknown tampering_confidence value should be accepted and preserved.""" @@ -71,8 +73,8 @@ def test_event_with_unknown_tampering_confidence(self) -> None: data['tampering_confidence'] = 'unknown-value' event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.tampering_confidence, 'unknown-value') + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.tampering_confidence, 'unknown-value') def test_event_with_unknown_rare_device_percentile_bucket(self) -> None: """Unknown rare_device_percentile_bucket value should be accepted and preserved.""" @@ -80,26 +82,25 @@ def test_event_with_unknown_rare_device_percentile_bucket(self) -> None: data['rare_device_percentile_bucket'] = 'unknown-value' event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.rare_device_percentile_bucket, 'unknown-value') + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.rare_device_percentile_bucket, 'unknown-value') def test_event_with_unknown_source(self) -> None: - """Unknown source value should be accepted and preserved.""" + """Unknown non-empty source cannot pick an Event oneOf variant.""" data = self._load_event_json() data['source'] = 'unknown-value' - event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.source, 'unknown-value') + with self.assertRaisesRegex(ValueError, "unknown Event source"): + Event.from_json(json.dumps(data)) def test_event_without_source(self) -> None: - """Event should deserialize when the optional source field is absent.""" + """Omit source hydrates to EventDevice.""" data = self._load_event_json() data.pop('source', None) event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertIsNone(event.source) + self.assertIsInstance(event.actual_instance, EventDevice) + self.assertEqual(event.actual_instance.source, EventSource.DEVICE) def test_proxy_details_with_unknown_proxy_type(self) -> None: """ProxyDetails model should accept unknown proxy_type directly.""" @@ -139,37 +140,42 @@ def test_event_with_multiple_unknown_enum_values(self) -> None: data['proxy_confidence'] = 'unknown-value' data['tampering_confidence'] = 'unknown-value' data['rare_device_percentile_bucket'] = 'unknown-value' - data['source'] = 'unknown-value' event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.proxy_details.proxy_type, 'unknown-value') - self.assertEqual(event.sdk.platform, 'unknown-value') - self.assertEqual(event.bot, 'unknown-value') - self.assertEqual(event.vpn_confidence, 'unknown-value') - self.assertEqual(event.proxy_confidence, 'unknown-value') - self.assertEqual(event.tampering_confidence, 'unknown-value') - self.assertEqual(event.rare_device_percentile_bucket, 'unknown-value') - self.assertEqual(event.source, 'unknown-value') + actual = event.actual_instance + self.assertIsInstance(actual, EventDevice) + self.assertEqual(actual.proxy_details.proxy_type, 'unknown-value') + self.assertEqual(actual.sdk.platform, 'unknown-value') + self.assertEqual(actual.bot, 'unknown-value') + self.assertEqual(actual.vpn_confidence, 'unknown-value') + self.assertEqual(actual.proxy_confidence, 'unknown-value') + self.assertEqual(actual.tampering_confidence, 'unknown-value') + self.assertEqual(actual.rare_device_percentile_bucket, 'unknown-value') def test_known_enum_values_still_work(self) -> None: """Known enum values should continue to work as before.""" data = self._load_event_json() event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.proxy_details.proxy_type, 'residential') - self.assertEqual(event.sdk.platform, 'js') - self.assertEqual(event.source, EventSource.DEVICE) + actual = event.actual_instance + self.assertIsInstance(actual, EventDevice) + self.assertEqual(actual.proxy_details.proxy_type, 'residential') + self.assertEqual(actual.sdk.platform, 'js') + self.assertEqual(actual.source, EventSource.DEVICE) def test_event_with_edge_source(self) -> None: """The edge source value should be deserialized into the enum member.""" data = self._load_event_json() - data['source'] = 'edge' - - event = Event.from_json(json.dumps(data)) - self.assertIsInstance(event, Event) - self.assertEqual(event.source, EventSource.EDGE) + edge_payload = { + 'event_id': data['event_id'], + 'timestamp': data['timestamp'], + 'ip_info': data['ip_info'], + 'source': 'edge', + } + + event = Event.from_json(json.dumps(edge_payload)) + self.assertIsInstance(event.actual_instance, EventEdge) + self.assertEqual(event.actual_instance.source, EventSource.EDGE) if __name__ == '__main__':