Coverage for fingerprint_server_sdk/models/raw_device_attributes.py: 70%

88 statements  

« prev     ^ index     » next       coverage.py v7.14.3, created at 2026-09-25 15:12 +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. 

6 

7The version of the OpenAPI document: 4 

8Contact: support@fingerprint.com 

9Generated by OpenAPI Generator (https://openapi-generator.tech) 

10 

11Do not edit the class manually. 

12""" # noqa: E501 

13 

14from __future__ import annotations 

15 

16import json 

17import pprint 

18import re # noqa: F401 

19from typing import Annotated, Any, ClassVar, Optional, Union 

20 

21from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr 

22from typing_extensions import Self 

23 

24from fingerprint_server_sdk.models.canvas import Canvas 

25from fingerprint_server_sdk.models.emoji import Emoji 

26from fingerprint_server_sdk.models.font_preferences import FontPreferences 

27from fingerprint_server_sdk.models.plugins_inner import PluginsInner 

28from fingerprint_server_sdk.models.touch_support import TouchSupport 

29from fingerprint_server_sdk.models.web_gl_basics import WebGlBasics 

30from fingerprint_server_sdk.models.web_gl_extensions import WebGlExtensions 

31 

32 

33class RawDeviceAttributes(BaseModel): 

34 """ 

35 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. 

36 """ 

37 

38 font_preferences: Optional[FontPreferences] = None 

39 emoji: Optional[Emoji] = None 

40 fonts: Optional[list[StrictStr]] = Field( 

41 default=None, description='List of fonts detected on the device.' 

42 ) 

43 device_memory: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field( 

44 default=None, 

45 description='Rounded amount of RAM in gigabytes. Available for browsers, Android, and iOS devices.', 

46 ) 

47 timezone: Optional[StrictStr] = Field( 

48 default=None, description='Timezone identifier detected on the client.' 

49 ) 

50 canvas: Optional[Canvas] = None 

51 languages: Optional[list[list[StrictStr]]] = Field( 

52 default=None, 

53 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. ', 

54 ) 

55 webgl_extensions: Optional[WebGlExtensions] = None 

56 webgl_basics: Optional[WebGlBasics] = None 

57 screen_resolution: Optional[Annotated[list[StrictInt], Field(min_length=2, max_length=2)]] = ( 

58 Field( 

59 default=None, 

60 description='Current screen resolution. Available for both browsers and iOS devices', 

61 ) 

62 ) 

63 touch_support: Optional[TouchSupport] = None 

64 oscpu: Optional[StrictStr] = Field(default=None, description='Navigator `oscpu` string.') 

65 architecture: Optional[StrictInt] = Field( 

66 default=None, 

67 description='Integer representing the CPU architecture exposed by the browser.', 

68 ) 

69 cookies_enabled: Optional[StrictBool] = Field( 

70 default=None, description='Whether the cookies are enabled in the browser.' 

71 ) 

72 hardware_concurrency: Optional[StrictInt] = Field( 

73 default=None, description='Number of logical CPU cores reported by the browser.' 

74 ) 

75 date_time_locale: Optional[StrictStr] = Field( 

76 default=None, 

77 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. ', 

78 ) 

79 vendor: Optional[StrictStr] = Field(default=None, description='Navigator vendor string.') 

80 color_depth: Optional[StrictInt] = Field( 

81 default=None, description='Screen color depth in bits.' 

82 ) 

83 platform: Optional[StrictStr] = Field(default=None, description='Navigator platform string.') 

84 session_storage: Optional[StrictBool] = Field( 

85 default=None, description='Whether sessionStorage is available.' 

86 ) 

87 local_storage: Optional[StrictBool] = Field( 

88 default=None, description='Whether localStorage is available.' 

89 ) 

90 audio: Optional[Union[StrictFloat, StrictInt]] = Field( 

91 default=None, 

92 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 ", 

93 ) 

94 plugins: Optional[list[PluginsInner]] = Field( 

95 default=None, description='Browser plugins reported by `navigator.plugins`.' 

96 ) 

97 indexed_db: Optional[StrictBool] = Field( 

98 default=None, description='Whether IndexedDB is available.' 

99 ) 

100 math: Optional[StrictStr] = Field( 

101 default=None, description='Hash of Math APIs used for entropy collection.' 

102 ) 

103 device_model: Optional[StrictStr] = Field( 

104 default=None, 

105 description='Device model string. Available only for Android and iOS devices.', 

106 ) 

107 device_manufacturer: Optional[StrictStr] = Field( 

108 default=None, 

109 description='Device manufacturer string. Available only for Android and iOS devices.', 

110 ) 

111 font_hash: Optional[StrictStr] = Field( 

112 default=None, description='Unique identifier for the user’s installed fonts.' 

113 ) 

114 timezone_offset: Optional[StrictStr] = Field( 

115 default=None, 

116 description='UTC offset in "±HH:MM" format derived from the detected IANA timezone.', 

117 ) 

118 battery_level: Optional[Annotated[int, Field(le=100, strict=True, ge=0)]] = Field( 

119 default=None, 

120 description='Battery charge level as a percentage (0-100). Available for Android, iOS, and web devices. On web, only available in Chromium-based browsers.', 

121 ) 

122 battery_charging: Optional[StrictBool] = Field( 

123 default=None, 

124 description='When `true`, the device is currently charging. Available only for web devices on Chromium-based browsers.', 

125 ) 

126 battery_low_power_mode: Optional[StrictBool] = Field( 

127 default=None, 

128 description="Whether the device's low power mode is enabled. Available only for Android and iOS devices.", 

129 ) 

130 keyboard_layout_hash: Optional[StrictStr] = Field( 

131 default=None, description="Unique identifier for the user's keyboard layout." 

132 ) 

133 keyboard_layout_name: Optional[StrictStr] = Field( 

134 default=None, 

135 description="Name of the user's configured keyboard layout as a BCP 47-style identifier. Only available in Chromium-based browsers, omitted otherwise.", 

136 ) 

137 __properties: ClassVar[list[str]] = [ 

138 'font_preferences', 

139 'emoji', 

140 'fonts', 

141 'device_memory', 

142 'timezone', 

143 'canvas', 

144 'languages', 

145 'webgl_extensions', 

146 'webgl_basics', 

147 'screen_resolution', 

148 'touch_support', 

149 'oscpu', 

150 'architecture', 

151 'cookies_enabled', 

152 'hardware_concurrency', 

153 'date_time_locale', 

154 'vendor', 

155 'color_depth', 

156 'platform', 

157 'session_storage', 

158 'local_storage', 

159 'audio', 

160 'plugins', 

161 'indexed_db', 

162 'math', 

163 'device_model', 

164 'device_manufacturer', 

165 'font_hash', 

166 'timezone_offset', 

167 'battery_level', 

168 'battery_charging', 

169 'battery_low_power_mode', 

170 'keyboard_layout_hash', 

171 'keyboard_layout_name', 

172 ] 

173 

174 model_config = ConfigDict( 

175 populate_by_name=True, 

176 validate_assignment=True, 

177 protected_namespaces=(), 

178 ) 

179 

180 def to_str(self) -> str: 

181 """Returns the string representation of the model using alias""" 

182 return pprint.pformat(self.model_dump(by_alias=True)) 

183 

184 def to_json(self) -> str: 

185 """Returns the JSON representation of the model using alias""" 

186 # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead 

187 return json.dumps(self.to_dict()) 

188 

189 @classmethod 

190 def from_json(cls, json_str: str) -> Optional[Self]: 

191 """Create an instance of RawDeviceAttributes from a JSON string""" 

192 return cls.from_dict(json.loads(json_str)) 

193 

194 def to_dict(self) -> dict[str, Any]: 

195 """Return the dictionary representation of the model using alias. 

196 

197 This has the following differences from calling pydantic's 

198 `self.model_dump(by_alias=True)`: 

199 

200 * `None` is only added to the output dict for nullable fields that 

201 were set at model initialization. Other fields with value `None` 

202 are ignored. 

203 """ 

204 excluded_fields: set[str] = set([]) 

205 

206 _dict = self.model_dump( 

207 by_alias=True, 

208 exclude=excluded_fields, 

209 exclude_none=True, 

210 ) 

211 # override the default output from pydantic by calling `to_dict()` of font_preferences 

212 if self.font_preferences: 

213 _dict['font_preferences'] = self.font_preferences.to_dict() 

214 # override the default output from pydantic by calling `to_dict()` of emoji 

215 if self.emoji: 

216 _dict['emoji'] = self.emoji.to_dict() 

217 # override the default output from pydantic by calling `to_dict()` of canvas 

218 if self.canvas: 

219 _dict['canvas'] = self.canvas.to_dict() 

220 # override the default output from pydantic by calling `to_dict()` of webgl_extensions 

221 if self.webgl_extensions: 

222 _dict['webgl_extensions'] = self.webgl_extensions.to_dict() 

223 # override the default output from pydantic by calling `to_dict()` of webgl_basics 

224 if self.webgl_basics: 

225 _dict['webgl_basics'] = self.webgl_basics.to_dict() 

226 # override the default output from pydantic by calling `to_dict()` of touch_support 

227 if self.touch_support: 

228 _dict['touch_support'] = self.touch_support.to_dict() 

229 # override the default output from pydantic by calling `to_dict()` of each item in plugins (list) 

230 _items = [] 

231 if self.plugins: 

232 for _item_plugins in self.plugins: 

233 if _item_plugins: 

234 _items.append(_item_plugins.to_dict()) 

235 _dict['plugins'] = _items 

236 return _dict 

237 

238 @classmethod 

239 def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]: 

240 """Create an instance of RawDeviceAttributes from a dict""" 

241 if obj is None: 

242 return None 

243 

244 if not isinstance(obj, dict): 

245 return cls.model_validate(obj) 

246 

247 _obj = cls.model_validate( 

248 { 

249 'font_preferences': FontPreferences.from_dict(obj['font_preferences']) 

250 if obj.get('font_preferences') is not None 

251 else None, 

252 'emoji': Emoji.from_dict(obj['emoji']) if obj.get('emoji') is not None else None, 

253 'fonts': obj.get('fonts'), 

254 'device_memory': obj.get('device_memory'), 

255 'timezone': obj.get('timezone'), 

256 'canvas': Canvas.from_dict(obj['canvas']) 

257 if obj.get('canvas') is not None 

258 else None, 

259 'languages': obj.get('languages'), 

260 'webgl_extensions': WebGlExtensions.from_dict(obj['webgl_extensions']) 

261 if obj.get('webgl_extensions') is not None 

262 else None, 

263 'webgl_basics': WebGlBasics.from_dict(obj['webgl_basics']) 

264 if obj.get('webgl_basics') is not None 

265 else None, 

266 'screen_resolution': obj.get('screen_resolution'), 

267 'touch_support': TouchSupport.from_dict(obj['touch_support']) 

268 if obj.get('touch_support') is not None 

269 else None, 

270 'oscpu': obj.get('oscpu'), 

271 'architecture': obj.get('architecture'), 

272 'cookies_enabled': obj.get('cookies_enabled'), 

273 'hardware_concurrency': obj.get('hardware_concurrency'), 

274 'date_time_locale': obj.get('date_time_locale'), 

275 'vendor': obj.get('vendor'), 

276 'color_depth': obj.get('color_depth'), 

277 'platform': obj.get('platform'), 

278 'session_storage': obj.get('session_storage'), 

279 'local_storage': obj.get('local_storage'), 

280 'audio': obj.get('audio'), 

281 'plugins': [PluginsInner.from_dict(_item) for _item in obj['plugins']] 

282 if obj.get('plugins') is not None 

283 else None, 

284 'indexed_db': obj.get('indexed_db'), 

285 'math': obj.get('math'), 

286 'device_model': obj.get('device_model'), 

287 'device_manufacturer': obj.get('device_manufacturer'), 

288 'font_hash': obj.get('font_hash'), 

289 'timezone_offset': obj.get('timezone_offset'), 

290 'battery_level': obj.get('battery_level'), 

291 'battery_charging': obj.get('battery_charging'), 

292 'battery_low_power_mode': obj.get('battery_low_power_mode'), 

293 'keyboard_layout_hash': obj.get('keyboard_layout_hash'), 

294 'keyboard_layout_name': obj.get('keyboard_layout_name'), 

295 } 

296 ) 

297 return _obj