248-sdk 0.1.0__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.
- 248_sdk-0.1.0/.gitignore +11 -0
- 248_sdk-0.1.0/PKG-INFO +157 -0
- 248_sdk-0.1.0/README.md +117 -0
- 248_sdk-0.1.0/pyproject.toml +78 -0
- 248_sdk-0.1.0/sdk_248/__init__.py +34 -0
- 248_sdk-0.1.0/sdk_248/db/__init__.py +12 -0
- 248_sdk-0.1.0/sdk_248/db/mongo.py +119 -0
- 248_sdk-0.1.0/sdk_248/db/postgres.py +139 -0
- 248_sdk-0.1.0/sdk_248/models/__init__.py +30 -0
- 248_sdk-0.1.0/sdk_248/models/enums.py +56 -0
- 248_sdk-0.1.0/sdk_248/models/mongo/__init__.py +13 -0
- 248_sdk-0.1.0/sdk_248/models/mongo/action_run.py +51 -0
- 248_sdk-0.1.0/sdk_248/models/mongo/campaign.py +75 -0
- 248_sdk-0.1.0/sdk_248/models/mongo/lead.py +71 -0
- 248_sdk-0.1.0/sdk_248/models/mongo/node.py +20 -0
- 248_sdk-0.1.0/sdk_248/models/postgres/__init__.py +8 -0
- 248_sdk-0.1.0/sdk_248/models/postgres/organization.py +38 -0
- 248_sdk-0.1.0/sdk_248/py.typed +0 -0
- 248_sdk-0.1.0/sdk_248/schemas/__init__.py +23 -0
- 248_sdk-0.1.0/sdk_248/schemas/organization.py +43 -0
- 248_sdk-0.1.0/sdk_248/schemas/smartlead/__init__.py +100 -0
- 248_sdk-0.1.0/sdk_248/schemas/smartlead/request.py +355 -0
- 248_sdk-0.1.0/sdk_248/schemas/smartlead/response.py +197 -0
- 248_sdk-0.1.0/sdk_248/schemas/smartlead/validators.py +100 -0
- 248_sdk-0.1.0/sdk_248/schemas/smartlead/webhook.py +122 -0
248_sdk-0.1.0/.gitignore
ADDED
248_sdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: 248-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Shared SDK for 248 products - MongoDB models, PostgreSQL models, and SmartLead schemas
|
|
5
|
+
Project-URL: Repository, https://github.com/248ai/248-sdk
|
|
6
|
+
Author-email: Wenzo Rithelly <rithellyenzo@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: beanie,mongodb,postgresql,sdk,smartlead,sqlalchemy
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Typing :: Typed
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: beanie<3.0.0,>=2.0.1
|
|
19
|
+
Requires-Dist: motor<4.0.0,>=3.3.0
|
|
20
|
+
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
21
|
+
Requires-Dist: sqlalchemy<3.0.0,>=2.0.0
|
|
22
|
+
Provides-Extra: all
|
|
23
|
+
Requires-Dist: mypy>=1.8.0; extra == 'all'
|
|
24
|
+
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.0; extra == 'all'
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'all'
|
|
26
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'all'
|
|
27
|
+
Requires-Dist: pytest>=8.0.0; extra == 'all'
|
|
28
|
+
Requires-Dist: ruff>=0.2.0; extra == 'all'
|
|
29
|
+
Provides-Extra: asyncpg
|
|
30
|
+
Requires-Dist: asyncpg<1.0.0,>=0.29.0; extra == 'asyncpg'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: mypy>=1.8.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.2.0; extra == 'dev'
|
|
37
|
+
Provides-Extra: postgres
|
|
38
|
+
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.0; extra == 'postgres'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# 248 SDK
|
|
42
|
+
|
|
43
|
+
Shared SDK for 248 products - MongoDB models, PostgreSQL models, and SmartLead schemas.
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# From Git
|
|
49
|
+
pip install git+https://github.com/248ai/248-sdk.git
|
|
50
|
+
|
|
51
|
+
# With PostgreSQL support
|
|
52
|
+
pip install "248-sdk[postgres] @ git+https://github.com/248ai/248-sdk.git"
|
|
53
|
+
|
|
54
|
+
# Local development (editable)
|
|
55
|
+
pip install -e .
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
### MongoDB Models
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
import asyncio
|
|
64
|
+
from sdk_248 import mongodb
|
|
65
|
+
from sdk_248.models import Campaign, CampaignStatus
|
|
66
|
+
|
|
67
|
+
async def main():
|
|
68
|
+
# Initialize MongoDB connection
|
|
69
|
+
await mongodb.initialize(
|
|
70
|
+
connection_string="mongodb://localhost:27017",
|
|
71
|
+
database_name="mydb"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Query campaigns
|
|
75
|
+
campaigns = await Campaign.find(
|
|
76
|
+
Campaign.status == CampaignStatus.RUNNING
|
|
77
|
+
).to_list()
|
|
78
|
+
|
|
79
|
+
for campaign in campaigns:
|
|
80
|
+
print(f"Campaign: {campaign.name}")
|
|
81
|
+
|
|
82
|
+
# Close connection
|
|
83
|
+
await mongodb.close()
|
|
84
|
+
|
|
85
|
+
asyncio.run(main())
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### PostgreSQL Models
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from sdk_248 import postgres
|
|
92
|
+
from sdk_248.models import Organization
|
|
93
|
+
|
|
94
|
+
# Initialize PostgreSQL
|
|
95
|
+
postgres.initialize(
|
|
96
|
+
connection_string="postgresql://user:pass@localhost:5432/db"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Use sessions
|
|
100
|
+
with postgres.session() as session:
|
|
101
|
+
orgs = session.query(Organization).all()
|
|
102
|
+
for org in orgs:
|
|
103
|
+
print(f"Organization: {org.name}")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Using Models Without Database
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from sdk_248.models import Lead, CampaignStatus
|
|
110
|
+
|
|
111
|
+
# Create models for validation/serialization
|
|
112
|
+
lead = Lead(
|
|
113
|
+
email="test@example.com",
|
|
114
|
+
first_name="John",
|
|
115
|
+
last_name="Doe"
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Serialize to dict
|
|
119
|
+
lead_dict = lead.model_dump()
|
|
120
|
+
|
|
121
|
+
# Use enums
|
|
122
|
+
status = CampaignStatus.RUNNING
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Available Exports
|
|
126
|
+
|
|
127
|
+
### From `sdk_248`
|
|
128
|
+
- `MongoDBManager`, `mongodb` - MongoDB connection management
|
|
129
|
+
- `PostgresManager`, `postgres`, `Base` - PostgreSQL connection management
|
|
130
|
+
|
|
131
|
+
### From `sdk_248.models`
|
|
132
|
+
|
|
133
|
+
#### Enums
|
|
134
|
+
- `CampaignStatus` - Campaign status values
|
|
135
|
+
- `EmailOrchestrator` - Email orchestrator options
|
|
136
|
+
- `AppType` - Application types
|
|
137
|
+
- `NodeType` - Node types for responder actions
|
|
138
|
+
- `ActionRunStatus` - Action run status values
|
|
139
|
+
- `CategoriserStatus` - Categoriser status values
|
|
140
|
+
|
|
141
|
+
#### MongoDB Models
|
|
142
|
+
- `Campaign` - Main campaign document (Beanie)
|
|
143
|
+
- `Lead` - Lead embedded model
|
|
144
|
+
- `ActionRun` - Action run embedded model
|
|
145
|
+
- `Node` - Responder node model
|
|
146
|
+
|
|
147
|
+
#### PostgreSQL Models
|
|
148
|
+
- `Organization` - Organization entity
|
|
149
|
+
- `OrganizationStatus` - Organization status enum
|
|
150
|
+
|
|
151
|
+
### From `sdk_248.schemas`
|
|
152
|
+
- `CampaignSequenceInput` - Campaign sequence configuration
|
|
153
|
+
- `CampaignReplyWebhookSchema` - Reply webhook payload
|
|
154
|
+
- `EmailSentWebhookSchema` - Email sent webhook payload
|
|
155
|
+
- `Organization` - Organization response schema (Pydantic)
|
|
156
|
+
- `OrganizationCreate` - Organization create schema
|
|
157
|
+
- `OrganizationUpdate` - Organization update schema
|
248_sdk-0.1.0/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# 248 SDK
|
|
2
|
+
|
|
3
|
+
Shared SDK for 248 products - MongoDB models, PostgreSQL models, and SmartLead schemas.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# From Git
|
|
9
|
+
pip install git+https://github.com/248ai/248-sdk.git
|
|
10
|
+
|
|
11
|
+
# With PostgreSQL support
|
|
12
|
+
pip install "248-sdk[postgres] @ git+https://github.com/248ai/248-sdk.git"
|
|
13
|
+
|
|
14
|
+
# Local development (editable)
|
|
15
|
+
pip install -e .
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### MongoDB Models
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
import asyncio
|
|
24
|
+
from sdk_248 import mongodb
|
|
25
|
+
from sdk_248.models import Campaign, CampaignStatus
|
|
26
|
+
|
|
27
|
+
async def main():
|
|
28
|
+
# Initialize MongoDB connection
|
|
29
|
+
await mongodb.initialize(
|
|
30
|
+
connection_string="mongodb://localhost:27017",
|
|
31
|
+
database_name="mydb"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Query campaigns
|
|
35
|
+
campaigns = await Campaign.find(
|
|
36
|
+
Campaign.status == CampaignStatus.RUNNING
|
|
37
|
+
).to_list()
|
|
38
|
+
|
|
39
|
+
for campaign in campaigns:
|
|
40
|
+
print(f"Campaign: {campaign.name}")
|
|
41
|
+
|
|
42
|
+
# Close connection
|
|
43
|
+
await mongodb.close()
|
|
44
|
+
|
|
45
|
+
asyncio.run(main())
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### PostgreSQL Models
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from sdk_248 import postgres
|
|
52
|
+
from sdk_248.models import Organization
|
|
53
|
+
|
|
54
|
+
# Initialize PostgreSQL
|
|
55
|
+
postgres.initialize(
|
|
56
|
+
connection_string="postgresql://user:pass@localhost:5432/db"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Use sessions
|
|
60
|
+
with postgres.session() as session:
|
|
61
|
+
orgs = session.query(Organization).all()
|
|
62
|
+
for org in orgs:
|
|
63
|
+
print(f"Organization: {org.name}")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Using Models Without Database
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from sdk_248.models import Lead, CampaignStatus
|
|
70
|
+
|
|
71
|
+
# Create models for validation/serialization
|
|
72
|
+
lead = Lead(
|
|
73
|
+
email="test@example.com",
|
|
74
|
+
first_name="John",
|
|
75
|
+
last_name="Doe"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# Serialize to dict
|
|
79
|
+
lead_dict = lead.model_dump()
|
|
80
|
+
|
|
81
|
+
# Use enums
|
|
82
|
+
status = CampaignStatus.RUNNING
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Available Exports
|
|
86
|
+
|
|
87
|
+
### From `sdk_248`
|
|
88
|
+
- `MongoDBManager`, `mongodb` - MongoDB connection management
|
|
89
|
+
- `PostgresManager`, `postgres`, `Base` - PostgreSQL connection management
|
|
90
|
+
|
|
91
|
+
### From `sdk_248.models`
|
|
92
|
+
|
|
93
|
+
#### Enums
|
|
94
|
+
- `CampaignStatus` - Campaign status values
|
|
95
|
+
- `EmailOrchestrator` - Email orchestrator options
|
|
96
|
+
- `AppType` - Application types
|
|
97
|
+
- `NodeType` - Node types for responder actions
|
|
98
|
+
- `ActionRunStatus` - Action run status values
|
|
99
|
+
- `CategoriserStatus` - Categoriser status values
|
|
100
|
+
|
|
101
|
+
#### MongoDB Models
|
|
102
|
+
- `Campaign` - Main campaign document (Beanie)
|
|
103
|
+
- `Lead` - Lead embedded model
|
|
104
|
+
- `ActionRun` - Action run embedded model
|
|
105
|
+
- `Node` - Responder node model
|
|
106
|
+
|
|
107
|
+
#### PostgreSQL Models
|
|
108
|
+
- `Organization` - Organization entity
|
|
109
|
+
- `OrganizationStatus` - Organization status enum
|
|
110
|
+
|
|
111
|
+
### From `sdk_248.schemas`
|
|
112
|
+
- `CampaignSequenceInput` - Campaign sequence configuration
|
|
113
|
+
- `CampaignReplyWebhookSchema` - Reply webhook payload
|
|
114
|
+
- `EmailSentWebhookSchema` - Email sent webhook payload
|
|
115
|
+
- `Organization` - Organization response schema (Pydantic)
|
|
116
|
+
- `OrganizationCreate` - Organization create schema
|
|
117
|
+
- `OrganizationUpdate` - Organization update schema
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "248-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Shared SDK for 248 products - MongoDB models, PostgreSQL models, and SmartLead schemas"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Wenzo Rithelly", email = "rithellyenzo@gmail.com"}
|
|
13
|
+
]
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Typing :: Typed",
|
|
24
|
+
]
|
|
25
|
+
keywords = ["sdk", "mongodb", "postgresql", "beanie", "sqlalchemy", "smartlead"]
|
|
26
|
+
|
|
27
|
+
dependencies = [
|
|
28
|
+
"pydantic>=2.0.0,<3.0.0",
|
|
29
|
+
"beanie>=2.0.1,<3.0.0",
|
|
30
|
+
"motor>=3.3.0,<4.0.0",
|
|
31
|
+
"sqlalchemy>=2.0.0,<3.0.0",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
postgres = [
|
|
36
|
+
"psycopg2-binary>=2.9.0,<3.0.0",
|
|
37
|
+
]
|
|
38
|
+
asyncpg = [
|
|
39
|
+
"asyncpg>=0.29.0,<1.0.0",
|
|
40
|
+
]
|
|
41
|
+
dev = [
|
|
42
|
+
"pytest>=8.0.0",
|
|
43
|
+
"pytest-asyncio>=0.23.0",
|
|
44
|
+
"pytest-cov>=4.0.0",
|
|
45
|
+
"mypy>=1.8.0",
|
|
46
|
+
"ruff>=0.2.0",
|
|
47
|
+
]
|
|
48
|
+
all = [
|
|
49
|
+
"248-sdk[postgres,dev]",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Repository = "https://github.com/248ai/248-sdk"
|
|
54
|
+
|
|
55
|
+
[tool.hatch.build.targets.wheel]
|
|
56
|
+
packages = ["sdk_248"]
|
|
57
|
+
|
|
58
|
+
[tool.hatch.build.targets.sdist]
|
|
59
|
+
include = [
|
|
60
|
+
"/sdk_248",
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
[tool.pytest.ini_options]
|
|
64
|
+
testpaths = ["tests"]
|
|
65
|
+
asyncio_mode = "auto"
|
|
66
|
+
|
|
67
|
+
[tool.mypy]
|
|
68
|
+
python_version = "3.10"
|
|
69
|
+
strict = true
|
|
70
|
+
warn_return_any = true
|
|
71
|
+
warn_unused_ignores = true
|
|
72
|
+
|
|
73
|
+
[tool.ruff]
|
|
74
|
+
line-length = 100
|
|
75
|
+
target-version = "py310"
|
|
76
|
+
|
|
77
|
+
[tool.ruff.lint]
|
|
78
|
+
select = ["E", "F", "I", "N", "W", "B", "Q"]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""248 SDK - Shared models and utilities for 248 products.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
from sdk_248 import mongodb, postgres
|
|
5
|
+
from sdk_248.models import Campaign, CampaignStatus
|
|
6
|
+
|
|
7
|
+
# Initialize MongoDB
|
|
8
|
+
await mongodb.initialize(
|
|
9
|
+
connection_string="mongodb://localhost:27017",
|
|
10
|
+
database_name="mydb"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# Use models
|
|
14
|
+
campaigns = await Campaign.find(
|
|
15
|
+
Campaign.status == CampaignStatus.RUNNING
|
|
16
|
+
).to_list()
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
__version__ = "0.1.0"
|
|
20
|
+
|
|
21
|
+
# Database managers
|
|
22
|
+
from sdk_248.db.mongo import MongoDBManager, mongodb
|
|
23
|
+
from sdk_248.db.postgres import Base, PostgresManager, postgres
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
# Version
|
|
27
|
+
"__version__",
|
|
28
|
+
# Database managers
|
|
29
|
+
"MongoDBManager",
|
|
30
|
+
"mongodb",
|
|
31
|
+
"PostgresManager",
|
|
32
|
+
"postgres",
|
|
33
|
+
"Base",
|
|
34
|
+
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Database connection managers for the SDK."""
|
|
2
|
+
|
|
3
|
+
from sdk_248.db.mongo import MongoDBManager, mongodb
|
|
4
|
+
from sdk_248.db.postgres import Base, PostgresManager, postgres
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"MongoDBManager",
|
|
8
|
+
"mongodb",
|
|
9
|
+
"PostgresManager",
|
|
10
|
+
"postgres",
|
|
11
|
+
"Base",
|
|
12
|
+
]
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""MongoDB connection and Beanie initialization for the SDK."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional, Type
|
|
4
|
+
|
|
5
|
+
from beanie import Document, init_beanie
|
|
6
|
+
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MongoDBManager:
|
|
10
|
+
"""Manages MongoDB connections and Beanie initialization.
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
# Option 1: Let the SDK create the client
|
|
14
|
+
from sdk_248 import mongodb, Campaign
|
|
15
|
+
|
|
16
|
+
await mongodb.initialize(
|
|
17
|
+
connection_string="mongodb://user:pass@host:27017",
|
|
18
|
+
database_name="mydb"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# Now use models
|
|
22
|
+
campaigns = await Campaign.find_all().to_list()
|
|
23
|
+
|
|
24
|
+
# Option 2: Use your own client
|
|
25
|
+
from motor.motor_asyncio import AsyncIOMotorClient
|
|
26
|
+
from sdk_248 import MongoDBManager, Campaign
|
|
27
|
+
|
|
28
|
+
client = AsyncIOMotorClient("mongodb://...")
|
|
29
|
+
manager = MongoDBManager()
|
|
30
|
+
await manager.initialize_with_client(
|
|
31
|
+
client=client,
|
|
32
|
+
database_name="mydb"
|
|
33
|
+
)
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
_client: Optional[AsyncIOMotorClient] = None
|
|
37
|
+
_database: Optional[AsyncIOMotorDatabase] = None
|
|
38
|
+
_initialized: bool = False
|
|
39
|
+
|
|
40
|
+
def _get_document_models(self) -> List[Type[Document]]:
|
|
41
|
+
"""Get all Beanie document models to register.
|
|
42
|
+
|
|
43
|
+
Import here to avoid circular imports.
|
|
44
|
+
"""
|
|
45
|
+
from sdk_248.models.mongo.campaign import Campaign
|
|
46
|
+
|
|
47
|
+
return [Campaign]
|
|
48
|
+
|
|
49
|
+
async def initialize(
|
|
50
|
+
self,
|
|
51
|
+
connection_string: str,
|
|
52
|
+
database_name: str,
|
|
53
|
+
document_models: Optional[List[Type[Document]]] = None,
|
|
54
|
+
) -> None:
|
|
55
|
+
"""Initialize MongoDB connection and Beanie ODM.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
connection_string: MongoDB connection URI
|
|
59
|
+
database_name: Name of the database to use
|
|
60
|
+
document_models: Optional custom list of document models.
|
|
61
|
+
If None, uses default SDK models.
|
|
62
|
+
"""
|
|
63
|
+
self._client = AsyncIOMotorClient(connection_string)
|
|
64
|
+
self._database = self._client[database_name]
|
|
65
|
+
|
|
66
|
+
models = document_models or self._get_document_models()
|
|
67
|
+
await init_beanie(database=self._database, document_models=models)
|
|
68
|
+
self._initialized = True
|
|
69
|
+
|
|
70
|
+
async def initialize_with_client(
|
|
71
|
+
self,
|
|
72
|
+
client: AsyncIOMotorClient,
|
|
73
|
+
database_name: str,
|
|
74
|
+
document_models: Optional[List[Type[Document]]] = None,
|
|
75
|
+
) -> None:
|
|
76
|
+
"""Initialize Beanie with an existing MongoDB client.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
client: Existing AsyncIOMotorClient instance
|
|
80
|
+
database_name: Name of the database to use
|
|
81
|
+
document_models: Optional custom list of document models
|
|
82
|
+
"""
|
|
83
|
+
self._client = client
|
|
84
|
+
self._database = client[database_name]
|
|
85
|
+
|
|
86
|
+
models = document_models or self._get_document_models()
|
|
87
|
+
await init_beanie(database=self._database, document_models=models)
|
|
88
|
+
self._initialized = True
|
|
89
|
+
|
|
90
|
+
async def close(self) -> None:
|
|
91
|
+
"""Close the MongoDB connection."""
|
|
92
|
+
if self._client:
|
|
93
|
+
self._client.close()
|
|
94
|
+
self._client = None
|
|
95
|
+
self._database = None
|
|
96
|
+
self._initialized = False
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def database(self) -> AsyncIOMotorDatabase:
|
|
100
|
+
"""Get the database instance."""
|
|
101
|
+
if not self._initialized:
|
|
102
|
+
raise RuntimeError("MongoDB not initialized. Call initialize() first.")
|
|
103
|
+
return self._database
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def client(self) -> AsyncIOMotorClient:
|
|
107
|
+
"""Get the MongoDB client instance."""
|
|
108
|
+
if not self._initialized:
|
|
109
|
+
raise RuntimeError("MongoDB not initialized. Call initialize() first.")
|
|
110
|
+
return self._client
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def is_initialized(self) -> bool:
|
|
114
|
+
"""Check if the database is initialized."""
|
|
115
|
+
return self._initialized
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# Global instance for convenience
|
|
119
|
+
mongodb = MongoDBManager()
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""PostgreSQL connection and SQLAlchemy setup for the SDK."""
|
|
2
|
+
|
|
3
|
+
from contextlib import contextmanager
|
|
4
|
+
from typing import Generator, Optional
|
|
5
|
+
|
|
6
|
+
from sqlalchemy import create_engine
|
|
7
|
+
from sqlalchemy.engine import Engine
|
|
8
|
+
from sqlalchemy.orm import Session, declarative_base, sessionmaker
|
|
9
|
+
|
|
10
|
+
# Create the declarative base for all SQLAlchemy models
|
|
11
|
+
Base = declarative_base()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class PostgresManager:
|
|
15
|
+
"""Manages PostgreSQL connections and sessions.
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
from sdk_248 import postgres, Organization
|
|
19
|
+
|
|
20
|
+
# Initialize PostgreSQL
|
|
21
|
+
postgres.initialize(
|
|
22
|
+
connection_string="postgresql://user:pass@host:5432/db"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
# Use sessions
|
|
26
|
+
with postgres.session() as session:
|
|
27
|
+
orgs = session.query(Organization).all()
|
|
28
|
+
|
|
29
|
+
# Or create tables
|
|
30
|
+
postgres.create_tables()
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
_engine: Optional[Engine] = None
|
|
34
|
+
_session_factory: Optional[sessionmaker] = None
|
|
35
|
+
_initialized: bool = False
|
|
36
|
+
|
|
37
|
+
def initialize(
|
|
38
|
+
self,
|
|
39
|
+
connection_string: str,
|
|
40
|
+
echo: bool = False,
|
|
41
|
+
pool_size: int = 5,
|
|
42
|
+
max_overflow: int = 10,
|
|
43
|
+
) -> None:
|
|
44
|
+
"""Initialize PostgreSQL connection.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
connection_string: PostgreSQL connection URI
|
|
48
|
+
echo: If True, log all SQL statements
|
|
49
|
+
pool_size: Connection pool size
|
|
50
|
+
max_overflow: Max connections beyond pool_size
|
|
51
|
+
"""
|
|
52
|
+
self._engine = create_engine(
|
|
53
|
+
connection_string,
|
|
54
|
+
echo=echo,
|
|
55
|
+
pool_size=pool_size,
|
|
56
|
+
max_overflow=max_overflow,
|
|
57
|
+
)
|
|
58
|
+
self._session_factory = sessionmaker(
|
|
59
|
+
autocommit=False,
|
|
60
|
+
autoflush=False,
|
|
61
|
+
bind=self._engine,
|
|
62
|
+
)
|
|
63
|
+
self._initialized = True
|
|
64
|
+
|
|
65
|
+
def initialize_with_engine(self, engine: Engine) -> None:
|
|
66
|
+
"""Initialize with an existing SQLAlchemy engine.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
engine: Existing SQLAlchemy Engine instance
|
|
70
|
+
"""
|
|
71
|
+
self._engine = engine
|
|
72
|
+
self._session_factory = sessionmaker(
|
|
73
|
+
autocommit=False,
|
|
74
|
+
autoflush=False,
|
|
75
|
+
bind=self._engine,
|
|
76
|
+
)
|
|
77
|
+
self._initialized = True
|
|
78
|
+
|
|
79
|
+
@contextmanager
|
|
80
|
+
def session(self) -> Generator[Session, None, None]:
|
|
81
|
+
"""Get a database session (context manager).
|
|
82
|
+
|
|
83
|
+
Yields:
|
|
84
|
+
SQLAlchemy Session instance
|
|
85
|
+
|
|
86
|
+
Example:
|
|
87
|
+
with postgres.session() as session:
|
|
88
|
+
orgs = session.query(Organization).all()
|
|
89
|
+
"""
|
|
90
|
+
if not self._initialized:
|
|
91
|
+
raise RuntimeError("PostgreSQL not initialized. Call initialize() first.")
|
|
92
|
+
|
|
93
|
+
session = self._session_factory()
|
|
94
|
+
try:
|
|
95
|
+
yield session
|
|
96
|
+
session.commit()
|
|
97
|
+
except Exception:
|
|
98
|
+
session.rollback()
|
|
99
|
+
raise
|
|
100
|
+
finally:
|
|
101
|
+
session.close()
|
|
102
|
+
|
|
103
|
+
def create_session(self) -> Session:
|
|
104
|
+
"""Create a new session (caller responsible for closing).
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
SQLAlchemy Session instance
|
|
108
|
+
"""
|
|
109
|
+
if not self._initialized:
|
|
110
|
+
raise RuntimeError("PostgreSQL not initialized. Call initialize() first.")
|
|
111
|
+
return self._session_factory()
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def engine(self) -> Engine:
|
|
115
|
+
"""Get the SQLAlchemy engine."""
|
|
116
|
+
if not self._initialized:
|
|
117
|
+
raise RuntimeError("PostgreSQL not initialized. Call initialize() first.")
|
|
118
|
+
return self._engine
|
|
119
|
+
|
|
120
|
+
def create_tables(self) -> None:
|
|
121
|
+
"""Create all tables defined in models."""
|
|
122
|
+
if not self._initialized:
|
|
123
|
+
raise RuntimeError("PostgreSQL not initialized. Call initialize() first.")
|
|
124
|
+
Base.metadata.create_all(bind=self._engine)
|
|
125
|
+
|
|
126
|
+
def drop_tables(self) -> None:
|
|
127
|
+
"""Drop all tables defined in models. Use with caution!"""
|
|
128
|
+
if not self._initialized:
|
|
129
|
+
raise RuntimeError("PostgreSQL not initialized. Call initialize() first.")
|
|
130
|
+
Base.metadata.drop_all(bind=self._engine)
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def is_initialized(self) -> bool:
|
|
134
|
+
"""Check if the database is initialized."""
|
|
135
|
+
return self._initialized
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# Global instance for convenience
|
|
139
|
+
postgres = PostgresManager()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""All data models for the 248 SDK."""
|
|
2
|
+
|
|
3
|
+
from sdk_248.models.enums import (
|
|
4
|
+
ActionRunStatus,
|
|
5
|
+
AppType,
|
|
6
|
+
CampaignStatus,
|
|
7
|
+
CategoriserStatus,
|
|
8
|
+
EmailOrchestrator,
|
|
9
|
+
NodeType,
|
|
10
|
+
)
|
|
11
|
+
from sdk_248.models.mongo import ActionRun, Campaign, Lead, Node
|
|
12
|
+
from sdk_248.models.postgres import Organization, OrganizationStatus
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
# Enums
|
|
16
|
+
"ActionRunStatus",
|
|
17
|
+
"AppType",
|
|
18
|
+
"CampaignStatus",
|
|
19
|
+
"CategoriserStatus",
|
|
20
|
+
"EmailOrchestrator",
|
|
21
|
+
"NodeType",
|
|
22
|
+
# MongoDB models
|
|
23
|
+
"ActionRun",
|
|
24
|
+
"Campaign",
|
|
25
|
+
"Lead",
|
|
26
|
+
"Node",
|
|
27
|
+
# PostgreSQL models
|
|
28
|
+
"Organization",
|
|
29
|
+
"OrganizationStatus",
|
|
30
|
+
]
|