Skip to main content

acme-portal-sdk

Important: This SDK is currently in alpha and primarily for demonstration purposes. APIs may still change frequently.

Overview

acme-portal-sdk is a Python SDK that provides data and actions for the acme-portal VSCode extension. It standardizes the deployment workflow for Python applications that implement "flows" (Jobs/DAGs/Workflows) while allowing full customization of the underlying implementation.

AI wiki

Main Idea

Rather than embedding pre-defined deployment logic in the VSCode extension, the SDK allows you to define custom sources of data and behavior. The extension serves as a UI layer to your SDK implementations, providing a consistent interface for:

  • Discovering flows in your codebase
  • Managing deployments across environments
  • Promoting deployments between environments (dev → staging → prod)

The SDK defines abstract interfaces that you implement according to your project's needs, whether using Prefect, Airflow, GitHub Actions, or custom deployment systems.

Quick Start

To set up your project with acme-portal-sdk, create a .acme_portal_sdk directory in your project root with these files:

1. Install the SDK

pip install acme_portal_sdk

2. Create SDK Configuration Files

mkdir .acme_portal_sdk

.acme_portal_sdk/flow_finder.py

from acme_portal_sdk.flow_finder import FlowFinder, FlowDetails
from pathlib import Path
from typing import List
import ast
import os

class MyCustomFlowFinder(FlowFinder):
    """Custom implementation to find flows in your codebase."""
    
    def __init__(self, root_dir: str):
        self.root_dir = Path(root_dir)
    
    def find_flows(self) -> List[FlowDetails]:
        """Find flows by scanning Python files for flow decorators."""
        flows = []
        
        for py_file in self.root_dir.rglob("*.py"):
            if py_file.is_file():
                try:
                    with open(py_file, 'r') as f:
                        tree = ast.parse(f.read())
                    
                    for node in ast.walk(tree):
                        if isinstance(node, ast.FunctionDef):
                            # Look for @flow decorator or similar patterns
                            for decorator in node.decorator_list:
                                if isinstance(decorator, ast.Name) and decorator.id == 'flow':
                                    flows.append(FlowDetails(
                                        name=node.name,
                                        original_name=node.name,
                                        description=ast.get_docstring(node) or "",
                                        obj_type="function",
                                        obj_name=node.name,
                                        obj_parent_type="module",
                                        obj_parent=py_file.stem,
                                        id=f"{py_file.stem}.{node.name}",
                                        module=py_file.stem,
                                        source_path=str(py_file),
                                        source_relative=str(py_file.relative_to(self.root_dir)),
                                        import_path=f"{py_file.stem}",
                                        grouping=[py_file.parent.name]
                                    ))
                except Exception:
                    continue
        
        return flows

# Create an instance to find flows in your project
project_root = Path(__file__).parent.parent
flow_finder = MyCustomFlowFinder(
    root_dir=str(project_root / "src" / "your_project_name")
)

.acme_portal_sdk/deployment_finder.py

from acme_portal_sdk.deployment_finder import DeploymentFinder, DeploymentDetails
from typing import List
import requests

class MyCustomDeploymentFinder(DeploymentFinder):
    """Custom implementation to find existing deployments."""
    
    def __init__(self, api_base_url: str = "https://your-deployment-api.com"):
        self.api_base_url = api_base_url
    
    def get_deployments(self) -> List[DeploymentDetails]:
        """Fetch deployments from your deployment API."""
        try:
            response = requests.get(f"{self.api_base_url}/deployments")
            response.raise_for_status()
            
            deployments = []
            for data in response.json():
                deployments.append(DeploymentDetails(
                    name=data["name"],
                    project_name=data["project"],
                    branch=data["branch"],
                    flow_name=data["flow_name"],
                    env=data["environment"],
                    commit_hash=data["commit_hash"],
                    package_version=data.get("version", "unknown"),
                    tags=data.get("tags", []),
                    id=data["id"],
                    created_at=data["created_at"],
                    updated_at=data["updated_at"],
                    flow_id=data["flow_id"],
                    url=data["url"]
                ))
            
            return deployments
        except Exception:
            return []

