Python API

The oblako.services package. Each service is the local counterpart of an AWS service, reached through its normal boto3 client (get_client()) or native driver (connect()). Oblako is the platform handle that owns them all.

Platform

class oblako.services.platform.Oblako[source]

Manage the full oblako service stack.

up()[source]

Start all Docker-managed services.

Return type:

None

down()[source]

Stop all Docker-managed services.

Return type:

None

status()[source]

Return status of user-facing services (infra like moto is hidden).

Return type:

dict[str, str]

wait_ready(timeout=60.0)[source]

Wait for all services to be ready.

Parameters:

timeout (float)

Return type:

dict[str, bool]

AI / ML

class oblako.services.bedrock.BedrockService(host_port=11434, runtime_port=8004, region=None)[source]

Local Amazon Bedrock service powered by Ollama.

Parameters:
  • host_port (int)

  • runtime_port (int)

  • region (str | None)

property url: str

Ollama engine URL.

start()[source]

Start Ollama in a container, unless one already answers on the port.

Return type:

None

status()[source]

Report running when oblako’s container runs or another Ollama answers.

Return type:

ServiceStatus

pull_model(model=None)[source]

Pull a model into the engine (defaults to the small qwen default).

Parameters:

model (str | None)

Return type:

None

list_models()[source]

List locally available models.

Return type:

list[str]

start_runtime_server()[source]

Start the local bedrock-runtime server in-process (idempotent).

get_client(autostart=True)[source]

boto3 bedrock-runtime client backed by Ollama via BedrockAdapter.

Parameters:

autostart (bool)

get_control_client(autostart=True)[source]

boto3 bedrock control-plane client (foundation models, batch jobs).

Parameters:

autostart (bool)

class oblako.services.sagemaker.SageMakerService[source]

Local SageMaker execution: oblako drives Docker directly.

Rather than depending on the SageMaker SDK’s local mode, oblako builds and runs the training/inference containers itself against SageMaker’s /opt/ml contract (see run_training), so it’s independent of the SDK version. This class also manages images, container status, and cleanup, and the Studio domain (composed from CloudFormation + EC2).

property client: docker.DockerClient

Return (or lazily create) the Docker client for the configured backend.

get_session()[source]

Return a SageMaker LocalSession (client helper).

v3 relocated it from sagemaker.local to sagemaker.core.local. oblako’s own execution no longer uses it (see run_training); this stays for client code that wants the SDK’s local session.

get_client()[source]

Return a boto3 sagemaker client wired to the local control plane.

Auto-starts the in-process server (ports.SAGEMAKER) that answers the boto3 sagemaker API and runs training jobs locally in Docker, so unmodified boto3 / SageMaker SDK code targets oblako.

get_runtime_client()[source]

Return a boto3 sagemaker-runtime client wired to the local server.

invoke_endpoint is proxied to the local serving container that create_endpoint started.

get_featurestore_runtime_client()[source]

Return a boto3 sagemaker-featurestore-runtime client (local).

put_record / get_record hit the local Feature Store: an in-process online store plus an S3 Parquet offline store.

build_image(path, tag)[source]

Build a training/inference Docker image.

Parameters:
  • path (str)

  • tag (str)

Return type:

str

run_training(image: str, channels: dict[str, str], hyperparameters: dict | None = None, environment: dict | None = None, gpus: bool = False, timeout: int = 1800, return_logs: Literal[False] = False, on_container=None) → dict[str, bytes][source]
run_training(image: str, channels: dict[str, str], hyperparameters: dict | None = None, environment: dict | None = None, gpus: bool = False, timeout: int = 1800, *, return_logs: Literal[True], on_container=None) → tuple[dict[str, bytes], str]

Run a SageMaker training container per the /opt/ml contract.

oblako drives Docker itself (no SageMaker SDK), so it works the same on Docker Desktop and Linux and doesn’t depend on the SDK’s local mode. Input is copied into the container and the model copied out with the docker cp mechanism (put_archive/get_archive), so there are no host bind-mounts to share.

channels maps a channel name to a local directory whose files are placed under /opt/ml/input/data/<channel>/. hyperparameters is written (values stringified) to /opt/ml/input/config/hyperparameters.json as the container expects. Returns the collected /opt/ml/model as a {relative_path: bytes} map. Raises on a non-zero exit. With return_logs=True returns (files, container_logs) instead, so a caller (e.g. automatic model tuning) can scrape an objective metric from the container’s stdout via a MetricDefinitions regex. on_container, if given, is called with the container right after it is created (before it starts), so a caller can record it and later StopTrainingJob by killing it.

