Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/add-event-source-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fingerprint/python-sdk': minor
---

Add `source` field to `Event` to identify how the event was generated (`device` or `edge`)
2 changes: 2 additions & 0 deletions .openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ docs/EventRuleAction.md
docs/EventRuleActionAllow.md
docs/EventRuleActionBlock.md
docs/EventSearch.md
docs/EventSource.md
docs/EventUpdate.md
docs/FingerprintApi.md
docs/FontPreferences.md
Expand Down Expand Up @@ -87,6 +88,7 @@ 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
fingerprint_server_sdk/models/event_search.py
fingerprint_server_sdk/models/event_source.py
fingerprint_server_sdk/models/event_update.py
fingerprint_server_sdk/models/font_preferences.py
fingerprint_server_sdk/models/geolocation.py
Expand Down
2 changes: 1 addition & 1 deletion .schema-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v3.5.1
v3.6.0
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ Class | Method | HTTP request | Description
- [EventRuleActionAllow](docs/EventRuleActionAllow.md)
- [EventRuleActionBlock](docs/EventRuleActionBlock.md)
- [EventSearch](docs/EventSearch.md)
- [EventSource](docs/EventSource.md)
- [EventUpdate](docs/EventUpdate.md)
- [FontPreferences](docs/FontPreferences.md)
- [Geolocation](docs/Geolocation.md)
Expand Down
1 change: 1 addition & 0 deletions README.pypi.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ Class | Method | HTTP request | Description
- [EventRuleActionAllow](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventRuleActionAllow.md)
- [EventRuleActionBlock](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventRuleActionBlock.md)
- [EventSearch](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventSearch.md)
- [EventSource](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventSource.md)
- [EventUpdate](https://github.com/fingerprintjs/python-sdk/blob/main/docs/EventUpdate.md)
- [FontPreferences](https://github.com/fingerprintjs/python-sdk/blob/main/docs/FontPreferences.md)
- [Geolocation](https://github.com/fingerprintjs/python-sdk/blob/main/docs/Geolocation.md)
Expand Down
1 change: 1 addition & 0 deletions docs/Event.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ 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]
**environment_id** | **str** | Environment Id of the event. | [optional]
Expand Down
13 changes: 13 additions & 0 deletions docs/EventSource.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# EventSource
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` (value: `'device'`)
* `EDGE` (value: `'edge'`)

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

2 changes: 2 additions & 0 deletions fingerprint_server_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
'EventRuleActionAllow',
'EventRuleActionBlock',
'EventSearch',
'EventSource',
'EventUpdate',
'FontPreferences',
'Geolocation',
Expand Down Expand Up @@ -145,6 +146,7 @@
from fingerprint_server_sdk.models.event_rule_action_allow import EventRuleActionAllow
from fingerprint_server_sdk.models.event_rule_action_block import EventRuleActionBlock
from fingerprint_server_sdk.models.event_search import EventSearch
from fingerprint_server_sdk.models.event_source import EventSource
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
Expand Down
1 change: 1 addition & 0 deletions fingerprint_server_sdk/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from fingerprint_server_sdk.models.event_rule_action_allow import EventRuleActionAllow
from fingerprint_server_sdk.models.event_rule_action_block import EventRuleActionBlock
from fingerprint_server_sdk.models.event_search import EventSearch
from fingerprint_server_sdk.models.event_source import EventSource
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
Expand Down
4 changes: 4 additions & 0 deletions fingerprint_server_sdk/models/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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,
Expand Down Expand Up @@ -57,6 +58,7 @@ class Event(BaseModel):
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.'
Expand Down Expand Up @@ -259,6 +261,7 @@ class Event(BaseModel):
__properties: ClassVar[list[str]] = [
'event_id',
'timestamp',
'source',
'incremental_identification_status',
'linked_id',
'environment_id',
Expand Down Expand Up @@ -424,6 +427,7 @@ def from_dict(cls, obj: Optional[dict[str, Any]]) -> Optional[Self]:
{
'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'),
Expand Down
48 changes: 48 additions & 0 deletions fingerprint_server_sdk/models/event_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
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
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.
"""

"""
allowed enum values
"""
DEVICE = 'device'
EDGE = 'edge'

@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of EventSource from a JSON string"""
return cls(json.loads(json_str))

@classmethod
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__}')
obj = str.__new__(cls, value)
obj._name_ = str(value)
obj._value_ = value
# cache it so the same value won't trigger `_missing_` again
cls._value2member_map_[value] = obj
return obj
19 changes: 19 additions & 0 deletions res/fingerprint-server-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,19 @@ 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:
Expand Down Expand Up @@ -3070,6 +3083,12 @@ components:
- android
- ios
- browser
source:
$ref: '#/components/schemas/EventSource'
x-platforms:
- android
- ios
- browser
incremental_identification_status:
$ref: '#/components/schemas/IncrementalIdentificationStatus'
x-platforms:
Expand Down
1 change: 1 addition & 0 deletions test/mocks/events/get_event_200.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"tags": {},
"timestamp": 1708102555327,
"event_id": "1708102555327.NLOjmg",
"source": "device",
"incremental_identification_status": "completed",
"url": "https://www.example.com/login?hope{this{works[!",
"ip_address": "61.127.217.15",
Expand Down
1 change: 1 addition & 0 deletions test/mocks/events/get_event_200_with_unknown_field.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"tags": {},
"timestamp": 1708102555327,
"event_id": "1708102555327.NLOjmg",
"source": "device",
"incremental_identification_status": "completed",
"url": "https://www.example.com/login?hope{this{works[!",
"ip_address": "61.127.217.15",
Expand Down
1 change: 1 addition & 0 deletions test/mocks/events/get_event_ruleset_200.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"tags": {},
"timestamp": 1708102555327,
"event_id": "1708102555327.NLOjmg",
"source": "device",
"incremental_identification_status": "completed",
"url": "https://www.example.com/login?hope{this{works[!",
"ip_address": "61.127.217.15",
Expand Down
1 change: 1 addition & 0 deletions test/mocks/events/get_event_with_bot_info_200.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"tags": {},
"timestamp": 1708102555327,
"event_id": "1708102555327.NLOjmg",
"source": "device",
"incremental_identification_status": "completed",
"url": "https://www.example.com/login?hope{this{works[!",
"ip_address": "61.127.217.15",
Expand Down
1 change: 1 addition & 0 deletions test/mocks/events/search/get_event_search_200.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"tags": {},
"timestamp": 1708102555327,
"event_id": "1708102555327.NLOjmg",
"source": "device",
"incremental_identification_status": "completed",
"url": "https://www.example.com/login?hope{this{works[!",
"ip_address": "61.127.217.15",
Expand Down
31 changes: 31 additions & 0 deletions test/test_unknown_enum_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from fingerprint_server_sdk import Event
from fingerprint_server_sdk.models.bot_info import BotInfo
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

Expand Down Expand Up @@ -82,6 +83,24 @@ def test_event_with_unknown_rare_device_percentile_bucket(self) -> None:
self.assertIsInstance(event, Event)
self.assertEqual(event.rare_device_percentile_bucket, 'unknown-value')

def test_event_with_unknown_source(self) -> None:
"""Unknown source value should be accepted and preserved."""
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')

def test_event_without_source(self) -> None:
"""Event should deserialize when the optional source field is absent."""
data = self._load_event_json()
data.pop('source', None)

event = Event.from_json(json.dumps(data))
self.assertIsInstance(event, Event)
self.assertIsNone(event.source)

def test_proxy_details_with_unknown_proxy_type(self) -> None:
"""ProxyDetails model should accept unknown proxy_type directly."""
details = ProxyDetails.from_dict({'proxy_type': 'unknown-value', 'last_seen_at': 123})
Expand Down Expand Up @@ -120,6 +139,7 @@ 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)
Expand All @@ -130,6 +150,7 @@ def test_event_with_multiple_unknown_enum_values(self) -> None:
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')

def test_known_enum_values_still_work(self) -> None:
"""Known enum values should continue to work as before."""
Expand All @@ -139,6 +160,16 @@ def test_known_enum_values_still_work(self) -> None:
self.assertIsInstance(event, Event)
self.assertEqual(event.proxy_details.proxy_type, 'residential')
self.assertEqual(event.sdk.platform, 'js')
self.assertEqual(event.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)


if __name__ == '__main__':
Expand Down