# Find existing deployments from your API
deployment_finder = MyCustomDeploymentFinder()

.acme_portal_sdk/flow_deploy.py

from acme_portal_sdk.flow_deploy import DeployWorkflow
from typing import Any, Optional
import subprocess

class MyCustomDeployWorkflow(DeployWorkflow):
    """Custom implementation for deploying flows."""
    
    def __init__(self, deploy_script: str = "scripts/deploy.sh"):
        self.deploy_script = deploy_script
    
    def run(self, *args: Any, **kwargs: Any) -> Optional[str]:
        """Deploy flows using custom deployment script."""
        try:
            flows_to_deploy = kwargs.get("flows_to_deploy", [])
            env = kwargs.get("env", "dev")
            branch_name = kwargs.get("branch_name", "main")
            
            # Build deployment command
            cmd = [
                "bash", self.deploy_script,
                "--flows", ",".join(flows_to_deploy),
                "--env", env,
                "--branch", branch_name
            ]
            
            # Execute deployment
            result = subprocess.run(cmd, capture_output=True, text=True)
            
            if result.returncode == 0:
                # Return deployment URL if available in output
                return result.stdout.strip()
            else:
                print(f"Deployment failed: {result.stderr}")
                return None
                
        except Exception as e:
            print(f"Deployment error: {e}")
            return None

# Deploy flows using custom script
deploy = MyCustomDeployWorkflow(deploy_script="scripts/deploy.sh")

.acme_portal_sdk/deployment_promote.py

from acme_portal_sdk.deployment_promote import PromoteWorkflow
from typing import Any, Optional
import subprocess

class MyCustomPromoteWorkflow(PromoteWorkflow):
    """Custom implementation for promoting deployments between environments."""
    
    def __init__(self, promote_script: str = "scripts/promote.sh"):
        self.promote_script = promote_script
    
    def run(self, *args: Any, **kwargs: Any) -> Optional[str]:
        """Promote deployments using custom promotion script."""
        try:
            flows_to_deploy = kwargs.get("flows_to_deploy", [])
            source_env = kwargs.get("source_env", "dev")
            target_env = kwargs.get("target_env", "prod")
            project_name = kwargs.get("project_name", "")
            
            # Build promotion command
            cmd = [
                "bash", self.promote_script,
                "--flows", ",".join(flows_to_deploy),
                "--from", source_env,
                "--to", target_env,
                "--project", project_name
            ]
            
            # Execute promotion
            result = subprocess.run(cmd, capture_output=True, text=True)
            
            if result.returncode == 0:
                # Return promotion URL if available in output
                return result.stdout.strip()
            else:
                print(f"Promotion failed: {result.stderr}")
                return None
                
        except Exception as e:
            print(f"Promotion error: {e}")
            return None

# Promote deployments using custom script
promote = MyCustomPromoteWorkflow(promote_script="scripts/promote.sh")

3. Install VSCode Extension

Install the acme-portal VSCode extension to get the UI interface for managing your flows and deployments.

Documentation

Example Projects

Development

For detailed development setup, contribution guidelines, and release notes process, see CONTRIBUTING.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

acme_portal_sdk-1.0.0.tar.gz (27.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

acme_portal_sdk-1.0.0-py3-none-any.whl (33.7 kB view details)

Uploaded Python 3

File details

Details for the file acme_portal_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: acme_portal_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 27.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.8.11

File hashes

Hashes for acme_portal_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 9985848125af96d4f7be346c3ba7bd89c72571876654a30582a46ea024d35a9d
MD5 39bfa2699bbfe0b3fa414b66f780f980
BLAKE2b-256 1b8359b606ee447b9949217096279aba48bbf74ff156b85b08042fdbfc611ab7

See more details on using hashes here.

File details

Details for the file acme_portal_sdk-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for acme_portal_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 20806ca84dd7100cd6fdfdfe1026bba6e42b87387f41936af1adbe57981ea1ed
MD5 53f383e3ce4cb1a8d60a478f8d974433
BLAKE2b-256 4d1cf274323fbe64302fd8745544cd587c66458ed01b670283cd9554515ef686

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page