Parameters:
  • image (str)

  • channels (dict[str, str])

  • hyperparameters (dict | None)

  • environment (dict | None)

  • gpus (bool)

  • timeout (int)

  • return_logs (bool)

Return type:

dict[str, bytes] | tuple[dict[str, bytes], str]

list_training_containers()[source]

List running SageMaker local mode containers.

Return type:

list[dict]

list_endpoint_containers()[source]

List running SageMaker local endpoint containers.

Return type:

list[dict]

cleanup()[source]

Remove stopped SageMaker local mode containers.

Return type:

int

image_exists(tag)[source]

Check if a training/inference image exists locally.

Parameters:

tag (str)

Return type:

bool

ensure_notebook_image()[source]

Build oblako’s slim notebook image (JupyterLab + boto3) if it’s absent.

Only builds the bundled image; a custom OBLAKO_NOTEBOOK_IMAGE is left to be pulled by the instance container as usual.

Return type:

str

create_domain(name='studio', instance_type='t3.medium', notebook_port=8889)[source]

Create a Studio domain as a CloudFormation stack (S3 + EC2 + EBS).

The notebook instance is a real container (Jupyter image) publishing JupyterLab on notebook_port. Returns the domain status.

Parameters:
  • name (str)

  • instance_type (str)

  • notebook_port (int)

Return type:

dict

domain_status(name='studio')[source]

Return {domain, stack, status, artifactsBucket, instanceId} (status NONE if absent).

Parameters:

name (str)

Return type:

dict

launch_notebook(name='studio', port=8889)[source]

Run JupyterLab inside the domain’s notebook instance (EBS as home, pre-wired).

boto3 in the kernel hits oblako’s services on the host via host.docker.internal — unmodified AWS code runs against oblako.

Parameters:
  • name (str)

  • port (int)

Return type:

dict

delete_domain(name='studio')[source]

Tear down the domain’s CloudFormation stack (S3 bucket + EC2 + EBS).

Parameters:

name (str)

Return type:

None

class oblako.services.mlflow.MlflowService(host_port=5050, s3_endpoint='http://host.docker.internal:9000')[source]

Local MLflow App container, pre-wired to S3Proxy for artifact storage.

Parameters:
  • host_port (int)

  • s3_endpoint (str)

property tracking_uri: str

Return the direct HTTP URL of the MLflow server (for the web UI).

property tracking_server_arn: str

Return the SageMaker MLflow tracking-server ARN.

This is the value you pass to mlflow.set_tracking_uri — exactly like real SageMaker-managed MLflow. The sagemaker-mlflow plugin resolves it to the server URL (via SAGEMAKER_MLFLOW_CUSTOM_ENDPOINT locally) and SigV4-signs the traffic.

property custom_endpoint: str

Return the value for SAGEMAKER_MLFLOW_CUSTOM_ENDPOINT.

Tells the sagemaker-mlflow plugin where to send tracking traffic when the URI is an ARN — locally, the MLflow container — so the ARN resolves without a SageMaker control plane.

ensure_image()[source]

Build the MLflow image (and slim it if docker-slim is available).

Return type:

None

start()[source]

Build the image (if needed), ensure the artifact bucket, then run.

Return type:

None

Storage & databases

class oblako.services.s3proxy.S3ProxyService(host_port=9000, backend_port=9001, extensions=None)[source]

S3-compatible object storage: S3Proxy, plus tagging and Inventory.

Parameters:
  • host_port (int)

  • backend_port (int)

  • extensions (bool | None)

property endpoint_url: str

Return the S3 endpoint URL.

start()[source]

Start S3Proxy, and with extensions the engine and the :9000 front.

Return type:

None

stop()[source]

Stop the front, the extensions engine and S3Proxy.

Return type:

None

status()[source]

Return RUNNING only when every part is up.

Return type:

ServiceStatus

get_client()[source]

Return a boto3 S3 client pointing at the S3 endpoint.

S3Proxy does not implement botocore’s default flexible checksums (x-amz-checksum-crc32 over aws-chunked), so keep checksum calculation “when_required”; otherwise uploads fail with 501 NotImplemented.

class oblako.services.dynamodb.DynamoDBService(host_port=8001)[source]

DynamoDB Local service backed by the official Amazon Docker image.

Parameters:

host_port (int)

property endpoint_url: str

Return the DynamoDB Local endpoint URL.

get_resource()[source]

Return a boto3 DynamoDB resource for higher-level API.

start()[source]

Start DynamoDB Local, then the proxy that adds vector search and tags.

Return type:

