Addons & Data Sources
Provision managed infrastructure services and connect to external data.
Overview
Strongly provides two complementary resources for data connectivity:
- Addons (
client.addons) -- Managed database and service instances (PostgreSQL, Redis, MySQL, etc.) provisioned and run inside the Strongly platform. You control their lifecycle, resources, backups, and access. - Data Sources (
client.datasources) -- Connections to external databases and services that live outside Strongly. Register credentials, test connectivity, and discover schemas.
Addons
Basic Usage
from strongly import Strongly
client = Strongly()
# List all addons
for addon in client.addons.list():
print(f"{addon.label} ({addon.type}) — {addon.status}")
# Create a PostgreSQL addon
addon = client.addons.create({
"label": "analytics-db",
"type": "postgresql",
"cpu": "500m",
"memory": "1Gi",
"disk": "10Gi",
"description": "Analytics database for dashboards",
})
print(f"Addon ID: {addon.id}")
print(f"Status: {addon.status}")
Creating an Addon
from strongly import Strongly
client = Strongly()
addon = client.addons.create({
"label": "cache-prod",
"type": "redis",
"cpu": "250m",
"memory": "512Mi",
"disk": "2Gi",
"description": "Production caching layer",
"version": "7.2",
"environment": "production",
"tier": "standard",
"config": {
"maxmemory-policy": "allkeys-lru",
},
})
print(f"Created: {addon.label} ({addon.id})")
Create Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
label | str | Yes | Display name for the addon |
type | str | Yes | Service type (postgresql, mysql, redis, mongodb, etc.) |
cpu | str | Yes | CPU allocation (e.g., 500m, 1) |
memory | str | Yes | Memory allocation (e.g., 1Gi, 512Mi) |
disk | str | Yes | Disk allocation (e.g., 10Gi) |
description | str | No | Human-readable description |
version | str | No | Service version (e.g., 16 for PostgreSQL) |
environment | str | No | Target environment (e.g., production, staging) |
tier | str | No | Service tier |
config | dict | No | Service-specific configuration options |
Getting Credentials
After an addon is running, retrieve its connection credentials:
from strongly import Strongly
client = Strongly()
creds = client.addons.credentials("addon-abc123")
print(f"Host: {creds.host}")
print(f"Port: {creds.port}")
print(f"Username: {creds.username}")
print(f"Password: {creds.password}")
print(f"Database: {creds.database}")
print(f"Connection string: {creds.connection_string}")
AddonCredentials Fields
| Field | Type | Description |
|---|---|---|
host | str | Hostname or IP address |
port | int | Port number |
username | str | Login username |
password | str | Login password |
database | str | Default database name |
connection_string | str | Full connection URI |
Using Credentials with Libraries
from strongly import Strongly
import psycopg2
client = Strongly()
creds = client.addons.credentials("addon-abc123")
# Connect using the connection string
conn = psycopg2.connect(creds.connection_string)
cursor = conn.cursor()
cursor.execute("SELECT version()")
print(cursor.fetchone())
conn.close()
Addon Lifecycle
from strongly import Strongly
client = Strongly()
addon_id = "addon-abc123"
# Stop a running addon
client.addons.stop(addon_id)
# Start a stopped addon
client.addons.start(addon_id)
# Restart an addon
client.addons.restart(addon_id)
# Recover a failed addon
client.addons.recover(addon_id)
Status and Monitoring
from strongly import Strongly
client = Strongly()
addon_id = "addon-abc123"
# Check status
status = client.addons.status(addon_id)
print(status)
# View metrics
metrics = client.addons.metrics(addon_id)
print(metrics)
# View logs
logs = client.addons.logs(addon_id, lines=50)
print(logs)
Backups
from strongly import Strongly
client = Strongly()
addon_id = "addon-abc123"
# Trigger a manual backup
client.addons.backup(addon_id)
# Configure automatic backups
client.addons.update_backup_config(addon_id, {
"enabled": True,
"schedule": "0 2 * * *", # Daily at 2:00 AM
"retention": 7, # Keep 7 backups
})
Connecting Addons to Apps
Link an addon to an application so the app receives the addon's credentials as environment variables:
from strongly import Strongly
client = Strongly()
# Connect addon to app
client.addons.connect_app("addon-abc123", "app-xyz789")
# Disconnect addon from app
client.addons.disconnect_app("addon-abc123", "app-xyz789")
Filtering and Searching
from strongly import Strongly
client = Strongly()
# Filter by type
for addon in client.addons.list(type="postgresql"):
print(f"{addon.label} — {addon.status}")
# Filter by status
for addon in client.addons.list(status="running"):
print(addon.label)
# Search by name
for addon in client.addons.list(search="analytics"):
print(addon.label)
# Combine filters
running_pg = client.addons.list(type="postgresql", status="running")
for addon in running_pg:
print(f"{addon.label}: {addon.cpu} CPU, {addon.memory} memory")
Addon Model
| Field | Type | Description |
|---|---|---|
id | str | Unique addon identifier |
label | str | Display name |
type | str | Service type (postgresql, redis, etc.) |
status | str | Current status |
description | str | Human-readable description |
version | str | Service version |
environment | str | Target environment |
tier | str | Service tier |
cpu | str | CPU allocation |
memory | str | Memory allocation |
disk | str | Disk allocation |
organization_id | str | Owning organization |
owner | str | Owner user ID |
config | dict | Service-specific configuration |
created_at | str | Creation timestamp |
updated_at | str | Last update timestamp |
Addons Method Reference
| Method | Description | Returns |
|---|---|---|
list(*, search=None, type=None, status=None, environment=None, limit=50) | List addons with optional filters | SyncPaginator[Addon] |
create(body) | Create a new addon | Addon |
retrieve(addon_id) | Get an addon by ID | Addon |
update(addon_id, body) | Update addon fields | Addon |
delete(addon_id) | Delete an addon | dict |
start(addon_id) | Start a stopped addon | dict |
stop(addon_id) | Stop a running addon | dict |
restart(addon_id) | Restart an addon | dict |
recover(addon_id) | Recover a failed addon | dict |
status(addon_id) | Get addon status | dict |
credentials(addon_id) | Get connection credentials | AddonCredentials |
metrics(addon_id) | Get resource usage metrics | dict |
logs(addon_id, *, lines=None, since=None, container=None) | Retrieve addon logs | Any |
backup(addon_id) | Trigger a manual backup | dict |
update_backup_config(addon_id, body) | Configure automatic backups | dict |
connect_app(addon_id, app_id) | Connect addon to an app | dict |
disconnect_app(addon_id, app_id) | Disconnect addon from an app | dict |
update_permissions(addon_id, body) | Update access permissions | dict |
Data Sources
Data sources represent connections to databases and services that live outside the Strongly platform. Register your external PostgreSQL, MySQL, S3, or API endpoints, then test connectivity and discover schemas.
Basic Usage
from strongly import Strongly
client = Strongly()
# List all data sources
for ds in client.datasources.list():
print(f"{ds.label} ({ds.type}) — {ds.status}")
Creating a Data Source
from strongly import Strongly
client = Strongly()
ds = client.datasources.create({
"name": "warehouse-pg",
"label": "Data Warehouse",
"type": "postgresql",
"description": "Central analytics warehouse",
"category": "database",
"credentials": {
"host": "warehouse.example.com",
"port": 5432,
"username": "readonly_user",
"password": "s3cret",
"database": "analytics",
},
"metadata": {
"department": "data-engineering",
},
})
print(f"Data Source ID: {ds.id}")
Create Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
name | str | Yes | Unique identifier name |
label | str | Yes | Display name |
type | str | Yes | Connection type (postgresql, mysql, mongodb, s3, etc.) |
credentials | dict | Yes | Connection credentials (host, port, username, password, etc.) |
description | str | No | Human-readable description |
category | str | No | Grouping category (e.g., database, storage, api) |
metadata | dict | No | Custom key-value metadata |
Testing a Connection
Verify that credentials are valid and the target is reachable:
from strongly import Strongly
client = Strongly()
result = client.datasources.test_connection("ds-abc123")
print(result)
# {"success": True, "message": "Connection successful", "latency_ms": 42}
Discovering Schema
Retrieve table and schema metadata from a connected data source:
from strongly import Strongly
client = Strongly()
meta = client.datasources.metadata("ds-abc123")
for table in meta.get("tables", []):
print(f"Table: {table['name']}")
for col in table.get("columns", []):
print(f" {col['name']} ({col['type']})")
Getting Credentials
Retrieve the stored credentials for a data source:
from strongly import Strongly
client = Strongly()
creds = client.datasources.credentials("ds-abc123")
print(creds)
Filtering and Searching
from strongly import Strongly
client = Strongly()
# Filter by type
for ds in client.datasources.list(type="postgresql"):
print(ds.label)
# Filter by category
for ds in client.datasources.list(category="database"):
print(f"{ds.label} ({ds.type})")
# Search by name
for ds in client.datasources.list(search="warehouse"):
print(ds.label)
DataSource Model
| Field | Type | Description |
|---|---|---|
id | str | Unique data source identifier |
name | str | Unique identifier name |
label | str | Display name |
type | str | Connection type |
category | str | Grouping category |
status | str | Connection status |
description | str | Human-readable description |
organization_id | str | Owning organization |
owner | str | Owner user ID |
permissions | dict | Access permissions |
metadata | dict | Custom metadata |
created_at | str | Creation timestamp |
updated_at | str | Last update timestamp |
Data Sources Method Reference
| Method | Description | Returns |
|---|---|---|
list(*, search=None, type=None, category=None, status=None, limit=50) | List data sources with optional filters | SyncPaginator[DataSource] |
create(body) | Register a new data source | DataSource |
retrieve(datasource_id) | Get a data source by ID | DataSource |
update(datasource_id, body) | Update data source fields | DataSource |
delete(datasource_id) | Delete a data source | dict |
test_connection(datasource_id) | Test connectivity | dict |
metadata(datasource_id) | Discover tables and schemas | dict |
credentials(datasource_id) | Get stored credentials | dict |
update_permissions(datasource_id, body) | Update access permissions | dict |
Complete Example
from strongly import Strongly
import time
def main():
client = Strongly()
# --- Provision a managed PostgreSQL addon ---
print("Creating PostgreSQL addon...")
addon = client.addons.create({
"label": "app-database",
"type": "postgresql",
"cpu": "500m",
"memory": "1Gi",
"disk": "10Gi",
"description": "Primary database for the app",
"version": "16",
})
print(f"Addon ID: {addon.id}")
# Wait for addon to be ready
while True:
status = client.addons.status(addon.id)
print(f" Status: {status}")
if status.get("status") == "running":
break
time.sleep(5)
# Get credentials
creds = client.addons.credentials(addon.id)
print(f"\nConnection string: {creds.connection_string}")
# Configure backups
client.addons.update_backup_config(addon.id, {
"enabled": True,
"schedule": "0 3 * * *",
"retention": 14,
})
print("Backups configured.")
# --- Register an external data source ---
print("\nRegistering external data source...")
ds = client.datasources.create({
"name": "legacy-warehouse",
"label": "Legacy Data Warehouse",
"type": "mysql",
"category": "database",
"credentials": {
"host": "db.legacy.example.com",
"port": 3306,
"username": "reader",
"password": "readonly-pass",
"database": "warehouse",
},
"description": "Read-only access to legacy warehouse",
})
ds_id = ds.id
print(f"Data Source ID: {ds_id}")
# Test the connection
result = client.datasources.test_connection(ds_id)
print(f"Connection test: {result}")
# Discover schema
meta = client.datasources.metadata(ds_id)
tables = meta.get("tables", [])
print(f"Found {len(tables)} tables")
for table in tables[:5]:
print(f" - {table['name']}")
# --- Summary ---
print("\n--- All Addons ---")
for a in client.addons.list():
print(f" {a.label} ({a.type}) — {a.status}")
print("\n--- All Data Sources ---")
for d in client.datasources.list():
print(f" {d.label} ({d.type}) — {d.status}")
if __name__ == "__main__":
main()