Metadata-Version: 2.5
Name: apex-core
Version: 0.15.16
Summary: Multi-Cloud Infrastructure Orchestration Platform (Alpha - Not Production Ready)
Project-URL: Homepage, https://sarala.ai
Author-email: Sarala <team@sarala.ai>
License-Expression: PolyForm-Small-Business-1.0.0
License-File: LICENSE
License-File: THIRD_PARTY_NOTICES
Keywords: aws,azure,cloud,gcp,infrastructure,kubernetes,orchestration
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.11
Requires-Dist: faiss-cpu>=1.13.2
Requires-Dist: fastmcp>=3.1.1
Requires-Dist: langchain-community>=0.4.1
Requires-Dist: langchain-core>=1.2.20
Requires-Dist: langchain-mcp-adapters>=0.2.2
Requires-Dist: langchain-ollama>=1.0.1
Requires-Dist: langgraph-checkpoint-sqlite>=3.0.0
Requires-Dist: langgraph>=1.1.3
Requires-Dist: packaging>=23.0
Requires-Dist: pydantic>=2.12.0
Requires-Dist: pynacl>=1.5.0
Requires-Dist: pyopenssl>=24.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: agent
Requires-Dist: click>=8.0.0; extra == 'agent'
Requires-Dist: faiss-cpu>=1.9.0; extra == 'agent'
Requires-Dist: langchain-community>=0.4.0; extra == 'agent'
Requires-Dist: langchain-ollama>=1.0.0; extra == 'agent'
Requires-Dist: rich>=13.0.0; extra == 'agent'
Provides-Extra: all
Requires-Dist: azure-identity>=1.12.0; extra == 'all'
Requires-Dist: azure-mgmt-compute>=29.0.0; extra == 'all'
Requires-Dist: azure-mgmt-network>=25.0.0; extra == 'all'
Requires-Dist: azure-mgmt-resource>=23.0.0; extra == 'all'
Requires-Dist: black>=23.0.0; extra == 'all'
Requires-Dist: boto3>=1.26.0; extra == 'all'
Requires-Dist: botocore>=1.29.0; extra == 'all'
Requires-Dist: click>=8.0.0; extra == 'all'
Requires-Dist: cloud-sql-python-connector[pg8000]>=1.12.0; extra == 'all'
Requires-Dist: google-auth>=2.16.0; extra == 'all'
Requires-Dist: google-cloud-compute>=1.11.0; extra == 'all'
Requires-Dist: google-cloud-storage>=2.7.0; extra == 'all'
Requires-Dist: isort>=5.12.0; extra == 'all'
Requires-Dist: kubernetes>=25.0.0; extra == 'all'
Requires-Dist: mypy>=1.0.0; extra == 'all'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27.0; extra == 'all'
Requires-Dist: opentelemetry-sdk>=1.27.0; extra == 'all'
Requires-Dist: pre-commit>=3.0.0; extra == 'all'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'all'
Requires-Dist: pytest-cov>=4.0.0; extra == 'all'
Requires-Dist: pytest>=7.0.0; extra == 'all'
Requires-Dist: rich>=13.0.0; extra == 'all'
Provides-Extra: all-providers
Requires-Dist: azure-identity>=1.12.0; extra == 'all-providers'
Requires-Dist: azure-mgmt-compute>=29.0.0; extra == 'all-providers'
Requires-Dist: azure-mgmt-network>=25.0.0; extra == 'all-providers'
Requires-Dist: azure-mgmt-resource>=23.0.0; extra == 'all-providers'
Requires-Dist: boto3>=1.26.0; extra == 'all-providers'
Requires-Dist: botocore>=1.29.0; extra == 'all-providers'
Requires-Dist: google-auth>=2.16.0; extra == 'all-providers'
Requires-Dist: google-cloud-compute>=1.11.0; extra == 'all-providers'
Requires-Dist: google-cloud-storage>=2.7.0; extra == 'all-providers'
Requires-Dist: kubernetes>=25.0.0; extra == 'all-providers'
Provides-Extra: aws
Requires-Dist: boto3>=1.26.0; extra == 'aws'
Requires-Dist: botocore>=1.29.0; extra == 'aws'
Provides-Extra: azure
Requires-Dist: azure-identity>=1.12.0; extra == 'azure'
Requires-Dist: azure-mgmt-compute>=29.0.0; extra == 'azure'
Requires-Dist: azure-mgmt-network>=25.0.0; extra == 'azure'
Requires-Dist: azure-mgmt-resource>=23.0.0; extra == 'azure'
Provides-Extra: chat
Requires-Dist: click>=8.0.0; extra == 'chat'
Requires-Dist: langchain-ollama>=1.0.0; extra == 'chat'
Requires-Dist: rich>=13.0.0; extra == 'chat'
Provides-Extra: chat-all
Requires-Dist: click>=8.0.0; extra == 'chat-all'
Requires-Dist: httpx>=0.24.0; extra == 'chat-all'
Requires-Dist: langchain-anthropic>=0.1.0; extra == 'chat-all'
Requires-Dist: langchain-community>=0.1.0; extra == 'chat-all'
Requires-Dist: langchain-ollama>=0.3.10; extra == 'chat-all'
Requires-Dist: langchain-openai>=0.1.0; extra == 'chat-all'
Requires-Dist: llama-cpp-python>=0.3.16; extra == 'chat-all'
Requires-Dist: rich>=13.0.0; extra == 'chat-all'
Provides-Extra: chat-cloud
Requires-Dist: click>=8.0.0; extra == 'chat-cloud'
Requires-Dist: httpx>=0.24.0; extra == 'chat-cloud'
Requires-Dist: langchain-anthropic>=0.1.0; extra == 'chat-cloud'
Requires-Dist: langchain-openai>=0.1.0; extra == 'chat-cloud'
Requires-Dist: rich>=13.0.0; extra == 'chat-cloud'
Provides-Extra: chat-local
Requires-Dist: click>=8.0.0; extra == 'chat-local'
Requires-Dist: langchain-community>=0.1.0; extra == 'chat-local'
Requires-Dist: llama-cpp-python>=0.3.16; extra == 'chat-local'
Requires-Dist: rich>=13.0.0; extra == 'chat-local'
Provides-Extra: cli
Requires-Dist: click>=8.0.0; extra == 'cli'
Requires-Dist: rich>=13.0.0; extra == 'cli'
Provides-Extra: databricks
Requires-Dist: databricks-sdk>=0.101.0; extra == 'databricks'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.0.0; extra == 'docs'
Requires-Dist: mkdocs>=1.4.0; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.20.0; extra == 'docs'
Provides-Extra: gcp
Requires-Dist: cloud-sql-python-connector[pg8000]>=1.12.0; extra == 'gcp'
Requires-Dist: google-auth>=2.16.0; extra == 'gcp'
Requires-Dist: google-cloud-compute>=1.11.0; extra == 'gcp'
Requires-Dist: google-cloud-storage>=2.7.0; extra == 'gcp'
Provides-Extra: kubernetes
Requires-Dist: kubernetes>=25.0.0; extra == 'kubernetes'
Provides-Extra: mlflow
Requires-Dist: mlflow>=3.10.1; extra == 'mlflow'
Provides-Extra: otel
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27.0; extra == 'otel'
Requires-Dist: opentelemetry-sdk>=1.27.0; extra == 'otel'
Provides-Extra: portal
Requires-Dist: alembic>=1.13; extra == 'portal'
Requires-Dist: pandas<3.0,>=2.0.0; extra == 'portal'
Requires-Dist: psycopg2-binary>=2.9; extra == 'portal'
Requires-Dist: sqlalchemy>=2.0; extra == 'portal'
Requires-Dist: streamlit-ace>=0.1.1; extra == 'portal'
Requires-Dist: streamlit-agraph>=0.0.45; extra == 'portal'
Requires-Dist: streamlit>=1.42.0; extra == 'portal'
Provides-Extra: test-ui
Requires-Dist: altair>=5.2.0; extra == 'test-ui'
Requires-Dist: pandas<3.0,>=2.1.0; extra == 'test-ui'
Requires-Dist: plotly>=5.18.0; extra == 'test-ui'
Requires-Dist: streamlit>=1.30.0; extra == 'test-ui'
Provides-Extra: ui
Requires-Dist: streamlit>=1.35.0; extra == 'ui'
Description-Content-Type: text/markdown