None

get_vector_client()[source]

Return a boto3 dynamodb client for the proxy (vector search, tags).

Starts DynamoDB Local (if needed) and the oblako proxy in front of it. See oblako.engines.dynamodb_vectors.

class oblako.services.kinesis.KinesisService(host_port=4567, shard_limit=100)[source]

Local Kinesis Data Streams (kinesalite-backed).

Parameters:
  • host_port (int)

  • shard_limit (int)

property endpoint_url: str

Return the local Kinesis endpoint URL for boto3 clients.

class oblako.services.redshift.RedshiftService(host_port=5439, user='oblako', password='oblako', database='oblako', control_port=8015, data_port=8002, region=None)[source]

Local Amazon Redshift, backed by the oblako/redshift image.

A bundled wire proxy handles the Redshift-only SQL (physical DDL, varchar(max)) and terminates TLS. libpq clients (psycopg2, JDBC) can use sslmode=require; for redshift_connector (dbt, awswrangler) run oblako trust once per venv to trust the proxy’s cert, then use sslmode=verify-ca. See trust_cert.

Parameters:
  • host_port (int)

  • user (str)

  • password (str)

  • database (str)

  • control_port (int)

  • data_port (int)

  • region (str | None)

connect()[source]

Return a psycopg2 connection straight to the Redshift engine.

server_certs()[source]

Return every TLS cert (PEM) a Redshift proxy on this machine presents.

oblako’s containers, the single-node engine and every node of a multi-node cluster, mount this machine’s cert (ensure_cert), so oblako trust works before anything runs and covers them all. A container started by docker compose makes its own, so a running compose redshift or redshift-coordinator container’s cert is added: both kinds can run on one machine, as in CI.

Return type:

list[str]

trust_cert(python_exe=None)[source]

Trust the proxy’s cert in a venv’s redshift_connector CA bundle.

redshift_connector (and thus dbt-redshift, awswrangler) verifies TLS against a hardcoded Amazon CA bundle with no override, so it can’t verify a local cert out of the box. This appends the proxy’s self-signed cert to that bundle in python_exe’s environment (default: the current one), so sslmode=verify-ca then gives real, verified TLS locally, no ssl=False. Idempotent. A keeper installed in the same venv re-appends the certificates at interpreter start, so the trust survives a redshift-connector reinstall (which restores the pristine bundle). The cert is this machine’s own and cannot sign others (CA:FALSE), so trusting it vouches for nothing else.

oblako certificates no proxy here presents any more (a removed compose container’s, say) are dropped from the bundle and the keeper: OpenSSL finds a trusted self-signed certificate by its subject, and certificates older oblako versions made share one, so a stale one can make it reject the current server.

Parameters:

python_exe (str | None)

Return type:

str

untrust(python_exe=None)[source]

Undo trust_cert: remove the keeper and its certificates from the bundle.

Parameters:

python_exe (str | None)

Return type:

str

start()[source]

Start the engine, then the Redshift API that runs multi-node clusters.

Return type:

None

get_client()[source]

boto3 redshift control-plane client (single-node and multi-node).

start_data_server()[source]

Start the redshift-data server in-process (idempotent). Returns its URL.

get_data_client(autostart=True)[source]

boto3 redshift-data client executing real SQL against the engine.

Parameters:

autostart (bool)

class oblako.services.rds.RdsService(engine='postgres', host_port=None, user='oblako', password='oblako', database='oblako', control_port=8014, data_port=8006, region=None)[source]

Local Amazon RDS and Aurora service backed by a real PostgreSQL or MySQL engine.

Parameters:
  • engine (str)

  • host_port (int | None)

  • user (str)

  • password (str)

  • database (str)

  • control_port (int)

  • data_port (int)

  • region (str | None)

connect()[source]

Return a DB connection to the engine (psycopg2 for postgres, pymysql for mysql).

start()[source]

Start the engine, then the RDS control plane that runs one per DB instance.

Return type:

None

get_client()[source]

boto3 rds control-plane client (RDS instances + Aurora clusters).

seed(instances=None, clusters=None)[source]

Idempotently (re)create RDS instances and Aurora clusters from a spec.

clusters entries may carry an "instances" list of member specs. Each dict is passed through as kwargs to create_db_cluster / create_db_instance. Safe to re-run after a moto restart.

Parameters:
  • instances (list[dict] | None)

  • clusters (list[dict] | None)

Return type:

dict

start_data_server()[source]

Start the rds-data server in-process (idempotent). Returns its URL.

get_data_client(autostart=True)[source]

boto3 rds-data client executing real SQL against the engine.

