cdp-python-sdk 0.1.0__tar.gz → 0.1.1__tar.gz
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.
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/PKG-INFO +2 -2
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_client/client.py +8 -8
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_client/gateway_urls.py +4 -4
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_client/models.py +36 -35
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_python_sdk.egg-info/PKG-INFO +2 -2
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/pyproject.toml +16 -2
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/setup.py +2 -2
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/MANIFEST.in +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/README.md +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_client/__init__.py +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_client/errors.py +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_client/validators.py +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_python_sdk.egg-info/SOURCES.txt +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_python_sdk.egg-info/dependency_links.txt +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_python_sdk.egg-info/requires.txt +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/cdp_python_sdk.egg-info/top_level.txt +0 -0
- {cdp_python_sdk-0.1.0 → cdp_python_sdk-0.1.1}/setup.cfg +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cdp-python-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: A Python client library for Codematic's Customer Data Platform (CDP) with optional Customer.io integration.
|
|
5
5
|
Author-email: Codematic Engineering <engineering@codematic.io>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
8
|
Classifier: Operating System :: OS Independent
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
Requires-Dist: httpx>=0.24.0
|
|
12
12
|
Requires-Dist: pydantic>=2.0.0
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
6
6
|
|
|
7
7
|
import httpx
|
|
8
8
|
from customerio import CustomerIO
|
|
@@ -33,7 +33,7 @@ class CDPClient:
|
|
|
33
33
|
self._timeout = config.timeout_ms / 1000.0
|
|
34
34
|
logger.setLevel(logging.DEBUG if config.debug else logging.INFO)
|
|
35
35
|
|
|
36
|
-
self.cio:
|
|
36
|
+
self.cio: CustomerIO | None = None
|
|
37
37
|
if self.config.send_to_customer_io and self.config.customer_io:
|
|
38
38
|
try:
|
|
39
39
|
self.cio = CustomerIO(
|
|
@@ -49,7 +49,7 @@ class CDPClient:
|
|
|
49
49
|
return {
|
|
50
50
|
"Authorization": self.config.cdp_api_key,
|
|
51
51
|
"Content-Type": "application/json",
|
|
52
|
-
"User-Agent": "cdp-python-sdk/0.
|
|
52
|
+
"User-Agent": "cdp-python-sdk/0.1.1",
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
def _handle_error(self, message: str, exc: Exception) -> None:
|
|
@@ -65,9 +65,9 @@ class CDPClient:
|
|
|
65
65
|
method: str,
|
|
66
66
|
path: str,
|
|
67
67
|
*,
|
|
68
|
-
json_body:
|
|
68
|
+
json_body: dict | None = None,
|
|
69
69
|
) -> httpx.Response:
|
|
70
|
-
last_error:
|
|
70
|
+
last_error: Exception | None = None
|
|
71
71
|
async with httpx.AsyncClient(
|
|
72
72
|
timeout=self._timeout,
|
|
73
73
|
headers=self._headers(),
|
|
@@ -104,7 +104,7 @@ class CDPClient:
|
|
|
104
104
|
self._handle_error("Ping failed", e)
|
|
105
105
|
return False
|
|
106
106
|
|
|
107
|
-
async def identify(self, identifier: str, properties:
|
|
107
|
+
async def identify(self, identifier: str, properties: dict[str, Any] | None = None) -> None:
|
|
108
108
|
try:
|
|
109
109
|
validated_id = validate_identifier(identifier)
|
|
110
110
|
normalized_props = validate_properties(properties)
|
|
@@ -130,7 +130,7 @@ class CDPClient:
|
|
|
130
130
|
self,
|
|
131
131
|
identifier: str,
|
|
132
132
|
event_name: str,
|
|
133
|
-
properties:
|
|
133
|
+
properties: dict[str, Any] | None = None,
|
|
134
134
|
) -> None:
|
|
135
135
|
try:
|
|
136
136
|
validated_id = validate_identifier(identifier)
|
|
@@ -217,4 +217,4 @@ class CDPClient:
|
|
|
217
217
|
|
|
218
218
|
async def close(self) -> None:
|
|
219
219
|
"""No persistent client; kept for API compatibility."""
|
|
220
|
-
return
|
|
220
|
+
return
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
DEFAULT_PRIMARY = "https://api.opencdp.
|
|
5
|
+
DEFAULT_PRIMARY = "https://api.opencdp.io/gateway/data-gateway"
|
|
6
6
|
DEFAULT_FALLBACKS = [
|
|
7
|
-
"https://api.
|
|
8
|
-
"https://api.
|
|
7
|
+
"https://api.open-cdp.com/gateway/data-gateway",
|
|
8
|
+
"https://api.open-cdp.xyz/gateway/data-gateway",
|
|
9
9
|
]
|
|
10
10
|
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ def normalize_base_url(url: str) -> str:
|
|
|
13
13
|
trimmed = url.strip()
|
|
14
14
|
if not trimmed:
|
|
15
15
|
return trimmed
|
|
16
|
-
return trimmed
|
|
16
|
+
return trimmed.removesuffix("/")
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def resolve_all_base_urls(
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Optional, Dict, Any, Literal
|
|
4
|
-
from pydantic import BaseModel, Field, ConfigDict
|
|
5
3
|
import logging
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
7
|
|
|
7
8
|
from .gateway_urls import DEFAULT_PRIMARY
|
|
8
9
|
|
|
@@ -12,7 +13,7 @@ logger = logging.getLogger(__name__)
|
|
|
12
13
|
class CustomerIoConfig(BaseModel):
|
|
13
14
|
site_id: str = Field(..., description="Customer.io Site ID")
|
|
14
15
|
api_key: str = Field(..., description="Customer.io API Key")
|
|
15
|
-
region:
|
|
16
|
+
region: Literal["us", "eu"] | None = Field("us", description="Data center region")
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class CDPConfig(BaseModel):
|
|
@@ -21,7 +22,7 @@ class CDPConfig(BaseModel):
|
|
|
21
22
|
DEFAULT_PRIMARY,
|
|
22
23
|
description="Primary gateway base URL",
|
|
23
24
|
)
|
|
24
|
-
cdp_fallback_endpoints:
|
|
25
|
+
cdp_fallback_endpoints: list[str] | None = Field(
|
|
25
26
|
None,
|
|
26
27
|
description="Optional fallback gateway base URLs",
|
|
27
28
|
)
|
|
@@ -31,30 +32,30 @@ class CDPConfig(BaseModel):
|
|
|
31
32
|
description="When true, raise on validation and HTTP errors",
|
|
32
33
|
)
|
|
33
34
|
send_to_customer_io: bool = Field(False, description="Enable dual-write to Customer.io")
|
|
34
|
-
customer_io:
|
|
35
|
+
customer_io: CustomerIoConfig | None = Field(None, description="Customer.io configuration")
|
|
35
36
|
debug: bool = Field(False, description="Enable debug logging")
|
|
36
37
|
|
|
37
38
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
class Identifiers(BaseModel):
|
|
41
|
-
id:
|
|
42
|
-
email:
|
|
43
|
-
cdp_id:
|
|
42
|
+
id: str | None = None
|
|
43
|
+
email: str | None = None
|
|
44
|
+
cdp_id: str | None = None
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
class BaseMessagePayload(BaseModel):
|
|
47
48
|
identifiers: Identifiers
|
|
48
|
-
transactional_message_id:
|
|
49
|
-
message_data:
|
|
50
|
-
send_at:
|
|
51
|
-
send_to_unsubscribed:
|
|
52
|
-
tracked:
|
|
53
|
-
disable_css_preprocessing:
|
|
54
|
-
headers:
|
|
55
|
-
disable_message_retention:
|
|
56
|
-
queue_draft:
|
|
57
|
-
attachments:
|
|
49
|
+
transactional_message_id: str | None = None
|
|
50
|
+
message_data: dict[str, Any] | None = None
|
|
51
|
+
send_at: int | None = None
|
|
52
|
+
send_to_unsubscribed: bool | None = None
|
|
53
|
+
tracked: bool | None = None
|
|
54
|
+
disable_css_preprocessing: bool | None = None
|
|
55
|
+
headers: str | None = None
|
|
56
|
+
disable_message_retention: bool | None = None
|
|
57
|
+
queue_draft: bool | None = None
|
|
58
|
+
attachments: dict[str, Any] | None = None
|
|
58
59
|
|
|
59
60
|
def check_unsupported_fields(self):
|
|
60
61
|
unsupported = [
|
|
@@ -77,34 +78,34 @@ class BaseMessagePayload(BaseModel):
|
|
|
77
78
|
|
|
78
79
|
class EmailPayload(BaseMessagePayload):
|
|
79
80
|
to: str
|
|
80
|
-
from_:
|
|
81
|
-
subject:
|
|
82
|
-
body:
|
|
83
|
-
body_plain:
|
|
84
|
-
reply_to:
|
|
81
|
+
from_: str | None = Field(None, alias="from")
|
|
82
|
+
subject: str | None = None
|
|
83
|
+
body: str | None = None
|
|
84
|
+
body_plain: str | None = None
|
|
85
|
+
reply_to: str | None = None
|
|
85
86
|
|
|
86
87
|
|
|
87
88
|
class PushPayload(BaseMessagePayload):
|
|
88
|
-
title:
|
|
89
|
-
body:
|
|
89
|
+
title: str | None = None
|
|
90
|
+
body: str | None = None
|
|
90
91
|
|
|
91
92
|
|
|
92
93
|
class SmsPayload(BaseMessagePayload):
|
|
93
|
-
to:
|
|
94
|
-
from_:
|
|
95
|
-
body:
|
|
94
|
+
to: str | None = None
|
|
95
|
+
from_: str | None = Field(None, alias="from")
|
|
96
|
+
body: str | None = None
|
|
96
97
|
|
|
97
98
|
|
|
98
99
|
class DeviceRegistrationParameters(BaseModel):
|
|
99
100
|
device_id: str = Field(..., alias="deviceId")
|
|
100
101
|
platform: Literal["android", "ios", "web"]
|
|
101
102
|
fcm_token: str = Field(..., alias="fcmToken")
|
|
102
|
-
name:
|
|
103
|
-
os_version:
|
|
104
|
-
model:
|
|
105
|
-
apn_token:
|
|
106
|
-
app_version:
|
|
107
|
-
last_active_at:
|
|
108
|
-
attributes:
|
|
103
|
+
name: str | None = None
|
|
104
|
+
os_version: str | None = Field(None, alias="osVersion")
|
|
105
|
+
model: str | None = None
|
|
106
|
+
apn_token: str | None = Field(None, alias="apnToken")
|
|
107
|
+
app_version: str | None = Field(None, alias="appVersion")
|
|
108
|
+
last_active_at: str | None = None
|
|
109
|
+
attributes: dict[str, Any] | None = None
|
|
109
110
|
|
|
110
111
|
model_config = ConfigDict(populate_by_name=True)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cdp-python-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: A Python client library for Codematic's Customer Data Platform (CDP) with optional Customer.io integration.
|
|
5
5
|
Author-email: Codematic Engineering <engineering@codematic.io>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
8
|
Classifier: Operating System :: OS Independent
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
Requires-Dist: httpx>=0.24.0
|
|
12
12
|
Requires-Dist: pydantic>=2.0.0
|
|
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cdp-python-sdk"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.1"
|
|
8
8
|
description = "A Python client library for Codematic's Customer Data Platform (CDP) with optional Customer.io integration."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Codematic Engineering", email = "engineering@codematic.io" }]
|
|
11
11
|
license = "MIT"
|
|
12
|
-
requires-python = ">=3.
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
13
|
classifiers = [
|
|
14
14
|
"Programming Language :: Python :: 3",
|
|
15
15
|
"Operating System :: OS Independent",
|
|
@@ -34,3 +34,17 @@ exclude = ["tests*", "example*"]
|
|
|
34
34
|
[tool.pytest.ini_options]
|
|
35
35
|
asyncio_mode = "auto"
|
|
36
36
|
testpaths = ["tests"]
|
|
37
|
+
|
|
38
|
+
[tool.ruff]
|
|
39
|
+
target-version = "py310"
|
|
40
|
+
exclude = [
|
|
41
|
+
"example",
|
|
42
|
+
"main.py",
|
|
43
|
+
".venv",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
ignore = [
|
|
48
|
+
# SDK intentionally catches Exception then uses fail_on_exception / _handle_error
|
|
49
|
+
"BLE001",
|
|
50
|
+
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|