# APEX Platform

**Multi-Cloud Infrastructure Orchestration with YAML Workflows**

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: PolyForm Small Business 1.0.0](https://img.shields.io/badge/License-PolyForm%20Small%20Business%201.0.0-blue.svg)](https://polyformproject.org/licenses/small-business/1.0.0)

APEX is a local-first CLI and MCP tool for orchestrating cloud infrastructure with declarative YAML workflows, state interpolation, and execution planning. Built safety-first: **plan / dry-run mode by default, no accidental infrastructure changes**.

APEX is complementary to Terraform, not a replacement — some workflows even wrap the `terraform` CLI.

## Key Features

- **YAML workflows** — declarative, list-based `steps:` with state interpolation (`${step.output}`)
- **DSL control flow** — step-level `retry` + `timeout_seconds` (a timed-out mutating step is not retried unless it opts in), `for_each` fan-out, and `run_when` failure/cleanup edges
- **Safety first** — plan by default; real changes require explicit opt-in. For GCP create and IAM tools a plan reads the live resource and reports `unchanged` / `create` / `update` / `recreate_required`
- **Opt-in remote state** — local SQLite by default, with optional GCS-backed run-record sync (`apex state sync`)
- **MCP-native** — exposes tools over the Model Context Protocol (FastMCP) for IDE / agent callers
- **Agent mode** — `--output json` for machine-readable, non-TTY output
- **DevTools workflows** — CI dispatch/watch/triage and a dogfooded release pipeline

## Provider Support

| Provider | Status | Servers / Tools | Notes |
|----------|--------|-----------------|-------|
| **GCP** | **Mature — integration-tested against real GCP** | 15 servers / 128 tools | Most-developed provider; shells out to `gcloud` / `bq` / `firebase` CLIs |
| **AWS** | Maintained | ~19 servers / 176 tools | boto3-based; not the primary focus |
| **Azure** | Framework only | 0 working tools | Config/placeholder — **not usable yet** |
| **Kubernetes** | Framework only | 0 working tools | Config/placeholder — **not usable yet** |
| Docker, MLflow, Databricks, Terraform | CLI/subprocess based | — | Wrap the respective CLIs |

GCP is the primary, most-built provider. Its 15 resource servers cover: artifact_registry, bigquery, cloud_run, cloud_sql, firebase, iam, identity_platform, inventory, networking, org_policy, project, pubsub, redis, secret_manager, and storage. The `tests/integration/gcp/` suite runs in CI against a scratch GCP project.

DevTools resource servers ship alongside the cloud providers: `test_runner`, `code_quality`, `health_check`, `validation`, `ci_runs` (GitHub Actions dispatch/watch/triage), and `release_ops` (release preflight + git tag/push).

## Quick Start

### Installation

```bash
# Using uv (recommended)
uv pip install apex-core[gcp]

# Using pip
pip install apex-core[gcp]

# For development
git clone https://github.com/sarala-ai/apex-core
cd apex-core
uv sync --group dev --extra gcp
```

### Run a workflow

Workflows use a list-based `steps:` format. Each step names a resource server (`server_type`), a `tool_name`, and `parameters`. Outputs from earlier steps are referenced with `${...}` interpolation.

```yaml
name: publish_python_package
version: "1.0"
description: "Build and publish a Python package to GCP Artifact Registry"

inputs:
  project_id:
    type: string
    required: true
  repo_name:
    type: string
    required: true
  location:
    type: string
    required: true

entry_point: ensure_repo

steps:
  - name: ensure_repo
    server_type: gcp_artifact_registry
    tool_name: create_repository
    parameters:
      project_id: "${project_id}"
      repository: "${repo_name}"
      location: "${location}"
      format: "python"
    # Bootstrap steps can retry through eventual-consistency lags:
    retry:
      max_attempts: 3
      delay_seconds: 5
      backoff_multiplier: 2
    timeout_seconds: 120
```

A step that times out is killed and fails. Because the cloud operation behind a killed CLI call may still be running, a mutating tool is not retried after a timeout unless the step sets `retry.retry_on_timeout: true`.

Preview, plan, then apply:

```bash
# Print the steps, tools and parameters (reads no cloud state)
apex plan workflows/gcp/publish-python-package.yml

# Plan against live GCP (default mode, writes nothing; needs credentials)
apex run workflow run --workflow workflows/gcp/publish-python-package.yml \
  --params '{"project_id":"my-project","repo_name":"my-packages","location":"us-central1"}'

# Apply against real GCP (opt-in)
apex run workflow run --workflow workflows/gcp/publish-python-package.yml \
  --params '{"project_id":"my-project","repo_name":"my-packages","location":"us-central1"}' \
  --execution-mode apply
```

The `apex` CLI is the primary interface. Key commands:

```
apex --version   # Print the installed apex-core version
apex init        # Initialize an APEX-aware project from a natural-language brief
apex plan        # Print the steps of a workflow without running it
apex run workflow run  # Plan (default) or apply (--execution-mode apply) a workflow
apex run         # Execute resource-server tools directly
apex docs        # Browse the guidance and guides that ship with the package
apex workflows   # List and show the workflow catalog
apex state       # Manage run-record state (sync / list / pull)
apex validate    # Validate resource-server configs and workflow DSL
apex mcp         # Start the MCP server for IDE integration
```

The full command tree is in [docs/guidance/reference/cli.md](docs/guidance/reference/cli.md).

AWS workflows run the same way (`server_type: aws_vpc`, `aws_ecs`, …) using boto3-backed servers.

## DSL Control Flow

**Step-level retry and timeout** (spec 018) — retry eventual-consistency-prone steps and bound their runtime:

```yaml
- name: enable_apis
  server_type: gcp_project
  tool_name: enable_apis
  retry: { max_attempts: 3, delay_seconds: 5, backoff_multiplier: 2 }
  timeout_seconds: 300
```

**`for_each` fan-out** (spec 019) — iterate a step over a dynamic input list instead of hand-numbered `resource_1..resource_N`:

```yaml
- name: create_buckets
  server_type: gcp_storage
  tool_name: create_bucket
  for_each: "${bucket_names}"
  parameters:
    name: "${item}"
```

**`run_when` failure-condition edges** (spec 020) — declarative error / cleanup branching:

```yaml
- name: rollback_notice
  server_type: health_check
  tool_name: notify
  run_when: { step: deploy, condition: failed }
```

## State Management

State is **local-first** (SQLite) by default. `apex state sync` opts a project into a GCS-backed run-record backend (git-like: push local records to a bucket, read them back elsewhere). This is opt-in per project via `.apex/settings.yaml`:

```yaml
state_sync:
  backend: gcs
  bucket: gs://my-apex-state
  prefix: apex
```

```bash
apex state sync            # push instance records / plan specs / audit logs to the bucket
apex state list --source remote   # list run records in the remote bucket
apex state pull            # read remote records back locally
```

This is a local-first store with an optional remote — not a distributed state store or a server.

## Safety Features

All operations default to **plan mode**. No real infrastructure is created or changed without an explicit `--execution-mode apply` (or equivalent opt-in).

A plan is not an offline simulation for GCP. Create and IAM tools (clusters, node pools, projects, service accounts, IAM bindings, custom roles, billing links, API enablement) read the live resource and report the action apply would take: `unchanged`, `create`, `update`, `add`, `remove`, or `recreate_required`. Planning them needs read access, a read that fails fails the plan, and a step APEX cannot see ends `unverified` and exits 1. Other tools return a preview without contacting the cloud. See [plan semantics](docs/guidance/reference/plan-semantics.md) and [read-first tools](docs/guidance/reference/read-first-tools.md).

> **Scope honesty:** APEX does not run a continuous drift-detection or reconciliation loop (read-first GCP tools compare live state to a step at plan and apply time, nothing more), and executed rollback against a real cloud is not proven (LIFO rollback ordering exists in the DSL model only). It is not a Terraform replacement, and it is not a multi-tenant / SaaS / web service — it is a local-first CLI + MCP tool.

## Testing

```bash
# Unit tests
pytest tests/unit/

# GCP integration suite (requires a scratch GCP project + credentials)
pytest tests/integration/gcp/
```

- Unit tests run on every pull request
- The GCP integration suite runs in CI against a scratch GCP project
- Coverage is enforced in CI

## Documentation

- [APEX White Paper](docs/APEX_WHITE_PAPER.md)
- [Documentation Map](docs/DOCUMENTATION_MAP.md)
- [CLI reference](docs/guidance/reference/cli.md)
- [Self-hosting guide](docs/guides/self-host.md)
- [Workflow DSL](docs/dsl/README.md)
- [Contributing Resource Servers](docs/CONTRIBUTING_RESOURCE_SERVERS.md)
- [Contributing](CONTRIBUTING.md)

## Contributing

Contributions welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) and [docs/CONTRIBUTING_RESOURCE_SERVERS.md](docs/CONTRIBUTING_RESOURCE_SERVERS.md) for how to add resource servers, testing requirements, and the PR process.

## Project Status

- **Version**: see `apex --version` and the [CHANGELOG](CHANGELOG.md)
- **Python**: 3.11+
- **Status**: Active development — GCP-first, local-first CLI + MCP tool

v0.4.0 is the first release shipped via APEX's own dogfooded `apex-release` workflow (APEX releasing APEX to GCP Artifact Registry).

## License

PolyForm Small Business License 1.0.0 — see [LICENSE](LICENSE) for details.

Free for individuals and for organizations with fewer than 100 people and under $1M USD annual revenue. Larger organizations need a commercial license — contact the maintainers.

## Acknowledgments

Built with:
- [FastMCP](https://github.com/jlowin/fastmcp) — Model Context Protocol integration
- [Pydantic](https://pydantic-docs.helpmanual.io/) — data validation
- [boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html) — AWS SDK

---

**Note:** APEX runs in **plan / dry-run mode by default**. Real infrastructure changes require explicit opt-in and correctly configured cloud credentials.
