Apps
Apps are containerized applications you deploy and run on the platform. Use this resource to create an app, upload a code bundle, deploy it, control its lifecycle (start/stop/restart), and watch its status, logs, and metrics.
Access it as client.apps on a Strongly client, or the same path on AsyncStrongly with await. All methods exist on both with identical signatures.
Quick start
from strongly import Strongly
client = Strongly()
# List (auto-paginates as you iterate) # filters: status, environment_id, search
for app in client.apps.list():
print(app.id)
Methods
Core
list
list(*, status: str | None = None, environment_id: str | None = None, search: str | None = None, limit: int | None = None) -> SyncPaginator[App]
List apps with pagination and filtering.
Parameters
status(str | None, optional): Filter by app status.environment_id(str | None, optional): Filter by the runtime environment the app runs in.search(str | None, optional): Search by name or description.limit(int | None, optional): Maximum number of items to return (default: all matching items).
create
create(*, name: str, description: str | None = None, display_name: str | None = None, source_volume_id: str | None = None, source_folder: str | None = None, github_repo_url: str | None = None, github_branch: str | None = None, github_ssh_key_id: str | None = None, github_subdirectory: str | None = None, instances: int | None = None, cpu: str | None = None, memory: str | None = None, disk: str | None = None, gpu: str | None = None, gpu_type: str | None = None, environment_id: str | None = None, environment_variables: Mapping[str, str] | None = None, addons: Sequence[str] | None = None, data_sources: Sequence[str] | None = None, ai_models: Sequence[str] | None = None, ml_models: Sequence[str] | None = None, workflows: Sequence[str] | None = None, feature_stores: Sequence[str] | None = None, agents: Sequence[str] | None = None, volumes: Sequence[str] | None = None, tags: Sequence[str] | None = None) -> App
Create a new app.
An app has no default size: it runs at exactly the size it is given.
Set environment_id (the app runs at that environment's size), or
cpu and memory (disk optional). deploy refuses an app
with neither and names what is missing.
Parameters
name(str): App name.description(str | None, optional): App description.display_name(str | None, optional): Name shown in the UI.source_volume_id(str | None, optional): Build from a volume's code, as last synced (what a workspace's Sync pushes): the volume's ID.source_folder(str | None, optional): The folder of that volume's code holdingstrongly.manifest.yaml; omit for the whole code.github_repo_url(str | None, optional): Build from a GitHub repository instead: its SSH URL (git@github.com:owner/repo.git). Needsgithub_branchandgithub_ssh_key_id.github_branch(str | None, optional): The branch to build.github_ssh_key_id(str | None, optional): The ID of one of your SSH keys (Profile > Integrations) GitHub accepts for the repository.github_subdirectory(str | None, optional): The repository folder holdingstrongly.manifest.yaml; omit for the root.instances(int | None, optional): Number of replicas.cpu(str | None, optional): CPU cores, e.g."0.5","2"or"500m".memory(str | None, optional): Memory, e.g."1GB"or"512MB".disk(str | None, optional): Disk, e.g."10GB".gpu(str | None, optional): Number of GPUs as a string, e.g."1".gpu_type(str | None, optional): GPU type whengpuis set, e.g."nvidia-t4".environment_id(str | None, optional): Runtime environment the app runs in (and at the size of).environment_variables(Mapping[str, str] | None, optional): Environment variables as a name -> value mapping.addons(Sequence[str] | None, optional): Add-on IDs to connect (credentials reach the app throughSTRONGLY_SERVICES).data_sources(Sequence[str] | None, optional): Data source IDs to connect.ai_models(Sequence[str] | None, optional): AI model IDs to connect.ml_models(Sequence[str] | None, optional): Model registry model IDs to connect.workflows(Sequence[str] | None, optional): Deployed workflow IDs the app may trigger.feature_stores(Sequence[str] | None, optional): Feature store IDs the app reads features from.agents(Sequence[str] | None, optional): Deployed agent IDs the app talks to.volumes(Sequence[str] | None, optional): Volume IDs the app mounts: a project's volume you have not shared at/volumes/local/<name>, every shared volume (yours included) at/volumes/shared/<name>;code/read-only,data/read and write, each written file saved as a new version. Needs a disk:disk, or an environment that has one.tags(Sequence[str] | None, optional): Tags.
Returns
App: The newly createdApp.
Raises
ValueError: Both a volume and a GitHub source are given, or a GitHub source without its branch or SSH key.
retrieve
retrieve(app_id: str) -> App
Get a single app by ID.
update
update(app_id: str, *, name: str | None = None, description: str | None = None, display_name: str | None = None, instances: int | None = None, cpu: str | None = None, memory: str | None = None, disk: str | None = None, environment_id: str | None = None, environment_variables: Mapping[str, str] | None = None, addons: Sequence[str] | None = None, data_sources: Sequence[str] | None = None, ai_models: Sequence[str] | None = None, ml_models: Sequence[str] | None = None, workflows: Sequence[str] | None = None, feature_stores: Sequence[str] | None = None, agents: Sequence[str] | None = None, volumes: Sequence[str] | None = None, tags: Sequence[str] | None = None, port: int | None = None) -> App
Update an app's definition.
Sizes are checked as given: cpu must be a number of cores and
memory / disk sizes such as "1GB". List arguments replace
the whole set. A change reaches the running app when it is redeployed
(deploy).
delete
delete(app_id: str) -> None
Delete an app.
Lifecycle & actions
start
start(app_id: str) -> dict[str, Any]
Start an app.
stop
stop(app_id: str) -> dict[str, Any]
Stop an app.
restart
restart(app_id: str) -> dict[str, Any]
Restart an app.
deploy
deploy(app_id: str, **kwargs) -> dict[str, Any]
Deploy an app at exactly its size.
Its environment's size, or the cpu and memory set on it. An app with neither is
refused with a ValidationError naming what is missing; set it with update.
Parameters
app_id(str): The app ID.**kwargs(Any): Optional deployment configuration options.
deploy_upload
deploy_upload(app_id: str, file: str | Path | BinaryIO, **kwargs) -> App
Deploy a zip bundle to an existing app.
Parameters
app_id(str): The app ID.file(str | Path | BinaryIO): Path to a zip file, or a file-like object (opened in binary mode).**kwargs(Any): Additional form fields to include.
Returns
App: The app, its new source building.
Examples
result = client.apps.deploy_upload("app-id", "my-app.zip")
Other
add_member
add_member(resource_id: str, *, user_id: str, role: str) -> Permissions
Share the resource with a user.
Parameters
resource_id(str): The resource's id.user_id(str): The user to share it with.role(str):"editor"(use and change it) or"user"(use it only; types without a use-only tier, such as knowledge bases, take"editor"only).
create_with_upload
create_with_upload(file: str | Path | BinaryIO, *, name: str | None = None, description: str | None = None, framework: str | None = None, runtime: str | None = None, **kwargs) -> App
Create a new app by uploading a zip bundle.
Parameters
file(str | Path | BinaryIO): Path to a zip file, or a file-like object (opened in binary mode).name(str | None, optional): App name. Defaults to the filename without extension.description(str | None, optional): App description.framework(str | None, optional): App framework (e.g."express","react").runtime(str | None, optional): App runtime (e.g."node18").**kwargs(Any): Additional form fields to include.
Returns
App: The new app, with its build.
Examples
app = client.apps.create_with_upload(
"my-app.zip",
name="My App",
description="An awesome app",
)
logs
logs(app_id: str, *, lines: int | None = None, since: str | None = None, container: str | None = None) -> Any
Get app logs.
Parameters
app_id(str): The app ID.lines(int | None, optional): Number of log lines to return.since(str | None, optional): ISO timestamp; return logs after this time.container(str | None, optional): Specific container name.
metrics
metrics(app_id: str) -> dict[str, Any]
Measure a running app now (about 6 seconds).
Returns cpu (usage_millicores, limit_millicores, percent)
and memory (usage_bytes, limit_bytes, percent) against the
app's size summed over replicas, network (receive_bytes_per_second,
transmit_bytes_per_second, total_bytes_per_second,
window_seconds), response_time (avg_ms, min_ms, max_ms,
samples), replicas (ready, total, measured),
containers (every container of every replica with its usage and size,
platform containers marked by role), platform_containers_total
and measured_at. Raises ConflictError (409) when the app is not
running, and an API error with the reason when a measurement fails.
permissions
permissions(resource_id: str) -> Permissions
Return who can reach the resource: its owner, members and their roles, and visibility.
Parameters
resource_id(str): The resource's id.
remove_member
remove_member(resource_id: str, user_id: str) -> None
Stop sharing the resource with a user.
Parameters
resource_id(str): The resource's id.user_id(str): The user to stop sharing it with.
set_visibility
set_visibility(resource_id: str, visibility: str) -> Permissions
Make the resource public (every user can find and use it) or private.
Parameters
resource_id(str): The resource's id.visibility(str):"public"or"private".
status
status(app_id: str) -> AppStatus
Get app deployment status.