cdp-python-sdk 0.1.0__py3-none-any.whl → 0.1.1__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.
cdp_client/client.py CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import logging
5
- from typing import Any, Dict, Optional
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: Optional[CustomerIO] = None
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.2.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: Optional[dict] = None,
68
+ json_body: dict | None = None,
69
69
  ) -> httpx.Response:
70
- last_error: Optional[Exception] = None
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: Optional[Dict[str, Any]] = None) -> None:
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: Optional[Dict[str, Any]] = None,
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 None
220
+ return
@@ -2,10 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- DEFAULT_PRIMARY = "https://api.opencdp.com/gateway/data-gateway"
5
+ DEFAULT_PRIMARY = "https://api.opencdp.io/gateway/data-gateway"
6
6
  DEFAULT_FALLBACKS = [
7
- "https://api.opencdp.xyz/gateway/data-gateway",
8
- "https://api.opencdp.io/gateway/data-gateway",
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[:-1] if trimmed.endswith("/") else trimmed
16
+ return trimmed.removesuffix("/")
17
17
 
18
18
 
19
19
  def resolve_all_base_urls(
cdp_client/models.py CHANGED
@@ -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: Optional[Literal["us", "eu"]] = Field("us", description="Data center 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: Optional[list[str]] = Field(
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: Optional[CustomerIoConfig] = Field(None, description="Customer.io configuration")
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: Optional[str] = None
42
- email: Optional[str] = None
43
- cdp_id: Optional[str] = None
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: Optional[str] = None
49
- message_data: Optional[Dict[str, Any]] = None
50
- send_at: Optional[int] = None
51
- send_to_unsubscribed: Optional[bool] = None
52
- tracked: Optional[bool] = None
53
- disable_css_preprocessing: Optional[bool] = None
54
- headers: Optional[str] = None
55
- disable_message_retention: Optional[bool] = None
56
- queue_draft: Optional[bool] = None
57
- attachments: Optional[Dict[str, Any]] = None
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_: Optional[str] = Field(None, alias="from")
81
- subject: Optional[str] = None
82
- body: Optional[str] = None
83
- body_plain: Optional[str] = None
84
- reply_to: Optional[str] = None
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: Optional[str] = None
89
- body: Optional[str] = None
89
+ title: str | None = None
90
+ body: str | None = None
90
91
 
91
92
 
92
93
  class SmsPayload(BaseMessagePayload):
93
- to: Optional[str] = None
94
- from_: Optional[str] = Field(None, alias="from")
95
- body: Optional[str] = None
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: Optional[str] = None
103
- os_version: Optional[str] = Field(None, alias="osVersion")
104
- model: Optional[str] = None
105
- apn_token: Optional[str] = Field(None, alias="apnToken")
106
- app_version: Optional[str] = Field(None, alias="appVersion")
107
- last_active_at: Optional[str] = None
108
- attributes: Optional[Dict[str, Any]] = None
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.0
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.8
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
@@ -0,0 +1,10 @@
1
+ cdp_client/__init__.py,sha256=e5RV_Us_IdqebbQjPynufcM5i41oba0EomvUwJpLxOE,433
2
+ cdp_client/client.py,sha256=dOipKQrFrpx1bXs-67O9UGS4IRFtsMZtIGHr7vkqsOc,8239
3
+ cdp_client/errors.py,sha256=a_TmPv2gxKDy3BlgYhgSmQBSvrcTNbXWVMYH6DNLWqg,395
4
+ cdp_client/gateway_urls.py,sha256=IBybDsgL3HWKiL4OxhYLe0vNspcNFK8Oj2zuAY8PoCc,1161
5
+ cdp_client/models.py,sha256=gbK-QnpQKD4mx8mapsDm-INUrSle5EEIBOHfxe4LnS8,3576
6
+ cdp_client/validators.py,sha256=MDjTrEqj-ALkuuDgMZcUZ9mKeueKny2SEgeYetFZelc,1054
7
+ cdp_python_sdk-0.1.1.dist-info/METADATA,sha256=UPXmtNv8NINgw95_UsOTikik2vpgMzstbM6ifmbS18w,7496
8
+ cdp_python_sdk-0.1.1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
9
+ cdp_python_sdk-0.1.1.dist-info/top_level.txt,sha256=jB1SkK6Q3zW7mSoeDfKRHQM2UZCUkDzD5A4TfJrOkZs,11
10
+ cdp_python_sdk-0.1.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (83.0.0)
2
+ Generator: setuptools (84.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,10 +0,0 @@
1
- cdp_client/__init__.py,sha256=e5RV_Us_IdqebbQjPynufcM5i41oba0EomvUwJpLxOE,433
2
- cdp_client/client.py,sha256=wVBufNCh4gDCU1Dlfua0zalC8yfc0QCJ9Ja-j_qEIE4,8275
3
- cdp_client/errors.py,sha256=a_TmPv2gxKDy3BlgYhgSmQBSvrcTNbXWVMYH6DNLWqg,395
4
- cdp_client/gateway_urls.py,sha256=08B8Y3OIc48T3KHiHLndD-R8j3tI43YFywd1eyRw6Ek,1184
5
- cdp_client/models.py,sha256=Egrdq9tugatsJRM_sqv4350XNaleZM2KRsaeFLK-YRQ,3690
6
- cdp_client/validators.py,sha256=MDjTrEqj-ALkuuDgMZcUZ9mKeueKny2SEgeYetFZelc,1054
7
- cdp_python_sdk-0.1.0.dist-info/METADATA,sha256=cuDbg7ViwrZ6tlsb6JO-2uqSrcadnl5JSNBCbb0lghU,7495
8
- cdp_python_sdk-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
9
- cdp_python_sdk-0.1.0.dist-info/top_level.txt,sha256=jB1SkK6Q3zW7mSoeDfKRHQM2UZCUkDzD5A4TfJrOkZs,11
10
- cdp_python_sdk-0.1.0.dist-info/RECORD,,