Parameters:

autostart (bool)

class oblako.services.iceberg.IcebergCatalogService(host_port=8181, s3_endpoint='http://host.docker.internal:9000', warehouse='s3://oblako-iceberg/')[source]

Local Iceberg REST catalog backed by S3Proxy.

Parameters:
  • host_port (int)

  • s3_endpoint (str)

  • warehouse (str)

start()[source]

Start the catalog and create its warehouse bucket if it’s missing.

Return type:

None

ensure_warehouse()[source]

Create the warehouse bucket on S3, where every table’s files go.

The REST catalog places a namespace’s tables under the warehouse, and writes there fail with NoSuchBucket until the bucket exists. Needs S3 running; without it this only says so.

Return type:

None

property endpoint_url: str

REST catalog endpoint that pyiceberg / Spark Iceberg connect to.

Analytics

class oblako.services.trino.TrinoService(host_port=8485)[source]

Local Trino, pre-wired with the Iceberg connector to oblako’s catalog + S3.

Parameters:

host_port (int)

start()[source]

Start the Glue engine (the awsdatacatalog metastore), then Trino.

Return type:

None

property endpoint_url: str

Trino HTTP endpoint (clients submit SQL via /v1/statement).

query(sql, *, catalog=None, schema=None, session=None, timeout=60.0)[source]

Run SQL through Trino’s REST API. Returns {columns, types, rows} or {error}.

catalog/schema set the Trino session defaults (so unqualified table names resolve), the way Athena’s QueryExecutionContext does.

Parameters:
  • sql (str)

  • catalog (str | None)

  • schema (str | None)

  • session (dict[str, str] | None)

  • timeout (float)

Return type:

dict

class oblako.services.glue.GlueService[source]

Per-job Glue 5 runner. Submit a PySpark script, get back logs + exit code.

property client

Return the docker-py client for the configured backend (docker/podman/colima).

ensure_image()[source]

Pull the Glue 5 image (~5 GB) if it isn’t present locally.

Return type:

None

submit_job(script, *, args=None, env=None, timeout=1200)[source]

Run a PySpark script in a Glue 5 container.

Returns {exit_code, logs, stdout, stderr}: logs is both streams together, and the split matches Glue’s two CloudWatch log groups (the script’s own output in /aws-glue/jobs/output, Spark’s in /error).

The script is written to a tempdir mounted at /scripts/job.py. The container is given creds + endpoints to reach oblako’s S3Proxy and Iceberg REST catalog at host.docker.internal, and an S3A interceptor that strips the one header S3Proxy can’t handle (see _INTERCEPTOR_CLASS).

Parameters:
  • script (str)

  • args (list[str] | None)

  • env (dict[str, str] | None)

  • timeout (int)

Return type:

dict

run_workflow(name, steps, *, timeout=600)[source]

Run a Glue workflow: a sequential pipeline of PySpark job steps.

Each step is {name, script}. Steps run in order, and a step runs only if every prior step SUCCEEDED — mirroring a Glue CONDITIONAL trigger gated on predecessor success. The first failure stops the pipeline; the rest are marked SKIPPED. Returns {name, status, steps:[{name, status, exitCode, logs}]}.

This covers the common sequential-ETL workflow from Python. The Glue API (CreateWorkflow, CreateTrigger, StartWorkflowRun) runs full graphs: conditional, scheduled and on-demand triggers, jobs and crawlers.

Parameters:
  • name (str)

  • steps (list[dict])

  • timeout (int)

Return type:

dict

class oblako.services.glue_catalog.GlueCatalogService(port=8486)[source]

Local Glue Data Catalog (boto3 glue) bridged to the Iceberg REST catalog.

Parameters:

port (int)

property endpoint_url: str

Endpoint URL boto3 clients connect to.

start_server()[source]

Start the in-process Glue-API shim (idempotent).

Return type:

str

get_client(autostart=True)[source]

Return a boto3 glue client (auto-starts the shim if it isn’t running).

Parameters:

autostart (bool)

Orchestration, compute & management

class oblako.services.stepfunctions.StepFunctionsService(host_port=8083, lambda_endpoint='http://host.docker.internal:3001')[source]

Step Functions Local service backed by the official Amazon image.

Parameters:
  • host_port (int)

  • lambda_endpoint (str)

write_mock_config(config)[source]

Write the SFN Local mock configuration to the mounted file (hot-reloaded).

Parameters:

config (dict)

Return type:

None

start()[source]

Seed the mock config from the bundled ML templates, then start the container.

Return type:

None

property endpoint_url: str

