agentcrm 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.
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .env
4
+ .venv/
5
+ dist/
6
+ *.egg-info/
7
+ .ruff_cache/
8
+ .pytest_cache/
9
+ test.db
10
+ node_modules/
11
+ console/dist/
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentcrm
3
+ Version: 0.1.0
4
+ Summary: Python SDK for AgentCRM — agent-native contact & newsletter API
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: httpx>=0.25.0
@@ -0,0 +1,3 @@
1
+ from agentcrm_sdk.client import AgentCRM
2
+
3
+ __all__ = ["AgentCRM"]
@@ -0,0 +1,149 @@
1
+ from __future__ import annotations
2
+
3
+ import httpx
4
+
5
+ DEFAULT_BASE_URL = "https://positive-wisdom-production-acc3.up.railway.app"
6
+
7
+
8
+ class AgentCRM:
9
+ def __init__(
10
+ self,
11
+ api_key: str,
12
+ base_url: str = DEFAULT_BASE_URL,
13
+ ):
14
+ self._client = httpx.Client(
15
+ base_url=base_url,
16
+ headers={"Authorization": f"Bearer {api_key}"},
17
+ timeout=30.0,
18
+ )
19
+ self.contacts = ContactsResource(self._client)
20
+ self.lists = ListsResource(self._client)
21
+ self.sends = SendsResource(self._client)
22
+
23
+ def close(self):
24
+ self._client.close()
25
+
26
+ def __enter__(self):
27
+ return self
28
+
29
+ def __exit__(self, *args):
30
+ self.close()
31
+
32
+
33
+ class ContactsResource:
34
+ def __init__(self, client: httpx.Client):
35
+ self._client = client
36
+
37
+ def create(
38
+ self, email: str, metadata: dict | None = None
39
+ ) -> dict:
40
+ resp = self._client.post(
41
+ "/contacts",
42
+ json={"email": email, "metadata": metadata},
43
+ )
44
+ resp.raise_for_status()
45
+ return resp.json()
46
+
47
+ def list(self, cursor: int | None = None, limit: int = 50) -> dict:
48
+ params = {"limit": limit}
49
+ if cursor is not None:
50
+ params["cursor"] = cursor
51
+ resp = self._client.get("/contacts", params=params)
52
+ resp.raise_for_status()
53
+ return resp.json()
54
+
55
+ def get(self, contact_id: int) -> dict:
56
+ resp = self._client.get(f"/contacts/{contact_id}")
57
+ resp.raise_for_status()
58
+ return resp.json()
59
+
60
+ def update(
61
+ self,
62
+ contact_id: int,
63
+ email: str | None = None,
64
+ metadata: dict | None = None,
65
+ ) -> dict:
66
+ body = {}
67
+ if email is not None:
68
+ body["email"] = email
69
+ if metadata is not None:
70
+ body["metadata"] = metadata
71
+ resp = self._client.put(f"/contacts/{contact_id}", json=body)
72
+ resp.raise_for_status()
73
+ return resp.json()
74
+
75
+ def delete(self, contact_id: int) -> None:
76
+ resp = self._client.delete(f"/contacts/{contact_id}")
77
+ resp.raise_for_status()
78
+
79
+
80
+ class ListsResource:
81
+ def __init__(self, client: httpx.Client):
82
+ self._client = client
83
+
84
+ def create(self, name: str) -> dict:
85
+ resp = self._client.post("/lists", json={"name": name})
86
+ resp.raise_for_status()
87
+ return resp.json()
88
+
89
+ def list(self) -> dict:
90
+ resp = self._client.get("/lists")
91
+ resp.raise_for_status()
92
+ return resp.json()
93
+
94
+ def get(self, list_id: int) -> dict:
95
+ resp = self._client.get(f"/lists/{list_id}")
96
+ resp.raise_for_status()
97
+ return resp.json()
98
+
99
+ def delete(self, list_id: int) -> None:
100
+ resp = self._client.delete(f"/lists/{list_id}")
101
+ resp.raise_for_status()
102
+
103
+ def add_contacts(self, list_id: int, contact_ids: list[int]) -> None:
104
+ resp = self._client.post(
105
+ f"/lists/{list_id}/contacts",
106
+ json={"contact_ids": contact_ids},
107
+ )
108
+ resp.raise_for_status()
109
+
110
+ def remove_contact(self, list_id: int, contact_id: int) -> None:
111
+ resp = self._client.delete(
112
+ f"/lists/{list_id}/contacts/{contact_id}"
113
+ )
114
+ resp.raise_for_status()
115
+
116
+ def members(self, list_id: int) -> dict:
117
+ resp = self._client.get(f"/lists/{list_id}/contacts")
118
+ resp.raise_for_status()
119
+ return resp.json()
120
+
121
+ def send(
122
+ self,
123
+ list_id: int,
124
+ subject: str,
125
+ sender_name: str,
126
+ body_text: str | None = None,
127
+ body_html: str | None = None,
128
+ ) -> dict:
129
+ resp = self._client.post(
130
+ f"/lists/{list_id}/send",
131
+ json={
132
+ "subject": subject,
133
+ "sender_name": sender_name,
134
+ "body_text": body_text,
135
+ "body_html": body_html,
136
+ },
137
+ )
138
+ resp.raise_for_status()
139
+ return resp.json()
140
+
141
+
142
+ class SendsResource:
143
+ def __init__(self, client: httpx.Client):
144
+ self._client = client
145
+
146
+ def get(self, send_id: int) -> dict:
147
+ resp = self._client.get(f"/sends/{send_id}")
148
+ resp.raise_for_status()
149
+ return resp.json()
@@ -0,0 +1,15 @@
1
+ [project]
2
+ name = "agentcrm"
3
+ version = "0.1.0"
4
+ description = "Python SDK for AgentCRM — agent-native contact & newsletter API"
5
+ requires-python = ">=3.10"
6
+ dependencies = [
7
+ "httpx>=0.25.0",
8
+ ]
9
+
10
+ [build-system]
11
+ requires = ["hatchling"]
12
+ build-backend = "hatchling.build"
13
+
14
+ [tool.hatch.build.targets.wheel]
15
+ packages = ["agentcrm_sdk"]