Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CCAI Python Client

Version: 1.1.0
Version: 1.2.0

A Python client for interacting with the CloudContactAI API.

Expand Down
26 changes: 24 additions & 2 deletions integration/test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""
Python SDK integration tests — 52 tests
Python SDK integration tests — 54 tests
Covers: SMS (1-6), MMS (7-17), Email (18-22), Webhook (23-29), Contact (30-31),
Brands (32-36), Campaigns (37-42), ContactValidator (43-46), Negative cases (47-52)
Brands (32-36), Campaigns (37-42), ContactValidator (43-46), Negative cases (47-52),
SMS Templates (53-54)

Test results use three states:
PASS — the test ran and all assertions held
Expand Down Expand Up @@ -133,6 +134,7 @@ def cleanup_resources(client: CCAI, cleanup: dict) -> None:
"CCAI_TEST_FIRST_NAME_3",
"CCAI_TEST_LAST_NAME_3",
"WEBHOOK_URL",
"CCAI_TEST_TEMPLATE_ID",
]


Expand All @@ -158,6 +160,7 @@ def main() -> None:
ln2 = os.environ["CCAI_TEST_LAST_NAME_2"]
fn3 = os.environ["CCAI_TEST_FIRST_NAME_3"]
ln3 = os.environ["CCAI_TEST_LAST_NAME_3"]
template_id = int(os.environ["CCAI_TEST_TEMPLATE_ID"])

# Unique per-run suffix so parallel SDK runs don't collide on the same webhook URL
run_id = f"python-{int(time.time())}"
Expand Down Expand Up @@ -844,6 +847,25 @@ def test_52():
assert_send_response(resp)
run("52 PERMISSIVE: MMS.send with nonexistent fileKey (API accepts)", test_52)

print("\n--- SMS Templates ---")

def test_53():
resp = client.sms.send_with_template(
[
Account(first_name=fn1, last_name=ln1, phone=phone1),
Account(first_name=fn2, last_name=ln2, phone=phone2),
], template_id=template_id, title="Python Template Test"
)
assert_send_response(resp)
run("53 SMS.send_with_template", test_53)

def test_54():
resp = client.sms.send_single_with_template(
first_name=fn1, last_name=ln1, phone=phone1, template_id=template_id, title="Python Single Template Test"
)
assert_send_response(resp)
run("54 SMS.send_single_with_template", test_54)

finally:
# ── Cleanup ─────────────────────────────────────────────────────────────
# Always runs, even if the test body raised: delete leftover resources and the temp PNG.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "ccai-python"
version = "1.1.0"
version = "1.2.0"
description = "Python client for CloudContactAI API"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='ccai',
version='1.1.0',
version='1.2.0',
description='A CLI and Python client for sending SMS via CloudContactAI',
author='CloudContactAI LLC',
license='MIT',
Expand Down
2 changes: 1 addition & 1 deletion src/ccai_python/sms/sms.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def send(
) -> SMSResponse:
if not accounts:
raise ValueError("At least one account is required")
if not message:
if not message and template_id is None:
raise ValueError("Message is required")
if not title:
raise ValueError("Campaign title is required")
Expand Down