Return the Step Functions Local endpoint URL.

create_state_machine(name, definition, role_arn='arn:aws:iam::123456789012:role/DummyRole')[source]

Create a state machine and return its ARN.

Parameters:
  • name (str)

  • definition (dict)

  • role_arn (str)

Return type:

str

execute(state_machine_arn, input_data)[source]

Start an execution and return the execution ARN.

Parameters:
  • state_machine_arn (str)

  • input_data (dict)

Return type:

str

class oblako.services.awslambda.LambdaService(moto)[source]

AWS Lambda — control plane + invocation via moto + Docker.

Parameters:

moto (MotoService)

property endpoint_url: str

Moto serves Lambda at the same endpoint as every other AWS API.

get_iam_client()[source]

boto3 IAM client pointed at moto (for the exec role).

ensure_exec_role(name='oblako-lambda-exec')[source]

Create (idempotent) and return the ARN of the default Lambda exec role.

Parameters:

name (str)

Return type:

str

ensure_runtime_image(runtime, architecture='x86_64')[source]

Pre-pull the runtime image for a given architecture (linux/amd64 or linux/arm64).

Real AWS Lambda defaults to x86_64. On Apple Silicon, Docker would pull the native arm64 manifest, which breaks layers built with x86_64 wheels (numpy, pandas, etc.). We pull the platform we want explicitly — moto then picks up the local image tag without caring about its arch.

Uses the official AWS Lambda images (Amazon Linux 2023, glibc 2.34) so modern wheels work — matches what MOTO_DOCKER_LAMBDA_IMAGE is set to in the moto container.

Parameters:
  • runtime (str)

  • architecture (str)

Return type:

None

start()[source]

Bring moto up if it isn’t already (no own container).

Return type:

None

stop()[source]

No-op — moto owns the lifecycle.

Return type:

None

wait_ready(timeout=5.0)[source]

Defer readiness to moto.

Parameters:

timeout (float)

Return type:

bool

status()[source]

Defer status to moto.

Return type:

str

class oblako.services.opensearch.OpenSearchService(host_port=9200)[source]

OpenSearch service for vector search and RAG Knowledge Bases.

Parameters:

host_port (int)

property url: str

Return the OpenSearch base URL.

create_knn_index(index_name, dimension=1536)[source]

Create a k-NN vector index (for RAG / Knowledge Bases).

Parameters:
  • index_name (str)

  • dimension (int)

Return type:

dict

class oblako.services.cloudformation.CloudFormationService(port=8017, region=None)[source]

Manage the in-process CloudFormation server and hand out boto3 clients.

Parameters:
  • port (int)

  • region (str | None)

property endpoint_url: str

Return the HTTP endpoint URL for the local CloudFormation server.

start_server()[source]

Start the CloudFormation server in-process (idempotent). Returns its URL.

Return type:

str

get_client(autostart=True)[source]

boto3 cloudformation client whose stacks provision into oblako.

Parameters:

autostart (bool)

is_running()[source]

Return True if the local CloudFormation server is already listening.

Return type:

bool

class oblako.services.iam.IamService(moto=None)[source]

IAM/STS control plane (moto) plus oblako’s trust + authorization evaluator.

Parameters:

moto (MotoService | None)

property endpoint_url: str

Return the moto endpoint that backs the IAM/STS control plane.

create_user(name)[source]

Create an IAM user and return its description.

Parameters:

name (str)

Return type:

dict

create_role(name, trust_policy)[source]

Create an IAM role with the given trust policy and return its description.

Parameters:
  • name (str)

  • trust_policy (dict)

Return type:

dict

create_policy(name, document)[source]

Create a customer-managed policy and return its description.

Parameters:
  • name (str)

  • document (dict)

Return type:

dict

attach_role_policy(role_name, policy_arn)[source]

Attach a managed policy to a role.

Parameters:
  • role_name (str)

  • policy_arn (str)

Return type:

None

attach_user_policy(user_name, policy_arn)[source]

Attach a managed policy to a user.

Parameters:
  • user_name (str)

  • policy_arn (str)

Return type:

None

gather_statements(principal_arn)[source]

Collect all identity-policy statements (managed + inline) for a user/role ARN.

Parameters:

principal_arn (str)

Return type:

list

authorize(principal_arn, action, resource)[source]

Return Allow/Deny/ImplicitDeny for the principal doing action on resource.

Parameters:
  • principal_arn (str)

  • action (str)

  • resource (str)

Return type:

str

assume_role(role_arn, principal_arn, session_name='oblako-session')[source]

