Official ActivitySmith Python SDK
Project description
ActivitySmith Python Library
The ActivitySmith Python library provides convenient access to the ActivitySmith API from Python applications.
Documentation
See the API reference.
Installation
This package is available on PyPI:
pip install activitysmith
Alternatively, install from source with:
python -m pip install .
Setup
import os
from activitysmith import ActivitySmith
activitysmith = ActivitySmith(
api_key=os.environ["ACTIVITYSMITH_API_KEY"],
)
Push Notifications
Send a Push Notification
activitysmith.notifications.send(
{
"title": "New subscription 💸",
"message": "Customer upgraded to Pro plan",
}
)
Rich Push Notifications with Media
activitysmith.notifications.send(
{
"title": "Homepage ready",
"message": "Your agent finished the redesign.",
"media": "https://cdn.example.com/output/homepage-v2.png",
"redirection": "https://github.com/acme/web/pull/482",
}
)
Send images, videos, or audio with your push notifications, press and hold to preview media directly from the notification, then tap through to open the linked content.
What will work:
- direct image URL:
.jpg,.png,.gif, etc. - direct audio file URL:
.mp3,.m4a, etc. - direct video file URL:
.mp4,.mov, etc. - URL that responds with a proper media
Content-Type, even if the path has no extension
Actionable Push Notifications
Actionable push notifications can open a URL on tap or trigger actions when someone long-presses the notification. Webhooks are executed by the ActivitySmith backend.
activitysmith.notifications.send(
{
"title": "New subscription 💸",
"message": "Customer upgraded to Pro plan",
"redirection": "https://crm.example.com/customers/cus_9f3a1d", # Optional
"actions": [ # Optional (max 4)
{
"title": "Open CRM Profile",
"type": "open_url",
"url": "https://crm.example.com/customers/cus_9f3a1d",
},
{
"title": "Start Onboarding Workflow",
"type": "webhook",
"url": "https://hooks.example.com/activitysmith/onboarding/start",
"method": "POST",
"body": {
"customer_id": "cus_9f3a1d",
"plan": "pro",
},
},
],
}
)
Live Activities
ActivitySmith supports two ways to drive Live Activities:
- Recommended: stream updates with
activitysmith.live_activities.stream(...) - Advanced: manual lifecycle control with
start,update, andend
Use stream updates when you want the easiest, stateless flow. You don't need to
store activity_id or manage lifecycle state yourself. Send the latest state
for a stable stream_key and ActivitySmith will start or update the Live
Activity for you. When the tracked process is over, call end_stream(...).
Use the manual lifecycle methods when you need direct control over a specific Live Activity instance.
Live Activity UI types:
metrics: best for live operational stats like server CPU and memory, queue depth, or replica lagsegmented_progress: best for step-based workflows like deployments, backups, and ETL pipelinesprogress: best for continuous jobs like uploads, reindexes, and long-running migrations tracked as a percentage
Recommended: Stream updates
Use a stable stream_key to identify the system or workflow you are tracking,
such as a server, deployment, build pipeline, cron job, or charging session.
This is especially useful for cron jobs and other scheduled tasks where you do
not want to store activity_id between runs.
Metrics
status = activitysmith.live_activities.stream(
"prod-web-1",
{
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{"label": "CPU", "value": 9, "unit": "%"},
{"label": "MEM", "value": 45, "unit": "%"},
],
},
},
)
Segmented progress
activitysmith.live_activities.stream(
"nightly-backup",
{
"content_state": {
"title": "Nightly Backup",
"subtitle": "upload archive",
"type": "segmented_progress",
"number_of_steps": 3,
"current_step": 2,
},
},
)
Progress
activitysmith.live_activities.stream(
"search-reindex",
{
"content_state": {
"title": "Search Reindex",
"subtitle": "catalog-v2",
"type": "progress",
"percentage": 42,
},
},
)
Call stream(...) again with the same stream_key whenever the state changes.
End a stream
Use this when the tracked process is finished and you no longer want the Live
Activity on devices. content_state is optional here; include it if you want
to end the stream with a final state.
activitysmith.live_activities.end_stream(
"prod-web-1",
{
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{"label": "CPU", "value": 7, "unit": "%"},
{"label": "MEM", "value": 38, "unit": "%"},
],
},
},
)
If you later send another stream(...) request with the same stream_key,
ActivitySmith starts a new Live Activity for that stream again.
Stream responses include an operation field:
started: ActivitySmith started a new Live Activity for thisstream_keyupdated: ActivitySmith updated the current Live Activityrotated: ActivitySmith ended the previous Live Activity and started a new onenoop: the incoming state matched the current state, so no update was sentpaused: the stream is paused, so no Live Activity was started or updatedended: returned byend_stream(...)after the stream is ended
Advanced: Manual lifecycle control
Use these methods when you want to manage the Live Activity lifecycle yourself.
Shared flow
- Call
activitysmith.live_activities.start(...). - Save the returned
activity_id. - Call
activitysmith.live_activities.update(...)as progress changes. - Call
activitysmith.live_activities.end(...)when the work is finished.
Metrics Type
Use metrics when you want to keep a small set of live stats visible, such as
server health, queue pressure, or database load.
Start
start = activitysmith.live_activities.start(
{
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{"label": "CPU", "value": 9, "unit": "%"},
{"label": "MEM", "value": 45, "unit": "%"},
],
},
}
)
activity_id = start.activity_id
Update
activitysmith.live_activities.update(
{
"activity_id": activity_id,
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{"label": "CPU", "value": 76, "unit": "%"},
{"label": "MEM", "value": 52, "unit": "%"},
],
},
}
)
End
activitysmith.live_activities.end(
{
"activity_id": activity_id,
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{"label": "CPU", "value": 7, "unit": "%"},
{"label": "MEM", "value": 38, "unit": "%"},
],
"auto_dismiss_minutes": 2,
},
}
)
Segmented Progress Type
Use segmented_progress when progress is easier to follow as steps instead of a
raw percentage. It fits jobs like backups, deployments, ETL pipelines, and
checklists where "step 2 of 3" is more useful than "67%". number_of_steps is
dynamic, so you can increase or decrease it later if the workflow changes.
Start
start = activitysmith.live_activities.start(
{
"content_state": {
"title": "Nightly database backup",
"subtitle": "create snapshot",
"number_of_steps": 3,
"current_step": 1,
"type": "segmented_progress",
"color": "yellow",
},
}
)
activity_id = start.activity_id
Update
activitysmith.live_activities.update(
{
"activity_id": activity_id,
"content_state": {
"title": "Nightly database backup",
"subtitle": "upload archive",
"number_of_steps": 3,
"current_step": 2,
},
}
)
End
activitysmith.live_activities.end(
{
"activity_id": activity_id,
"content_state": {
"title": "Nightly database backup",
"subtitle": "verify restore",
"number_of_steps": 3,
"current_step": 3,
"auto_dismiss_minutes": 2,
},
}
)
Progress Type
Use progress when the state is naturally continuous. It fits charging,
downloads, sync jobs, uploads, timers, and any flow where a percentage or
numeric range is the clearest signal.
Start
start = activitysmith.live_activities.start(
{
"content_state": {
"title": "EV Charging",
"subtitle": "Added 30 mi range",
"type": "progress",
"percentage": 15,
}
}
)
activity_id = start.activity_id
Update
activitysmith.live_activities.update(
{
"activity_id": activity_id,
"content_state": {
"title": "EV Charging",
"subtitle": "Added 120 mi range",
"percentage": 60,
}
}
)
End
activitysmith.live_activities.end(
{
"activity_id": activity_id,
"content_state": {
"title": "EV Charging",
"subtitle": "Added 200 mi range",
"percentage": 100,
"auto_dismiss_minutes": 2,
}
}
)
Live Activity Action
Just like Actionable Push Notifications, Live Activities can have a button that opens a URL in a browser or triggers a webhook. Webhooks are executed by the ActivitySmith backend.
Open URL action
start = activitysmith.live_activities.start(
{
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{"label": "CPU", "value": 76, "unit": "%"},
{"label": "MEM", "value": 52, "unit": "%"},
],
},
"action": {
"title": "Open Dashboard",
"type": "open_url",
"url": "https://ops.example.com/servers/prod-web-1",
},
}
)
activity_id = start.activity_id
Webhook action
activitysmith.live_activities.update(
{
"activity_id": activity_id,
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{"label": "CPU", "value": 91, "unit": "%"},
{"label": "MEM", "value": 57, "unit": "%"},
],
},
"action": {
"title": "Restart Service",
"type": "webhook",
"url": "https://ops.example.com/hooks/servers/prod-web-1/restart",
"method": "POST",
"body": {
"server_id": "prod-web-1",
"requested_by": "activitysmith-python",
},
},
}
)
Channels
Channels are used to target specific team members or devices. Can be used for both push notifications and live activities.
activitysmith.notifications.send(
{
"title": "New subscription 💸",
"message": "Customer upgraded to Pro plan",
"channels": ["sales", "customer-success"], # Optional
}
)
Error Handling
try:
activitysmith.notifications.send(
{
"title": "New subscription 💸",
}
)
except Exception as err:
print("Request failed:", err)
Request/response models are included and can be imported from activitysmith_openapi.models.
Requirements
- Python 3.9 or newer
License
MIT
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 activitysmith-1.1.0.tar.gz.
File metadata
- Download URL: activitysmith-1.1.0.tar.gz
- Upload date:
- Size: 42.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d69b5eca626dad32770279c03a05fccc9b71304afde84fb7fc5f7e868efba8d6
|
|
| MD5 |
f4c44c5ea598d2cf9aaa6f68f62e94d0
|
|
| BLAKE2b-256 |
c0657e08d29ceee6fb803da2d86c3860aa526aa021b2968a6def74c09028914b
|
Provenance
The following attestation bundles were made for activitysmith-1.1.0.tar.gz:
Publisher:
publish.yml on ActivitySmithHQ/activitysmith-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
activitysmith-1.1.0.tar.gz -
Subject digest:
d69b5eca626dad32770279c03a05fccc9b71304afde84fb7fc5f7e868efba8d6 - Sigstore transparency entry: 1155184670
- Sigstore integration time:
-
Permalink:
ActivitySmithHQ/activitysmith-python@8a3dc97b4d7dad8eff3fdaa14afb0a784a3397c3 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/ActivitySmithHQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8a3dc97b4d7dad8eff3fdaa14afb0a784a3397c3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file activitysmith-1.1.0-py3-none-any.whl.
File metadata
- Download URL: activitysmith-1.1.0-py3-none-any.whl
- Upload date:
- Size: 112.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4b204bd176d709c1a89de75241591d3dd45abd90a72078681f24a8b1d2b53b7
|
|
| MD5 |
ccd1bb100e242bda3098ffa8923f32f2
|
|
| BLAKE2b-256 |
99e0cfd98315e4035014f4f072e47e0532e17cce5be2e737c9b60803eab3a033
|
Provenance
The following attestation bundles were made for activitysmith-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on ActivitySmithHQ/activitysmith-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
activitysmith-1.1.0-py3-none-any.whl -
Subject digest:
c4b204bd176d709c1a89de75241591d3dd45abd90a72078681f24a8b1d2b53b7 - Sigstore transparency entry: 1155184672
- Sigstore integration time:
-
Permalink:
ActivitySmithHQ/activitysmith-python@8a3dc97b4d7dad8eff3fdaa14afb0a784a3397c3 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/ActivitySmithHQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8a3dc97b4d7dad8eff3fdaa14afb0a784a3397c3 -
Trigger Event:
push
-
Statement type: