Coverage for fingerprint_server_sdk / models / event.py: 74%
135 statements
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-15 09:18 +0000
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-15 09:18 +0000
1"""
2Server API
3Fingerprint 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.
4Server 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.
6The version of the OpenAPI document: 4
7Contact: support@fingerprint.com
8Generated by OpenAPI Generator (https://openapi-generator.tech)
10Do not edit the class manually.
11""" # noqa: E501
13from __future__ import annotations
15import json
16import pprint
17import re # noqa: F401
18from typing import Annotated, Any, ClassVar, Optional, Union
20from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
21from typing_extensions import Self
23from fingerprint_server_sdk.models.bot_info import BotInfo
24from fingerprint_server_sdk.models.bot_result import BotResult
25from fingerprint_server_sdk.models.browser_details import BrowserDetails
26from fingerprint_server_sdk.models.event_rule_action import EventRuleAction
27from fingerprint_server_sdk.models.identification import Identification
28from fingerprint_server_sdk.models.incremental_identification_status import (
29 IncrementalIdentificationStatus,
30)
31from fingerprint_server_sdk.models.ip_block_list import IPBlockList
32from fingerprint_server_sdk.models.ip_info import IPInfo
33from fingerprint_server_sdk.models.proximity import Proximity
34from fingerprint_server_sdk.models.proxy_confidence import ProxyConfidence
35from fingerprint_server_sdk.models.proxy_details import ProxyDetails
36from fingerprint_server_sdk.models.rare_device_percentile_bucket import RareDevicePercentileBucket
37from fingerprint_server_sdk.models.raw_device_attributes import RawDeviceAttributes
38from fingerprint_server_sdk.models.sdk import SDK
39from fingerprint_server_sdk.models.supplementary_id_high_recall import SupplementaryIDHighRecall
40from fingerprint_server_sdk.models.tampering_confidence import TamperingConfidence
41from fingerprint_server_sdk.models.tampering_details import TamperingDetails
42from fingerprint_server_sdk.models.velocity import Velocity
43from fingerprint_server_sdk.models.vpn_confidence import VpnConfidence
44from fingerprint_server_sdk.models.vpn_methods import VpnMethods
47class Event(BaseModel):
48 """
49 Contains results from Fingerprint Identification and all active Smart Signals.
50 """
52 event_id: StrictStr = Field(
53 description="Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp For example: `1758130560902.8tRtrH` "
54 )
55 timestamp: StrictInt = Field(
56 description='Timestamp of the event with millisecond precision in Unix time.'
57 )
58 incremental_identification_status: Optional[IncrementalIdentificationStatus] = None
59 linked_id: Optional[StrictStr] = Field(
60 default=None, description='A customer-provided id that was sent with the request.'
61 )
62 environment_id: Optional[StrictStr] = Field(
63 default=None,
64 description='Environment Id of the event. For example: `ae_47abaca3db2c7c43` ',
65 )
66 suspect: Optional[StrictBool] = Field(
67 default=None,
68 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).',
69 )
70 sdk: Optional[SDK] = None
71 replayed: Optional[StrictBool] = Field(
72 default=None,
73 description='`true` if we determined that this payload was replayed, `false` otherwise. ',
74 )
75 identification: Optional[Identification] = None
76 supplementary_id_high_recall: Optional[SupplementaryIDHighRecall] = None
77 tags: Optional[dict[str, Any]] = Field(
78 default=None,
79 description='A customer-provided value or an object that was sent with the identification request or updated later.',
80 )
81 url: Optional[StrictStr] = Field(
82 default=None,
83 description='Page URL from which the request was sent. For example `https://example.com/` ',
84 )
85 bundle_id: Optional[StrictStr] = Field(
86 default=None,
87 description='Bundle Id of the iOS application integrated with the Fingerprint SDK for the event. For example: `com.foo.app` ',
88 )
89 package_name: Optional[StrictStr] = Field(
90 default=None,
91 description='Package name of the Android application integrated with the Fingerprint SDK for the event. For example: `com.foo.app` ',
92 )
93 ip_address: Optional[StrictStr] = Field(
94 default=None, description='IP address of the requesting browser or bot.'
95 )
96 user_agent: Optional[StrictStr] = Field(
97 default=None,
98 description='User Agent of the client, for example: `Mozilla/5.0 (Windows NT 6.1; Win64; x64) ....` ',
99 )
100 client_referrer: Optional[StrictStr] = Field(
101 default=None,
102 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) For example: `https://example.com/blog/my-article` ',
103 )
104 browser_details: Optional[BrowserDetails] = None
105 proximity: Optional[Proximity] = None
106 bot: Optional[BotResult] = None
107 bot_type: Optional[StrictStr] = Field(
108 default=None, description='Additional classification of the bot type if detected. '
109 )
110 bot_info: Optional[BotInfo] = None
111 cloned_app: Optional[StrictBool] = Field(
112 default=None,
113 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. ',
114 )
115 developer_tools: Optional[StrictBool] = Field(
116 default=None,
117 description='`true` if the browser is Chrome with DevTools open or Firefox with Developer Tools open, `false` otherwise. ',
118 )
119 emulator: Optional[StrictBool] = Field(
120 default=None,
121 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. ',
122 )
123 factory_reset_timestamp: Optional[StrictInt] = Field(
124 default=None,
125 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. ',
126 )
127 frida: Optional[StrictBool] = Field(
128 default=None,
129 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. ',
130 )
131 ip_blocklist: Optional[IPBlockList] = None
132 ip_info: Optional[IPInfo] = None
133 proxy: Optional[StrictBool] = Field(
134 default=None,
135 description='IP address was used by a public proxy provider or belonged to a known recent residential proxy ',
136 )
137 proxy_confidence: Optional[ProxyConfidence] = None
138 proxy_details: Optional[ProxyDetails] = None
139 proxy_ml_score: Optional[
140 Union[
141 Annotated[float, Field(le=1, strict=True, ge=0)],
142 Annotated[int, Field(le=1, strict=True, ge=0)],
143 ]
144 ] = Field(
145 default=None,
146 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 ',
147 )
148 incognito: Optional[StrictBool] = Field(
149 default=None,
150 description='`true` if we detected incognito mode used in the browser, `false` otherwise. ',
151 )
152 jailbroken: Optional[StrictBool] = Field(
153 default=None,
154 description='iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. ',
155 )
156 location_spoofing: Optional[StrictBool] = Field(
157 default=None,
158 description='Flag indicating whether the request came from a mobile device with location spoofing enabled.',
159 )
160 mitm_attack: Optional[StrictBool] = Field(
161 default=None,
162 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. ",
163 )
164 privacy_settings: Optional[StrictBool] = Field(
165 default=None,
166 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`. ',
167 )
168 root_apps: Optional[StrictBool] = Field(
169 default=None,
170 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. ",
171 )
172 rule_action: Optional[EventRuleAction] = None
173 simulator: Optional[StrictBool] = Field(
174 default=None,
175 description='iOS specific simulator detection. There are 2 values: * `true` - Simulator environment detected. * `false` - No signs of simulator or the client is not iOS. ',
176 )
177 suspect_score: Optional[StrictInt] = Field(
178 default=None,
179 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 ',
180 )
181 tampering: Optional[StrictBool] = Field(
182 default=None,
183 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 ',
184 )
185 tampering_confidence: Optional[TamperingConfidence] = None
186 tampering_ml_score: Optional[
187 Union[
188 Annotated[float, Field(le=1, strict=True, ge=0)],
189 Annotated[int, Field(le=1, strict=True, ge=0)],
190 ]
191 ] = Field(
192 default=None,
193 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) ',
194 )
195 tampering_details: Optional[TamperingDetails] = None
196 velocity: Optional[Velocity] = None
197 virtual_machine: Optional[StrictBool] = Field(
198 default=None,
199 description='`true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. ',
200 )
201 virtual_machine_ml_score: Optional[
202 Union[
203 Annotated[float, Field(le=1, strict=True, ge=0)],
204 Annotated[int, Field(le=1, strict=True, ge=0)],
205 ]
206 ] = Field(
207 default=None,
208 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 ',
209 )
210 vpn: Optional[StrictBool] = Field(
211 default=None,
212 description='VPN or other anonymizing service has been used when sending the request. ',
213 )
214 vpn_confidence: Optional[VpnConfidence] = None
215 vpn_origin_timezone: Optional[StrictStr] = Field(
216 default=None, description='Local timezone which is used in timezone_mismatch method. '
217 )
218 vpn_origin_country: Optional[StrictStr] = Field(
219 default=None,
220 description='Country of the request (only for Android SDK version >= 2.4.0, ISO 3166 format or unknown). ',
221 )
222 vpn_methods: Optional[VpnMethods] = None
223 high_activity_device: Optional[StrictBool] = Field(
224 default=None,
225 description='Flag indicating if the request came from a high-activity visitor.',
226 )
227 rare_device: Optional[StrictBool] = Field(
228 default=None,
229 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/). ',
230 )
231 rare_device_percentile_bucket: Optional[RareDevicePercentileBucket] = None
232 raw_device_attributes: Optional[RawDeviceAttributes] = None
233 __properties: ClassVar[list[str]] = [
234 'event_id',
235 'timestamp',
236 'incremental_identification_status',
237 'linked_id',
238 'environment_id',
239 'suspect',
240 'sdk',
241 'replayed',
242 'identification',
243 'supplementary_id_high_recall',
244 'tags',
245 'url',
246 'bundle_id',
247 'package_name',
248 'ip_address',
249 'user_agent',
250 'client_referrer',
251 'browser_details',
252 'proximity',
253 'bot',
254 'bot_type',
255 'bot_info',
256 'cloned_app',
257 'developer_tools',
258 'emulator',
259 'factory_reset_timestamp',
260 'frida',
261 'ip_blocklist',
262 'ip_info',
263 'proxy',
264 'proxy_confidence',
265 'proxy_details',
266 'proxy_ml_score',
267 'incognito',
268 'jailbroken',
269 'location_spoofing',
270 'mitm_attack',
271 'privacy_settings',
272 'root_apps',
273 'rule_action',
274 'simulator',
275 'suspect_score',
276 'tampering',
277 'tampering_confidence',
278 'tampering_ml_score',
279 'tampering_details',
280 'velocity',
281 'virtual_machine',
282 'virtual_machine_ml_score',
283 'vpn',
284 'vpn_confidence',
285 'vpn_origin_timezone',
286 'vpn_origin_country',
287 'vpn_methods',
288 'high_activity_device',
289 'rare_device',
290 'rare_device_percentile_bucket',
291 'raw_device_attributes',
292 ]
294 model_config = ConfigDict(
295 populate_by_name=True,
296 validate_assignment=True,
297 protected_namespaces=(),
298 )
300 def to_str(self) -> str:
301 """Returns the string representation of the model using alias"""
302 return pprint.pformat(self.model_dump(by_alias=True))
304 def to_json(self) -> str:
305 """Returns the JSON representation of the model using alias"""
306 # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
307 return json.dumps(self.to_dict())
309 @classmethod
310 def from_json(cls, json_str: str) -> Optional[Self]:
311 """Create an instance of Event from a JSON string"""
312 return cls.from_dict(json.loads(json_str))
314 def to_dict(self) -> dict[str, Any]:
315 """Return the dictionary representation of the model using alias.
317 This has the following differences from calling pydantic's
318 `self.model_dump(by_alias=True)`:
320 * `None` is only added to the output dict for nullable fields that
321 were set at model initialization. Other fields with value `None`
322 are ignored.
323 """
324 excluded_fields: set[str] = set([])
326 _dict = self.model_dump(
327 by_alias=True,
328 exclude=excluded_fields,
329 exclude_none=True,
330 )
331 # override the default output from pydantic by calling `to_dict()` of sdk
332 if self.sdk:
333 _dict['sdk'] = self.sdk.to_dict()
334 # override the default output from pydantic by calling `to_dict()` of identification
335 if self.identification:
336 _dict['identification'] = self.identification.to_dict()
337 # override the default output from pydantic by calling `to_dict()` of supplementary_id_high_recall
338 if self.supplementary_id_high_recall:
339 _dict['supplementary_id_high_recall'] = self.supplementary_id_high_recall.to_dict()
340 # override the default output from pydantic by calling `to_dict()` of browser_details
341 if self.browser_details:
342 _dict['browser_details'] = self.browser_details.to_dict()
343 # override the default output from pydantic by calling `to_dict()` of proximity
344 if self.proximity:
345 _dict['proximity'] = self.proximity.to_dict()
346 # override the default output from pydantic by calling `to_dict()` of bot_info
347 if self.bot_info:
348 _dict['bot_info'] = self.bot_info.to_dict()
349 # override the default output from pydantic by calling `to_dict()` of ip_blocklist
350 if self.ip_blocklist:
351 _dict['ip_blocklist'] = self.ip_blocklist.to_dict()
352 # override the default output from pydantic by calling `to_dict()` of ip_info
353 if self.ip_info:
354 _dict['ip_info'] = self.ip_info.to_dict()
355 # override the default output from pydantic by calling `to_dict()` of proxy_details
356 if self.proxy_details:
357 _dict['proxy_details'] = self.proxy_details.to_dict()
358 # override the default output from pydantic by calling `to_dict()` of rule_action
359 if self.rule_action:
360 _dict['rule_action'] = self.rule_action.to_dict()
361 # override the default output from pydantic by calling `to_dict()` of tampering_details
362 if self.tampering_details:
363 _dict['tampering_details'] = self.tampering_details.to_dict()
364 # override the default output from pydantic by calling `to_dict()` of velocity
365 if self.velocity:
366 _dict['velocity'] = self.velocity.to_dict()
367 # override the default output from pydantic by calling `to_dict()` of vpn_methods
368 if self.vpn_methods:
369 _dict['vpn_methods'] = self.vpn_methods.to_dict()
370 # override the default output from pydantic by calling `to_dict()` of raw_device_attributes
371 if self.raw_device_attributes:
372 _dict['raw_device_attributes'] = self.raw_device_attributes.to_dict()
373 return _dict
375 @classmethod
376 def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]:
377 """Create an instance of Event from a dict"""
378 if obj is None:
379 return None
381 if not isinstance(obj, dict):
382 return cls.model_validate(obj)
384 _obj = cls.model_validate(
385 {
386 'event_id': obj.get('event_id'),
387 'timestamp': obj.get('timestamp'),
388 'incremental_identification_status': obj.get('incremental_identification_status'),
389 'linked_id': obj.get('linked_id'),
390 'environment_id': obj.get('environment_id'),
391 'suspect': obj.get('suspect'),
392 'sdk': SDK.from_dict(obj['sdk']) if obj.get('sdk') is not None else None,
393 'replayed': obj.get('replayed'),
394 'identification': Identification.from_dict(obj['identification'])
395 if obj.get('identification') is not None
396 else None,
397 'supplementary_id_high_recall': SupplementaryIDHighRecall.from_dict(
398 obj['supplementary_id_high_recall']
399 )
400 if obj.get('supplementary_id_high_recall') is not None
401 else None,
402 'tags': obj.get('tags'),
403 'url': obj.get('url'),
404 'bundle_id': obj.get('bundle_id'),
405 'package_name': obj.get('package_name'),
406 'ip_address': obj.get('ip_address'),
407 'user_agent': obj.get('user_agent'),
408 'client_referrer': obj.get('client_referrer'),
409 'browser_details': BrowserDetails.from_dict(obj['browser_details'])
410 if obj.get('browser_details') is not None
411 else None,
412 'proximity': Proximity.from_dict(obj['proximity'])
413 if obj.get('proximity') is not None
414 else None,
415 'bot': obj.get('bot'),
416 'bot_type': obj.get('bot_type'),
417 'bot_info': BotInfo.from_dict(obj['bot_info'])
418 if obj.get('bot_info') is not None
419 else None,
420 'cloned_app': obj.get('cloned_app'),
421 'developer_tools': obj.get('developer_tools'),
422 'emulator': obj.get('emulator'),
423 'factory_reset_timestamp': obj.get('factory_reset_timestamp'),
424 'frida': obj.get('frida'),
425 'ip_blocklist': IPBlockList.from_dict(obj['ip_blocklist'])
426 if obj.get('ip_blocklist') is not None
427 else None,
428 'ip_info': IPInfo.from_dict(obj['ip_info'])
429 if obj.get('ip_info') is not None
430 else None,
431 'proxy': obj.get('proxy'),
432 'proxy_confidence': obj.get('proxy_confidence'),
433 'proxy_details': ProxyDetails.from_dict(obj['proxy_details'])
434 if obj.get('proxy_details') is not None
435 else None,
436 'proxy_ml_score': obj.get('proxy_ml_score'),
437 'incognito': obj.get('incognito'),
438 'jailbroken': obj.get('jailbroken'),
439 'location_spoofing': obj.get('location_spoofing'),
440 'mitm_attack': obj.get('mitm_attack'),
441 'privacy_settings': obj.get('privacy_settings'),
442 'root_apps': obj.get('root_apps'),
443 'rule_action': EventRuleAction.from_dict(obj['rule_action'])
444 if obj.get('rule_action') is not None
445 else None,
446 'simulator': obj.get('simulator'),
447 'suspect_score': obj.get('suspect_score'),
448 'tampering': obj.get('tampering'),
449 'tampering_confidence': obj.get('tampering_confidence'),
450 'tampering_ml_score': obj.get('tampering_ml_score'),
451 'tampering_details': TamperingDetails.from_dict(obj['tampering_details'])
452 if obj.get('tampering_details') is not None
453 else None,
454 'velocity': Velocity.from_dict(obj['velocity'])
455 if obj.get('velocity') is not None
456 else None,
457 'virtual_machine': obj.get('virtual_machine'),
458 'virtual_machine_ml_score': obj.get('virtual_machine_ml_score'),
459 'vpn': obj.get('vpn'),
460 'vpn_confidence': obj.get('vpn_confidence'),
461 'vpn_origin_timezone': obj.get('vpn_origin_timezone'),
462 'vpn_origin_country': obj.get('vpn_origin_country'),
463 'vpn_methods': VpnMethods.from_dict(obj['vpn_methods'])
464 if obj.get('vpn_methods') is not None
465 else None,
466 'high_activity_device': obj.get('high_activity_device'),
467 'rare_device': obj.get('rare_device'),
468 'rare_device_percentile_bucket': obj.get('rare_device_percentile_bucket'),
469 'raw_device_attributes': RawDeviceAttributes.from_dict(
470 obj['raw_device_attributes']
471 )
472 if obj.get('raw_device_attributes') is not None
473 else None,
474 }
475 )
476 return _obj