Evaluate the role’s trust policy, then sts:AssumeRole if the principal is allowed.

Parameters:
  • role_arn (str)

  • principal_arn (str)

  • session_name (str)

Return type:

dict

class oblako.services.ec2.Ec2Service(moto)[source]

AWS EC2 — moto control plane + container-backed instances.

Parameters:

moto (MotoService)

property endpoint_url: str

Moto serves EC2 at the same endpoint as every other AWS API.

run_instance(image_id='ami-0abcdef1234567890', instance_type='t3.micro', *, backed=True, **kwargs)[source]

Launch one instance: record it in moto, then back it with a container.

Returns the InstanceId. backed=False records control-plane metadata only (no container) — useful when Docker isn’t available.

Parameters:
  • image_id (str)

  • instance_type (str)

  • backed (bool)

Return type:

str

stop_instance(instance_id)[source]

Stop the instance (moto -> stopped; container stopped, EBS volume kept).

Parameters:

instance_id (str)

Return type:

None

start_instance(instance_id)[source]

Start a stopped instance (moto -> running; container started).

Parameters:

instance_id (str)

Return type:

None

terminate_instance(instance_id)[source]

Terminate the instance (moto -> terminated; container + EBS volume removed).

Parameters:

instance_id (str)

Return type:

None

instance_container(instance_id)[source]

Return the backing container (or None if the instance isn’t backed).

Parameters:

instance_id (str)

list_instance_containers()[source]

All oblako EC2 instance containers (running or stopped).

Return type:

list

start()[source]

Bring moto up if it isn’t already (no own service container).

Return type:

None

stop()[source]

No-op — moto owns the control plane; instances are managed per-id.

Return type:

None

wait_ready(timeout=5.0)[source]

Defer readiness to moto.

Parameters:

timeout (float)

Return type:

bool

status()[source]

Defer status to moto.

class oblako.services.ecs.EcsService(moto, elbv2=None)[source]

AWS ECS, moto control plane + real container-backed Fargate tasks.

Parameters:

moto (MotoService)

property endpoint_url: str

Moto serves ECS at the same endpoint as every other AWS API.

register_task_definition(**kwargs)[source]

Register a task definition in moto, returning its ARN.

Return type:

str

run_task(task_definition, *, cluster='default', count=1, launch_type='FARGATE', backed=True, service_name=None, network_configuration=None)[source]

Launch count real containers for task_definition.

Reads the task definition from moto, runs each container on the backend with oblako’s endpoint env + host gateway, and publishes the first port mapping of each container on a host port. Returns a RunTask-shaped dict whose containers[].networkBindings carry the assigned host ports. backed=False records nothing real, just the metadata shape. service_name labels the containers so a service can reconcile them.

For awsvpc task definitions oblako attaches a moto ENI (with a private IP) to each task so describe_tasks shows a faithful attachment, the container still runs on the bridge network. network_configuration is honoured when given, else oblako auto-fills the default-VPC subnet (the same lenient-local default the load balancer uses), rather than raising the AWS “network configuration must be provided” error.

Parameters:
  • task_definition (str)

  • cluster (str)

  • count (int)

  • launch_type (str)

  • backed (bool)

  • service_name (str | None)

  • network_configuration (dict | None)

Return type:

dict

create_service(*, service_name, task_definition, cluster='default', desired_count=1, launch_type='FARGATE', load_balancers=None, network_configuration=None)[source]

Run desired_count tasks and register them as ALB targets.

load_balancers mirrors the ECS API: a list of {"targetGroupArn", "containerName", "containerPort"}. Each task’s published host port for that container is registered into the target group, so the load balancer routes to the real containers. network_configuration is passed through to the tasks (awsvpc).

Parameters:
  • service_name (str)

  • task_definition (str)

  • cluster (str)

  • desired_count (int)

  • launch_type (str)

  • load_balancers (list[dict] | None)

  • network_configuration (dict | None)

Return type:

dict

delete_service(service_name, cluster='default')[source]

Stop every task container of a service (idempotent).

Parameters:
  • service_name (str)

  • cluster (str)

Return type:

None

describe_tasks(cluster='default', tasks=None)[source]

Reflect real container state back as ECS task descriptions.

One entry per task, with each container’s name, status and exit code; a task is RUNNING while any of its containers runs, then STOPPED, as on ECS.

Parameters:
  • cluster (str)

  • tasks (list[str] | None)

Return type:

dict

list_tasks(cluster='default')[source]

Task ARNs of all oblako ECS task containers in the cluster.

Parameters:

cluster (str)

Return type:

list[str]

stop_task(task)[source]

