Coverage for fingerprint_server_sdk/models/event.py: 72%
155 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-11-03 19:57 +0000
« prev ^ index » next coverage.py v7.14.3, created at 2026-11-03 19:57 +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.
5The API also supports collection of Automation Intelligence for requests to your server in edge, pre-origin, or middleware contexts.
7The version of the OpenAPI document: 4
8Contact: support@fingerprint.com
9Generated by OpenAPI Generator (https://openapi-generator.tech)
11Do not edit the class manually.
12""" # noqa: E501
14from __future__ import annotations
16import json
17import pprint
18import re # noqa: F401
19from typing import Annotated, Any, ClassVar, Optional, Union
21from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
22from typing_extensions import Self
24from fingerprint_server_sdk.models.bot_info import BotInfo
25from fingerprint_server_sdk.models.bot_result import BotResult
26from fingerprint_server_sdk.models.browser_details import BrowserDetails
27from fingerprint_server_sdk.models.device_details import DeviceDetails
28from fingerprint_server_sdk.models.event_rule_action import EventRuleAction
29from fingerprint_server_sdk.models.event_source import EventSource
30from fingerprint_server_sdk.models.identification import Identification
31from fingerprint_server_sdk.models.incremental_identification_status import (
32 IncrementalIdentificationStatus,
33)
34from fingerprint_server_sdk.models.ip_block_list import IPBlockList
35from fingerprint_server_sdk.models.ip_info import IPInfo
36from fingerprint_server_sdk.models.labels_inner import LabelsInner
37from fingerprint_server_sdk.models.proximity import Proximity
38from fingerprint_server_sdk.models.proxy_confidence import ProxyConfidence
39from fingerprint_server_sdk.models.proxy_details import ProxyDetails
40from fingerprint_server_sdk.models.rare_device_percentile_bucket import RareDevicePercentileBucket
41from fingerprint_server_sdk.models.raw_device_attributes import RawDeviceAttributes
42from fingerprint_server_sdk.models.sdk import SDK
43from fingerprint_server_sdk.models.supplementary_id_high_recall import SupplementaryIDHighRecall
44from fingerprint_server_sdk.models.tampering_confidence import TamperingConfidence
45from fingerprint_server_sdk.models.tampering_details import TamperingDetails
46from fingerprint_server_sdk.models.velocity import Velocity
47from fingerprint_server_sdk.models.vpn_confidence import VpnConfidence
48from fingerprint_server_sdk.models.vpn_methods import VpnMethods
51class Event(BaseModel):
52 """
53 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.
54 """
56 event_id: StrictStr = Field(
57 description="Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. "
58 )
59 timestamp: StrictInt = Field(
60 description='Timestamp of the event with millisecond precision in Unix time.'
61 )
62 source: Optional[EventSource] = None
63 incremental_identification_status: Optional[IncrementalIdentificationStatus] = None
64 linked_id: Optional[StrictStr] = Field(
65 default=None, description='A customer-provided ID that was sent with the request.'
66 )
67 environment_id: Optional[StrictStr] = Field(
68 default=None, description='Environment ID of the event.'
69 )
70 suspect: Optional[StrictBool] = Field(
71 default=None,
72 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).',
73 )
74 sdk: Optional[SDK] = None
75 replayed: Optional[StrictBool] = Field(
76 default=None,
77 description='`true` if we determined that this payload was replayed, `false` otherwise. ',
78 )
79 identification: Optional[Identification] = None
80 supplementary_id_high_recall: Optional[SupplementaryIDHighRecall] = None
81 tags: Optional[dict[str, Any]] = Field(
82 default=None,
83 description='A customer-provided value or an object that was sent with the identification request or updated later.',
84 )
85 url: Optional[StrictStr] = Field(
86 default=None, description='Page URL from which the request was sent.'
87 )
88 bundle_id: Optional[StrictStr] = Field(
89 default=None,
90 description='Bundle ID of the iOS application integrated with the Fingerprint SDK for the event. ',
91 )
92 package_name: Optional[StrictStr] = Field(
93 default=None,
94 description='Package name of the Android application integrated with the Fingerprint SDK for the event. ',
95 )
96 ip_address: Optional[StrictStr] = Field(
97 default=None, description='IP address of the requesting browser or bot.'
98 )
99 user_agent: Optional[StrictStr] = Field(default=None, description='User Agent of the client.')
100 device: Optional[StrictStr] = Field(
101 default=None,
102 description='Device model or family extracted from the user agent string. On web, this field is also present inside `browser_details`. ',
103 )
104 os: Optional[StrictStr] = Field(
105 default=None,
106 description='Operating system family extracted from the user agent string. On web, this field is also present inside `browser_details`. ',
107 )
108 os_version: Optional[StrictStr] = Field(
109 default=None,
110 description='Operating system version string extracted from the user agent string. On web, this field is also present inside `browser_details`. ',
111 )
112 client_referrer: Optional[StrictStr] = Field(
113 default=None,
114 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). ',
115 )
116 browser_details: Optional[BrowserDetails] = None
117 proximity: Optional[Proximity] = None
118 active_call: Optional[StrictBool] = Field(
119 default=None,
120 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. ',
121 )
122 bot: Optional[BotResult] = None
123 bot_type: Optional[StrictStr] = Field(
124 default=None, description='Additional classification of the bot type if detected. '
125 )
126 bot_info: Optional[BotInfo] = None
127 cloned_app: Optional[StrictBool] = Field(
128 default=None,
129 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. ',
130 )
131 compromised_device_integrity: Optional[StrictBool] = Field(
132 default=None,
133 description="`true` if the Android device's boot or system integrity is compromised (e.g., an unlocked bootloader or a failed verified boot), so the device cannot be trusted. `false` if no integrity issue was detected. Available from Android SDK 2.6.0+. ",
134 )
135 developer_tools: Optional[StrictBool] = Field(
136 default=None,
137 description='`true` if the browser has DevTools open (Chrome, Firefox) or the Android/iOS device has Developer Tools enabled, `false` otherwise. ',
138 )
139 device_details: Optional[DeviceDetails] = None
140 emulator: Optional[StrictBool] = Field(
141 default=None,
142 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. ',
143 )
144 factory_reset_timestamp: Optional[StrictInt] = Field(
145 default=None,
146 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. ',
147 )
148 frida: Optional[StrictBool] = Field(
149 default=None,
150 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. ',
151 )
152 ip_blocklist: Optional[IPBlockList] = None
153 ip_info: Optional[IPInfo] = None
154 proxy: Optional[StrictBool] = Field(
155 default=None,
156 description='IP address was used by a public proxy provider or belonged to a known recent residential proxy ',
157 )
158 proxy_confidence: Optional[ProxyConfidence] = None
159 proxy_details: Optional[ProxyDetails] = None
160 proxy_ml_score: Optional[
161 Union[
162 Annotated[float, Field(le=1, strict=True, ge=0)],
163 Annotated[int, Field(le=1, strict=True, ge=0)],
164 ]
165 ] = Field(
166 default=None,
167 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/). ',
168 )
169 incognito: Optional[StrictBool] = Field(
170 default=None,
171 description='`true` if we detected incognito mode used in the browser, `false` otherwise. ',
172 )
173 jailbroken: Optional[StrictBool] = Field(
174 default=None,
175 description='iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. ',
176 )
177 location_spoofing: Optional[StrictBool] = Field(
178 default=None,
179 description='Flag indicating whether the request came from a mobile device with location spoofing enabled.',
180 )
181 mitm_attack: Optional[StrictBool] = Field(
182 default=None,
183 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. ",
184 )
185 privacy_settings: Optional[StrictBool] = Field(
186 default=None,
187 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`. ',
188 )
189 root_apps: Optional[StrictBool] = Field(
190 default=None,
191 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. ",
192 )
193 rule_action: Optional[EventRuleAction] = None
194 simulator: Optional[StrictBool] = Field(
195 default=None,
196 description='iOS specific simulator detection. There are 2 values: * `true` - Simulator environment detected. * `false` - No signs of simulator or the client is not iOS. ',
197 )
198 suspect_score: Optional[StrictInt] = Field(
199 default=None,
200 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 ',
201 )
202 tampering: Optional[StrictBool] = Field(
203 default=None,
204 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 ',
205 )
206 tampering_confidence: Optional[TamperingConfidence] = None
207 tampering_ml_score: Optional[
208 Union[
209 Annotated[float, Field(le=1, strict=True, ge=0)],
210 Annotated[int, Field(le=1, strict=True, ge=0)],
211 ]
212 ] = Field(
213 default=None,
214 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) ',
215 )
216 tampering_details: Optional[TamperingDetails] = None
217 velocity: Optional[Velocity] = None
218 virtual_machine: Optional[StrictBool] = Field(
219 default=None,
220 description='`true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. ',
221 )
222 virtual_machine_ml_score: Optional[
223 Union[
224 Annotated[float, Field(le=1, strict=True, ge=0)],
225 Annotated[int, Field(le=1, strict=True, ge=0)],
226 ]
227 ] = Field(
228 default=None,
229 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/). ',
230 )
231 vpn: Optional[StrictBool] = Field(
232 default=None,
233 description='VPN or other anonymizing service has been used when sending the request. ',
234 )
235 vpn_confidence: Optional[VpnConfidence] = None
236 vpn_ml_score: Optional[
237 Union[
238 Annotated[float, Field(le=1, strict=True, ge=0)],
239 Annotated[int, Field(le=1, strict=True, ge=0)],
240 ]
241 ] = Field(
242 default=None,
243 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/). ',
244 )
245 vpn_origin_timezone: Optional[StrictStr] = Field(
246 default=None, description='Local timezone which is used in timezone_mismatch method. '
247 )
248 vpn_origin_country: Optional[StrictStr] = Field(
249 default=None,
250 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. ',
251 )
252 vpn_methods: Optional[VpnMethods] = None
253 high_activity_device: Optional[StrictBool] = Field(
254 default=None,
255 description='Flag indicating if the request came from a high-activity visitor.',
256 )
257 rare_device: Optional[StrictBool] = Field(
258 default=None,
259 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/). ',
260 )
261 rare_device_percentile_bucket: Optional[RareDevicePercentileBucket] = None
262 raw_device_attributes: Optional[RawDeviceAttributes] = None
263 labels: Optional[list[LabelsInner]] = Field(
264 default=None,
265 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/). ',
266 )
267 __properties: ClassVar[list[str]] = [
268 'event_id',
269 'timestamp',
270 'source',
271 'incremental_identification_status',
272 'linked_id',
273 'environment_id',
274 'suspect',
275 'sdk',
276 'replayed',
277 'identification',
278 'supplementary_id_high_recall',
279 'tags',
280 'url',
281 'bundle_id',
282 'package_name',
283 'ip_address',
284 'user_agent',
285 'device',
286 'os',
287 'os_version',
288 'client_referrer',
289 'browser_details',
290 'proximity',
291 'active_call',
292 'bot',
293 'bot_type',
294 'bot_info',
295 'cloned_app',
296 'compromised_device_integrity',
297 'developer_tools',
298 'device_details',
299 'emulator',
300 'factory_reset_timestamp',
301 'frida',
302 'ip_blocklist',
303 'ip_info',
304 'proxy',
305 'proxy_confidence',
306 'proxy_details',
307 'proxy_ml_score',
308 'incognito',
309 'jailbroken',
310 'location_spoofing',
311 'mitm_attack',
312 'privacy_settings',
313 'root_apps',
314 'rule_action',
315 'simulator',
316 'suspect_score',
317 'tampering',
318 'tampering_confidence',
319 'tampering_ml_score',
320 'tampering_details',
321 'velocity',
322 'virtual_machine',
323 'virtual_machine_ml_score',
324 'vpn',
325 'vpn_confidence',
326 'vpn_ml_score',
327 'vpn_origin_timezone',
328 'vpn_origin_country',
329 'vpn_methods',
330 'high_activity_device',
331 'rare_device',
332 'rare_device_percentile_bucket',
333 'raw_device_attributes',
334 'labels',
335 ]
337 model_config = ConfigDict(
338 populate_by_name=True,
339 validate_assignment=True,
340 protected_namespaces=(),
341 )
343 def to_str(self) -> str:
344 """Returns the string representation of the model using alias"""
345 return pprint.pformat(self.model_dump(by_alias=True))
347 def to_json(self) -> str:
348 """Returns the JSON representation of the model using alias"""
349 # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
350 return json.dumps(self.to_dict())
352 @classmethod
353 def from_json(cls, json_str: str) -> Optional[Self]:
354 """Create an instance of Event from a JSON string"""
355 return cls.from_dict(json.loads(json_str))
357 def to_dict(self) -> dict[str, Any]:
358 """Return the dictionary representation of the model using alias.
360 This has the following differences from calling pydantic's
361 `self.model_dump(by_alias=True)`:
363 * `None` is only added to the output dict for nullable fields that
364 were set at model initialization. Other fields with value `None`
365 are ignored.
366 """
367 excluded_fields: set[str] = set([])
369 _dict = self.model_dump(
370 by_alias=True,
371 exclude=excluded_fields,
372 exclude_none=True,
373 )
374 # override the default output from pydantic by calling `to_dict()` of sdk
375 if self.sdk:
376 _dict['sdk'] = self.sdk.to_dict()
377 # override the default output from pydantic by calling `to_dict()` of identification
378 if self.identification:
379 _dict['identification'] = self.identification.to_dict()
380 # override the default output from pydantic by calling `to_dict()` of supplementary_id_high_recall
381 if self.supplementary_id_high_recall:
382 _dict['supplementary_id_high_recall'] = self.supplementary_id_high_recall.to_dict()
383 # override the default output from pydantic by calling `to_dict()` of browser_details
384 if self.browser_details:
385 _dict['browser_details'] = self.browser_details.to_dict()
386 # override the default output from pydantic by calling `to_dict()` of proximity
387 if self.proximity:
388 _dict['proximity'] = self.proximity.to_dict()
389 # override the default output from pydantic by calling `to_dict()` of bot_info
390 if self.bot_info:
391 _dict['bot_info'] = self.bot_info.to_dict()
392 # override the default output from pydantic by calling `to_dict()` of device_details
393 if self.device_details:
394 _dict['device_details'] = self.device_details.to_dict()
395 # override the default output from pydantic by calling `to_dict()` of ip_blocklist
396 if self.ip_blocklist:
397 _dict['ip_blocklist'] = self.ip_blocklist.to_dict()
398 # override the default output from pydantic by calling `to_dict()` of ip_info
399 if self.ip_info:
400 _dict['ip_info'] = self.ip_info.to_dict()
401 # override the default output from pydantic by calling `to_dict()` of proxy_details
402 if self.proxy_details:
403 _dict['proxy_details'] = self.proxy_details.to_dict()
404 # override the default output from pydantic by calling `to_dict()` of rule_action
405 if self.rule_action:
406 _dict['rule_action'] = self.rule_action.to_dict()
407 # override the default output from pydantic by calling `to_dict()` of tampering_details
408 if self.tampering_details:
409 _dict['tampering_details'] = self.tampering_details.to_dict()
410 # override the default output from pydantic by calling `to_dict()` of velocity
411 if self.velocity:
412 _dict['velocity'] = self.velocity.to_dict()
413 # override the default output from pydantic by calling `to_dict()` of vpn_methods
414 if self.vpn_methods:
415 _dict['vpn_methods'] = self.vpn_methods.to_dict()
416 # override the default output from pydantic by calling `to_dict()` of raw_device_attributes
417 if self.raw_device_attributes:
418 _dict['raw_device_attributes'] = self.raw_device_attributes.to_dict()
419 # override the default output from pydantic by calling `to_dict()` of each item in labels (list)
420 _items = []
421 if self.labels:
422 for _item_labels in self.labels:
423 if _item_labels:
424 _items.append(_item_labels.to_dict())
425 _dict['labels'] = _items
426 return _dict
428 @classmethod
429 def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]:
430 """Create an instance of Event from a dict"""
431 if obj is None:
432 return None
434 if not isinstance(obj, dict):
435 return cls.model_validate(obj)
437 _obj = cls.model_validate(
438 {
439 'event_id': obj.get('event_id'),
440 'timestamp': obj.get('timestamp'),
441 'source': obj.get('source'),
442 'incremental_identification_status': obj.get('incremental_identification_status'),
443 'linked_id': obj.get('linked_id'),
444 'environment_id': obj.get('environment_id'),
445 'suspect': obj.get('suspect'),
446 'sdk': SDK.from_dict(obj['sdk']) if obj.get('sdk') is not None else None,
447 'replayed': obj.get('replayed'),
448 'identification': Identification.from_dict(obj['identification'])
449 if obj.get('identification') is not None
450 else None,
451 'supplementary_id_high_recall': SupplementaryIDHighRecall.from_dict(
452 obj['supplementary_id_high_recall']
453 )
454 if obj.get('supplementary_id_high_recall') is not None
455 else None,
456 'tags': obj.get('tags'),
457 'url': obj.get('url'),
458 'bundle_id': obj.get('bundle_id'),
459 'package_name': obj.get('package_name'),
460 'ip_address': obj.get('ip_address'),
461 'user_agent': obj.get('user_agent'),
462 'device': obj.get('device'),
463 'os': obj.get('os'),
464 'os_version': obj.get('os_version'),
465 'client_referrer': obj.get('client_referrer'),
466 'browser_details': BrowserDetails.from_dict(obj['browser_details'])
467 if obj.get('browser_details') is not None
468 else None,
469 'proximity': Proximity.from_dict(obj['proximity'])
470 if obj.get('proximity') is not None
471 else None,
472 'active_call': obj.get('active_call'),
473 'bot': obj.get('bot'),
474 'bot_type': obj.get('bot_type'),
475 'bot_info': BotInfo.from_dict(obj['bot_info'])
476 if obj.get('bot_info') is not None
477 else None,
478 'cloned_app': obj.get('cloned_app'),
479 'compromised_device_integrity': obj.get('compromised_device_integrity'),
480 'developer_tools': obj.get('developer_tools'),
481 'device_details': DeviceDetails.from_dict(obj['device_details'])
482 if obj.get('device_details') is not None
483 else None,
484 'emulator': obj.get('emulator'),
485 'factory_reset_timestamp': obj.get('factory_reset_timestamp'),
486 'frida': obj.get('frida'),
487 'ip_blocklist': IPBlockList.from_dict(obj['ip_blocklist'])
488 if obj.get('ip_blocklist') is not None
489 else None,
490 'ip_info': IPInfo.from_dict(obj['ip_info'])
491 if obj.get('ip_info') is not None
492 else None,
493 'proxy': obj.get('proxy'),
494 'proxy_confidence': obj.get('proxy_confidence'),
495 'proxy_details': ProxyDetails.from_dict(obj['proxy_details'])
496 if obj.get('proxy_details') is not None
497 else None,
498 'proxy_ml_score': obj.get('proxy_ml_score'),
499 'incognito': obj.get('incognito'),
500 'jailbroken': obj.get('jailbroken'),
501 'location_spoofing': obj.get('location_spoofing'),
502 'mitm_attack': obj.get('mitm_attack'),
503 'privacy_settings': obj.get('privacy_settings'),
504 'root_apps': obj.get('root_apps'),
505 'rule_action': EventRuleAction.from_dict(obj['rule_action'])
506 if obj.get('rule_action') is not None
507 else None,
508 'simulator': obj.get('simulator'),
509 'suspect_score': obj.get('suspect_score'),
510 'tampering': obj.get('tampering'),
511 'tampering_confidence': obj.get('tampering_confidence'),
512 'tampering_ml_score': obj.get('tampering_ml_score'),
513 'tampering_details': TamperingDetails.from_dict(obj['tampering_details'])
514 if obj.get('tampering_details') is not None
515 else None,
516 'velocity': Velocity.from_dict(obj['velocity'])
517 if obj.get('velocity') is not None
518 else None,
519 'virtual_machine': obj.get('virtual_machine'),
520 'virtual_machine_ml_score': obj.get('virtual_machine_ml_score'),
521 'vpn': obj.get('vpn'),
522 'vpn_confidence': obj.get('vpn_confidence'),
523 'vpn_ml_score': obj.get('vpn_ml_score'),
524 'vpn_origin_timezone': obj.get('vpn_origin_timezone'),
525 'vpn_origin_country': obj.get('vpn_origin_country'),
526 'vpn_methods': VpnMethods.from_dict(obj['vpn_methods'])
527 if obj.get('vpn_methods') is not None
528 else None,
529 'high_activity_device': obj.get('high_activity_device'),
530 'rare_device': obj.get('rare_device'),
531 'rare_device_percentile_bucket': obj.get('rare_device_percentile_bucket'),
532 'raw_device_attributes': RawDeviceAttributes.from_dict(
533 obj['raw_device_attributes']
534 )
535 if obj.get('raw_device_attributes') is not None
536 else None,
537 'labels': [LabelsInner.from_dict(_item) for _item in obj['labels']]
538 if obj.get('labels') is not None
539 else None,
540 }
541 )
542 return _obj