airbyte-agent-stripe 0.5.32__py3-none-any.whl → 0.5.37__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airbyte_agent_stripe/__init__.py +108 -88
- airbyte_agent_stripe/_vendored/connector_sdk/constants.py +1 -1
- airbyte_agent_stripe/_vendored/connector_sdk/executor/local_executor.py +3 -3
- airbyte_agent_stripe/_vendored/connector_sdk/extensions.py +3 -3
- airbyte_agent_stripe/_vendored/connector_sdk/introspection.py +1 -1
- airbyte_agent_stripe/_vendored/connector_sdk/observability/config.py +179 -0
- airbyte_agent_stripe/_vendored/connector_sdk/observability/session.py +35 -28
- airbyte_agent_stripe/_vendored/connector_sdk/schema/operations.py +1 -1
- airbyte_agent_stripe/_vendored/connector_sdk/telemetry/events.py +2 -1
- airbyte_agent_stripe/_vendored/connector_sdk/telemetry/tracker.py +3 -0
- airbyte_agent_stripe/_vendored/connector_sdk/types.py +1 -1
- airbyte_agent_stripe/connector.py +291 -58
- airbyte_agent_stripe/connector_model.py +3444 -692
- airbyte_agent_stripe/models.py +880 -720
- airbyte_agent_stripe/types.py +41 -13
- {airbyte_agent_stripe-0.5.32.dist-info → airbyte_agent_stripe-0.5.37.dist-info}/METADATA +12 -16
- {airbyte_agent_stripe-0.5.32.dist-info → airbyte_agent_stripe-0.5.37.dist-info}/RECORD +18 -17
- {airbyte_agent_stripe-0.5.32.dist-info → airbyte_agent_stripe-0.5.37.dist-info}/WHEEL +0 -0
|
@@ -3,46 +3,40 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
import uuid
|
|
5
5
|
from datetime import UTC, datetime
|
|
6
|
-
from pathlib import Path
|
|
7
6
|
from typing import Any, Dict, Optional
|
|
8
7
|
|
|
8
|
+
from .config import SDKConfig, load_config
|
|
9
|
+
|
|
9
10
|
logger = logging.getLogger(__name__)
|
|
10
11
|
|
|
12
|
+
# Cache the config at module level to avoid repeated reads
|
|
13
|
+
_cached_config: Optional[SDKConfig] = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _get_config() -> SDKConfig:
|
|
17
|
+
"""Get cached SDK config or load from file."""
|
|
18
|
+
global _cached_config
|
|
19
|
+
if _cached_config is None:
|
|
20
|
+
_cached_config = load_config()
|
|
21
|
+
return _cached_config
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _clear_config_cache() -> None:
|
|
25
|
+
"""Clear the cached config. Used for testing."""
|
|
26
|
+
global _cached_config
|
|
27
|
+
_cached_config = None
|
|
28
|
+
|
|
11
29
|
|
|
12
30
|
def get_persistent_user_id() -> str:
|
|
13
31
|
"""
|
|
14
|
-
Get
|
|
32
|
+
Get the persistent anonymous user ID.
|
|
15
33
|
|
|
16
|
-
|
|
17
|
-
If the file doesn't exist, a new UUID is generated and saved.
|
|
34
|
+
Now reads from ~/.airbyte/connector-sdk/config.yaml
|
|
18
35
|
|
|
19
36
|
Returns:
|
|
20
37
|
An anonymous UUID string that uniquely identifies this user across sessions.
|
|
21
38
|
"""
|
|
22
|
-
|
|
23
|
-
# Create .airbyte directory in home folder if it doesn't exist
|
|
24
|
-
airbyte_dir = Path.home() / ".airbyte"
|
|
25
|
-
airbyte_dir.mkdir(exist_ok=True)
|
|
26
|
-
|
|
27
|
-
# Path to user ID file
|
|
28
|
-
user_id_file = airbyte_dir / "ai_sdk_user_id"
|
|
29
|
-
|
|
30
|
-
# Try to read existing user ID
|
|
31
|
-
if user_id_file.exists():
|
|
32
|
-
user_id = user_id_file.read_text().strip()
|
|
33
|
-
if user_id: # Validate it's not empty
|
|
34
|
-
return user_id
|
|
35
|
-
|
|
36
|
-
# Generate new user ID if file doesn't exist or is empty
|
|
37
|
-
user_id = str(uuid.uuid4())
|
|
38
|
-
user_id_file.write_text(user_id)
|
|
39
|
-
logger.debug(f"Generated new anonymous user ID: {user_id}")
|
|
40
|
-
|
|
41
|
-
return user_id
|
|
42
|
-
except Exception as e:
|
|
43
|
-
# If we can't read/write the file, generate a session-only ID
|
|
44
|
-
logger.debug(f"Could not access anonymous user ID file: {e}")
|
|
45
|
-
return str(uuid.uuid4())
|
|
39
|
+
return _get_config().user_id
|
|
46
40
|
|
|
47
41
|
|
|
48
42
|
def get_public_ip() -> Optional[str]:
|
|
@@ -65,6 +59,18 @@ def get_public_ip() -> Optional[str]:
|
|
|
65
59
|
return None
|
|
66
60
|
|
|
67
61
|
|
|
62
|
+
def get_is_internal_user() -> bool:
|
|
63
|
+
"""
|
|
64
|
+
Check if the current user is an internal Airbyte user.
|
|
65
|
+
|
|
66
|
+
Now reads from ~/.airbyte/connector-sdk/config.yaml
|
|
67
|
+
Environment variable AIRBYTE_INTERNAL_USER can override.
|
|
68
|
+
|
|
69
|
+
Returns False if not set or on any error.
|
|
70
|
+
"""
|
|
71
|
+
return _get_config().is_internal_user
|
|
72
|
+
|
|
73
|
+
|
|
68
74
|
class ObservabilitySession:
|
|
69
75
|
"""Shared session context for both logging and telemetry."""
|
|
70
76
|
|
|
@@ -84,6 +90,7 @@ class ObservabilitySession:
|
|
|
84
90
|
self.operation_count = 0
|
|
85
91
|
self.metadata: Dict[str, Any] = {}
|
|
86
92
|
self.public_ip = get_public_ip()
|
|
93
|
+
self.is_internal_user = get_is_internal_user()
|
|
87
94
|
|
|
88
95
|
def increment_operations(self):
|
|
89
96
|
"""Increment the operation counter."""
|
|
@@ -61,7 +61,7 @@ class Operation(BaseModel):
|
|
|
61
61
|
description=(
|
|
62
62
|
"JSONPath expression to extract records from API response envelopes. "
|
|
63
63
|
"When specified, executor extracts data at this path instead of returning "
|
|
64
|
-
"full response. Returns array for list/
|
|
64
|
+
"full response. Returns array for list/api_search actions, single record for "
|
|
65
65
|
"get/create/update/delete actions."
|
|
66
66
|
),
|
|
67
67
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Telemetry event models."""
|
|
2
2
|
|
|
3
|
-
from dataclasses import asdict, dataclass
|
|
3
|
+
from dataclasses import asdict, dataclass, field
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from typing import Any, Dict, Optional
|
|
6
6
|
|
|
@@ -13,6 +13,7 @@ class BaseEvent:
|
|
|
13
13
|
session_id: str
|
|
14
14
|
user_id: str
|
|
15
15
|
execution_context: str
|
|
16
|
+
is_internal_user: bool = field(default=False, kw_only=True)
|
|
16
17
|
|
|
17
18
|
def to_dict(self) -> Dict[str, Any]:
|
|
18
19
|
"""Convert event to dictionary with ISO formatted timestamp."""
|
|
@@ -59,6 +59,7 @@ class SegmentTracker:
|
|
|
59
59
|
session_id=self.session.session_id,
|
|
60
60
|
user_id=self.session.user_id,
|
|
61
61
|
execution_context=self.session.execution_context,
|
|
62
|
+
is_internal_user=self.session.is_internal_user,
|
|
62
63
|
public_ip=self.session.public_ip,
|
|
63
64
|
connector_name=self.session.connector_name,
|
|
64
65
|
connector_version=connector_version,
|
|
@@ -101,6 +102,7 @@ class SegmentTracker:
|
|
|
101
102
|
session_id=self.session.session_id,
|
|
102
103
|
user_id=self.session.user_id,
|
|
103
104
|
execution_context=self.session.execution_context,
|
|
105
|
+
is_internal_user=self.session.is_internal_user,
|
|
104
106
|
public_ip=self.session.public_ip,
|
|
105
107
|
connector_name=self.session.connector_name,
|
|
106
108
|
entity=entity,
|
|
@@ -130,6 +132,7 @@ class SegmentTracker:
|
|
|
130
132
|
session_id=self.session.session_id,
|
|
131
133
|
user_id=self.session.user_id,
|
|
132
134
|
execution_context=self.session.execution_context,
|
|
135
|
+
is_internal_user=self.session.is_internal_user,
|
|
133
136
|
public_ip=self.session.public_ip,
|
|
134
137
|
connector_name=self.session.connector_name,
|
|
135
138
|
duration_seconds=self.session.duration_seconds(),
|