Stop and remove every container of a task (idempotent).

Parameters:

task (str)

Return type:

None

task_url(task)[source]

Reachable URL for a task’s first published port, or None.

Parameters:

task (str)

Return type:

str | None

start()[source]

Bring moto up if it isn’t already (no own service container).

Return type:

None

stop()[source]

No-op: moto owns the control plane; tasks are managed per-arn.

Return type:

None

wait_ready(timeout=5.0)[source]

Defer readiness to moto.

Parameters:

timeout (float)

Return type:

bool

status()[source]

Defer status to moto.

class oblako.services.elbv2.Elbv2Service(moto)[source]

Application Load Balancer, moto control plane + a real Caddy proxy per LB.

Parameters:

moto (MotoService)

property endpoint_url: str

Moto serves ELBv2 at the same endpoint as every other AWS API.

create_load_balancer(**kwargs)[source]

Record the LB in moto and assign it a host listener port.

Subnets are optional locally: if omitted, moto’s default-VPC subnets are used, so the caller doesn’t have to know any subnet IDs.

Return type:

dict

create_target_group(**kwargs)[source]

Record the target group in moto and track its health-check path.

VpcId is optional locally: the default VPC is used when omitted.

Return type:

dict

create_listener(**kwargs)[source]

Record the listener in moto and map its LB to the forwarded target group.

Return type:

dict

register_targets(target_group_arn, host_ports)[source]

Register ECS-task host ports as targets and refresh the proxy.

Parameters:
  • target_group_arn (str)

  • host_ports (list[int])

Return type:

None

deregister_targets(target_group_arn, host_ports)[source]

Remove targets and refresh the proxy.

Parameters:
  • target_group_arn (str)

  • host_ports (list[int])

Return type:

None

dns_name(lb_arn)[source]

Return the local hostname for an LB, so http://<DNSName> is curlable.

Parameters:

lb_arn (str)

Return type:

str

lb_url(lb_arn)[source]

Full URL for the load balancer.

Parameters:

lb_arn (str)

Return type:

str

delete_load_balancer(lb_arn)[source]

Remove the proxy container, the moto LB, and forget it (idempotent).

Parameters:

lb_arn (str)

Return type:

None

start()[source]

Bring moto up if it isn’t already (no own service container).

Return type:

None

stop()[source]

No-op: moto owns the control plane; proxies are managed per-LB.

Return type:

None

wait_ready(timeout=5.0)[source]

Defer readiness to moto.

Parameters:

timeout (float)

Return type:

bool

status()[source]

Defer status to moto.

class oblako.services.appconfig.AppConfigService(port=8003)[source]

Local AppConfig + AppConfigData, served by the in-process engine.

Parameters:

port (int)

property endpoint_url: str

Endpoint URL boto3 clients connect to.

start_server()[source]

Start the in-process AppConfig server (idempotent). Returns its URL.

Return type:

str

get_client(autostart=True)[source]

boto3 appconfig management client (applications, profiles, versions…).

Parameters:

autostart (bool)

get_data_client(autostart=True)[source]

boto3 appconfigdata client (StartConfigurationSession / GetLatestConfiguration).

Parameters:

autostart (bool)

get_agent(autostart=True)[source]

Return the bundled AppConfigClient agent, wired to oblako, for flag evaluation.

Parameters:

autostart (bool)

Container backends

The lifecycle layer behind every service: Docker, Apple container, or Kubernetes (selected with OBLAKO_CONTAINER_BACKEND).

Pluggable container backend so oblako isn’t hard-wired to Docker.

Service (see base.py) drives containers through a ContainerBackend instead of calling docker-py directly. Docker, Podman, and Colima all speak the Docker Engine API, so they share DockerBackend — the only difference is which socket it talks to (honoured via DOCKER_HOST or auto-detected per runtime). Kubernetes is a genuinely different control plane, so it gets its own backend, as does Apple’s container (macOS 26+), which has no Docker-API socket.

Select with OBLAKO_CONTAINER_BACKEND = docker (default) | podman | colima | kubernetes | apple. DOCKER_HOST always wins for the Docker-API runtimes.

class oblako.services.backends.ContainerBackend[source]

Minimal container lifecycle interface a Service needs.

ensure_image(image)[source]

Pull the image if it is not present locally.

Parameters:

image (str)

Return type:

None

build_image(image, context_dir)[source]

Build an oblako-owned image from a Dockerfile context.

Parameters:
  • image (str)

  • context_dir (str)

Return type:

None

run(*, name, image, ports, environment, volumes, extra_hosts, command, working_dir, user)[source]

