Python SDK for sf-queue - Redis-based queue system
Project description
sf-queue-sdk
Python SDK for sf-queue. Enqueues emails via Redis Streams with optional blocking confirmation from the Go consumer service.
Installation
pip install sf-queue-sdk
Setup
from queue_sdk import QueueClient
client = QueueClient(
redis_url="redis://localhost:6379",
redis_password="your-password",
environment="staging", # prefixes stream names: staging:{email}
)
Single Email
Fire and forget
Enqueues the email and returns immediately. Does not wait for the consumer to process it.
result = client.email.send(
to="user@example.com",
preview="Welcome to StudyFetch!",
subject="Welcome to StudyFetch!",
paragraphs=[
"Hey there,",
"Welcome to the StudyFetch community!",
"Thanks for joining us.",
],
button={
"text": "Go to Platform",
"href": "https://www.studyfetch.com/platform",
},
)
print("Enqueued:", result.message_id)
Send and wait for confirmation
Enqueues the email and blocks until the Go consumer processes it (or timeout).
result = client.email.send_and_wait(
to="user@example.com",
preview="Reset your password",
subject="StudyFetch: Reset Your Password",
paragraphs=[
"Hi There,",
"Click the button below to reset your password.",
],
button={
"text": "Reset Password",
"href": "https://www.studyfetch.com/reset?token=abc",
},
timeout=30, # optional, default 30s
)
print(result.success) # True or False
print(result.message_id) # request ID
print(result.error) # error message if failed
Batch Email
Send the same email content to multiple recipients (up to 100). The Go consumer sends to each recipient individually.
Fire and forget
result = client.email.send_batch(
to=[
"student1@example.com",
"student2@example.com",
"student3@example.com",
],
preview="You have been invited to join a class!",
subject="StudyFetch: Class Invitation",
paragraphs=[
"Hi There,",
'You have been invited to join "Intro to CS" on StudyFetch!',
"Click the button below to accept the invite.",
],
button={
"text": "Accept Invite",
"href": "https://www.studyfetch.com/invite/abc",
},
)
print("Enqueued:", result.message_id)
Send and wait for confirmation
result = client.email.send_batch_and_wait(
to=[
"student1@example.com",
"student2@example.com",
"student3@example.com",
],
preview="You have been invited to join a class!",
subject="StudyFetch: Class Invitation",
paragraphs=[
"Hi There,",
'You have been invited to join "Intro to CS" on StudyFetch!',
"Click the button below to accept the invite.",
],
button={
"text": "Accept Invite",
"href": "https://www.studyfetch.com/invite/abc",
},
timeout=30,
)
print(result.success) # True if at least some sent
print(result.message_id) # request ID
print(result.total) # 3
print(result.successful) # number sent successfully
print(result.failed) # number that failed
print(result.error) # error message if all failed
All Email Fields
| Field | Type | Required | Description |
|---|---|---|---|
to |
str |
Yes (single) | Recipient email address |
to |
list[str] |
Yes (batch) | List of recipient emails (max 100) |
preview |
str |
Yes | Preview text shown in email clients |
subject |
str |
Yes | Email subject line |
paragraphs |
list[str] |
Yes | Body content as paragraph strings |
button |
{"text": str, "href": str} |
No | Call-to-action button |
reply_to |
str |
No | Reply-to email address |
image |
{"src": str, "alt"?: str, "width"?: int, "height"?: int} |
No | Image in email body |
Optional Fields
# With all optional fields
client.email.send(
to="support@studyfetch.com",
preview="Support Request",
subject="StudyFetch: Support Request",
paragraphs=["Hi There,", "You received a support request.", issue],
reply_to="requester@example.com",
image={
"src": "https://example.com/logo.png",
"alt": "Logo",
"width": 150,
"height": 50,
},
)
Migrating from sendEmail / sendBatchEmail
The SDK is a drop-in replacement. Field names match the existing functions:
# BEFORE
send_email(to=to, preview=preview, subject=subject, paragraphs=paragraphs, button=button)
# AFTER (fire and forget)
client.email.send(to=to, preview=preview, subject=subject, paragraphs=paragraphs, button=button)
# AFTER (wait for confirmation)
client.email.send_and_wait(to=to, preview=preview, subject=subject, paragraphs=paragraphs, button=button)
# BEFORE (batch)
send_batch_email(to=[...], preview=preview, subject=subject, paragraphs=paragraphs, button=button)
# AFTER (batch, fire and forget)
client.email.send_batch(to=[...], preview=preview, subject=subject, paragraphs=paragraphs, button=button)
# AFTER (batch, wait for confirmation)
client.email.send_batch_and_wait(to=[...], preview=preview, subject=subject, paragraphs=paragraphs, button=button)
Methods and Response Types
| Method | Return Type | Fields |
|---|---|---|
send() |
SendResult |
message_id |
send_and_wait() |
EmailResponse |
success, message_id, error?, processed_at? |
send_batch() |
SendResult |
message_id |
send_batch_and_wait() |
BatchEmailResponse |
success, message_id, error?, processed_at?, total, successful, failed |
Topic Assignment
Fire and forget
result = client.topic_assignment.send(
topic_vector_id="507f1f77bcf86cd799439011",
topic_id="topic_abc123",
user_id="user_xyz",
current_assignment=None,
new_assignment="faiss_1422.0",
)
print("Enqueued:", result.message_id)
Send and wait for confirmation
result = client.topic_assignment.send_and_wait(
topic_vector_id="507f1f77bcf86cd799439011",
topic_id="topic_abc123",
user_id="user_xyz",
current_assignment=None,
new_assignment="faiss_1422.0",
timeout=30,
)
print(result.success)
print(result.message_id)
Batch (fire and forget)
result = client.topic_assignment.send_batch(
assignments=[
{
"topic_vector_id": "507f1f77bcf86cd799439011",
"topic_id": "topic_abc123",
"user_id": "user_xyz",
"current_assignment": None,
"new_assignment": "faiss_1422.0",
},
{
"topic_vector_id": "507f1f77bcf86cd799439012",
"topic_id": "topic_def456",
"user_id": "user_xyz",
"current_assignment": "faiss_1422",
"new_assignment": "faiss_1422.1",
},
],
)
Batch (wait for confirmation)
result = client.topic_assignment.send_batch_and_wait(
assignments=[
{
"topic_vector_id": "507f1f77bcf86cd799439011",
"topic_id": "topic_abc123",
"user_id": "user_xyz",
"current_assignment": None,
"new_assignment": "faiss_1422.0",
},
],
timeout=30,
)
print(result.success)
print(result.total)
print(result.successful)
print(result.failed)
Topic Assignment Fields
| Field | Type | Required | Description |
|---|---|---|---|
topic_vector_id |
str |
Yes | MongoDB _id of the topic_vector |
topic_id |
str |
Yes | The topicId field |
user_id |
str |
Yes | The userId who owns the topic |
current_assignment |
Optional[str] |
Yes | Current cluster_id (None for first-time) |
new_assignment |
str |
Yes | The new cluster_id |
Tool Assignment
Fire and forget
result = client.tool_assignment.send(
tool_id="507f1f77bcf86cd799439011",
user_id="user_xyz",
topic_id="topic_abc123",
current_assignment=None,
new_assignment="faiss_1422.0",
)
Send and wait for confirmation
result = client.tool_assignment.send_and_wait(
tool_id="507f1f77bcf86cd799439011",
user_id="user_xyz",
topic_id="topic_abc123",
current_assignment=None,
new_assignment="faiss_1422.0",
timeout=30,
)
Batch (fire and forget)
result = client.tool_assignment.send_batch(
assignments=[
{
"tool_id": "507f1f77bcf86cd799439011",
"user_id": "user_xyz",
"topic_id": "topic_abc123",
"current_assignment": None,
"new_assignment": "faiss_1422.0",
},
{
"tool_id": "507f1f77bcf86cd799439012",
"user_id": "user_xyz",
"topic_id": "topic_abc123",
"current_assignment": "faiss_1422",
"new_assignment": "faiss_1422.1",
},
],
)
Batch (wait for confirmation)
result = client.tool_assignment.send_batch_and_wait(
assignments=[
{"tool_id": "...", "user_id": "...", "topic_id": "...", "current_assignment": None, "new_assignment": "..."},
],
timeout=30,
)
Tool Assignment Fields
| Field | Type | Required | Description |
|---|---|---|---|
tool_id |
str |
Yes | MongoDB _id of the tool document |
user_id |
str |
Yes | The userId who owns the tool |
topic_id |
str |
Yes | The topicId the tool belongs to |
current_assignment |
Optional[str] |
Yes | Current cluster_id (None for new embeddings) |
new_assignment |
str |
Yes | The cluster_id to assign to |
Cleanup
client.disconnect()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sf_queue_sdk-0.2.0b21.tar.gz.
File metadata
- Download URL: sf_queue_sdk-0.2.0b21.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7db9481531b60846a02685e75dcdafeef0890722d7e9c36f7f0b7d4c88e8910d
|
|
| MD5 |
2757eac1d520377ccdc53b283c21f07c
|
|
| BLAKE2b-256 |
0624d98be74b97586dd038dbcfe80bb38314503b019a19b0500a7118b4158ccf
|
File details
Details for the file sf_queue_sdk-0.2.0b21-py3-none-any.whl.
File metadata
- Download URL: sf_queue_sdk-0.2.0b21-py3-none-any.whl
- Upload date:
- Size: 18.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9b37c49b16719392f99d3e25bffbafcaafeafe30b37d3afd66999082af699e8
|
|
| MD5 |
107bb576c4c9f44304c233ba026fbdb5
|
|
| BLAKE2b-256 |
5cf5d82e140f008833634cb71d554031994eef02f679b7d588b78353132f3b2b
|