Create and start a detached container with the given spec.

Return type:

None

status(name)[source]

Return RUNNING, STOPPED, or ABSENT for the named container.

Parameters:

name (str)

Return type:

str

remove(name)[source]

Force-remove the container if present.

Parameters:

name (str)

Return type:

None

stop(name)[source]

Stop and remove the container (no-op if absent).

Parameters:

name (str)

Return type:

None

logs(name, tail=50)[source]

Return the container’s recent logs.

Parameters:
  • name (str)

  • tail (int)

Return type:

str

class oblako.services.backends.DockerBackend(base_url=None)[source]

Docker Engine API backend — also serves Podman and Colima via their sockets.

Parameters:

base_url (str | None)

property client

Lazily create the docker-py client, honouring DOCKER_HOST or the active context.

ensure_image(image)[source]

Pull the image if it is not already present.

Parameters:

image (str)

Return type:

None

build_image(image, context_dir)[source]

Build an image from a Dockerfile context (skips if already present).

Parameters:
  • image (str)

  • context_dir (str)

Return type:

None

run(*, name, image, ports, environment, volumes, extra_hosts, command, working_dir, user)[source]

Create and start a detached container.

Return type:

None

status(name)[source]

Return RUNNING/STOPPED/ABSENT for the container.

Parameters:

name (str)

Return type:

str

remove(name)[source]

Force-remove the container if present.

Parameters:

name (str)

Return type:

None

stop(name)[source]

Stop and remove the container (no-op if absent).

Parameters:

name (str)

Return type:

None

logs(name, tail=50)[source]

Return recent logs, or empty string if the container is gone.

Parameters:
  • name (str)

  • tail (int)

Return type:

str

class oblako.services.backends.KubernetesBackend(namespace=None, kubectl='kubectl')[source]

Run oblako services as Kubernetes workloads (e.g. on minikube), via kubectl.

Each Service maps to a Deployment + Service; kubectl port-forward binds localhost:host_port to the in-cluster Service so oblako’s boto3 clients work unchanged. Port-forwards live as long as the oblako process — after a restart, re-run start (or restart) on a service to re-establish them.

Parameters:
  • namespace (str | None)

  • kubectl (str)

ensure_image(image)[source]

No image pre-pull: the cluster pulls it (use minikube image load for local images).

Parameters:

image (str)

Return type:

None

run(*, name, image, ports, environment, volumes, extra_hosts, command, working_dir, user)[source]

Apply a Deployment + Service, wait for it, and port-forward each port.

Return type:

None

status(name)[source]

Return RUNNING/STOPPED/ABSENT from the deployment’s ready replicas.

Parameters:

name (str)

Return type:

str

remove(name)[source]

Delete the Deployment + Service and stop its port-forwards.

Parameters:

name (str)

Return type:

None

stop(name)[source]

Stop the service (delete its workload + port-forwards).

Parameters:

name (str)

Return type:

None

logs(name, tail=50)[source]

Return recent logs from the deployment’s pods.

Parameters:
  • name (str)

  • tail (int)

Return type:

str

class oblako.services.backends.AppleContainerBackend[source]

Apple container backend (macOS 26+): Linux containers in lightweight VMs.

Shells out to the container CLI (there is no Python SDK). Each container runs in its own VM with an IP on a vmnet subnet, but -p host:container publishes to localhost exactly like Docker — so oblako’s fixed-endpoint contract holds unchanged. Two adaptations vs Docker: named volumes are mapped to host dirs (the CLI bind-mounts host paths), and since there is no host.docker.internal / –add-host, env values referencing it are rewritten to the vmnet gateway.

ensure_image(image)[source]

Pre-pull the image (best effort; container run also auto-pulls).

Parameters:

image (str)

Return type:

None

build_image(image, context_dir)[source]

Build an image from a Dockerfile context via container build.

Parameters:
  • image (str)

  • context_dir (str)

Return type:

None

run(*, name, image, ports, environment, volumes, extra_hosts, command, working_dir, user)[source]

Create and start a detached container via container run.

Return type:

None

status(name)[source]

Return RUNNING/STOPPED/ABSENT from container ls –format json.

Parameters:

name (str)

Return type:

str

remove(name)[source]

Force-remove the container if present.

Parameters:

name (str)

Return type:

None

stop(name)[source]

Stop and remove the container (no-op if absent).

Parameters:

name (str)

Return type:

None

logs(name, tail=50)[source]

Return recent container logs, or empty string if unavailable.

Parameters:
  • name (str)

  • tail (int)

Return type:

str