mule-analysis
Analyze Mule application estates — call graphs, frequency analysis, and curl extraction.
Scans Mule 4 (and 3) XML source files, resolves ${property} placeholders from .properties and .yaml configs, and produces structured output in multiple formats.
Quick Start (uv)
No install required — just run from the project directory:
cd mule-analysis
# Extract curl commands from a Mule app
uv run mule-curl-extract /path/to/apps -r
# Frequency analysis
uv run mule-call-frequency /path/to/apps
# Call graph
uv run mule-call-graph /path/to/apps --format dot -o graph.dot
uv run reads pyproject.toml, resolves dependencies into an ephemeral environment, and runs the command. Nothing is installed globally.
Installation
From PyPI
pip install mule-analysis
# Then run directly
mule-curl-extract /path/to/apps -r
From source (development)
uv sync --extra dev
Requires Python 3.10+.
CLI Tools
mule-curl-extract
Extract outbound HTTP/SOAP calls from Mule apps and generate ready-to-run curl commands.
# Scan a single Mule app
uv run mule-curl-extract /path/to/mule-app
# Scan all apps under a directory
uv run mule-curl-extract /path/to/apps --recursive
# Output as YAML
uv run mule-curl-extract /path/to/apps -r --format yaml
# Write to file
uv run mule-curl-extract /path/to/apps -r -o curls.sh
Resolves ${property} and p('property') placeholders, extracts basic/bearer auth, and converts DataWeave transform bodies into sample JSON for curl -d flags.
mule-call-frequency
Analyze call frequency across a Mule application estate.
# Text report (default)
uv run mule-call-frequency /path/to/apps
# YAML output
uv run mule-call-frequency /path/to/apps --format yaml -o report.yaml
# Custom layer classification
uv run mule-call-frequency /path/to/apps --layer-config layers.yaml
Reports include:
- App inventory with layer classification (experience / process / system)
- Backend system frequency (which systems are called, how often)
- Inter-app call graph (EL → PL → SL)
- Endpoint hotspots (called from multiple apps/flows)
- Shared sub-flow usage
mule-call-graph
Generate a machine-readable call graph of app-to-app and app-to-backend connections.
# Mermaid (default) — renders in GitHub, GitLab, Notion
uv run mule-call-graph /path/to/apps
# Graphviz DOT — render with: dot -Tpng graph.dot -o graph.png
uv run mule-call-graph /path/to/apps --format dot -o graph.dot
# JSON adjacency list
uv run mule-call-graph /path/to/apps --format json -o graph.json
# CSV edge list
uv run mule-call-graph /path/to/apps --format csv -o edges.csv
# Mule-to-Mule only (exclude external backends)
uv run mule-call-graph /path/to/apps --mule-only
# Custom layer classification
uv run mule-call-graph /path/to/apps --layer-config layers.yaml
Package Structure
src/mule_analysis/
├── xml_helpers.py # XML namespace helpers, constants
├── models/ # Data models (dataclasses)
│ ├── app.py # MuleApp
│ ├── backend.py # BackendConfig, HttpRequest, SoapCall
│ ├── graph.py # Node, Edge, CallGraph
│ └── frequency.py # FrequencyReport, EndpointHotspot, ...
├── parsers/ # File IO → models
│ ├── app_discovery.py # find_mule_apps()
│ ├── properties.py # .properties + .yaml loading & resolution
│ └── mule_xml.py # HTTP configs, requests, WSC from Mule XML
├── analysis/ # Models → models (pure functions)
│ ├── layer_classifier.py # App name → experience/process/system (configurable)
│ ├── curl_generator.py # BackendConfig + HttpRequest → curl string
│ ├── frequency.py # Multi-app frequency aggregation
│ └── graph_builder.py # Multi-app call graph construction
├── output/ # Models → formatted strings
│ ├── curl_output.py # Shell script with curl commands
│ ├── yaml_output.py # YAML
│ ├── text_output.py # Human-readable tables
│ ├── dot_output.py # Graphviz DOT
│ ├── mermaid_output.py # Mermaid flowchart
│ ├── csv_output.py # CSV edge list
│ └── json_output.py # JSON
└── cli/ # CLI entry points (thin wrappers)
├── curl_extract.py # mule-curl-extract
├── call_frequency.py # mule-call-frequency
└── call_graph.py # mule-call-graph
Design Principles
- No function does both IO and computation. Parsers read files → return models. Analysis takes models → returns models. Output takes models → returns strings.
- All data models are plain dataclasses with typed fields — no methods with side effects.
- All analysis functions are standalone — no class methods, no inheritance.
- Each output format is a separate module.
Testing
make test
Or directly:
uv run --extra dev python -m pytest
Coverage is enforced at 100% (branch coverage) via pyproject.toml.
Layer Classification
Apps are classified into experience/process/system layers by splitting the app name on - and _ and matching segments against known abbreviations.
Default Segments
| Segment | Layer |
|---|---|
el, exp, eapi, xapi, experience |
Experience |
pl, prc, papi, process |
Process |
sl, sys, sapi, system |
System |
This means all of these classify correctly out of the box:
acme-el-orders → experience (segment: el)
acme-exp-api → experience (segment: exp)
orders-eapi → experience (segment: eapi)
acme-pl-orders → process (segment: pl)
customers-prc-svc → process (segment: prc)
orders-papi → process (segment: papi)
acme-sl-billing → system (segment: sl)
customers-sys-api → system (segment: sys)
billing-sapi → system (segment: sapi)
Inter-app calls are detected by matching CloudHub hostnames (mule-worker-internal-{env}-{app}-{version}.cloudhub.io) and ALB patterns (mu-alb-{layer}.).
Custom Configuration
Override the defaults by passing a --layer-config YAML file to mule-call-frequency or mule-call-graph:
uv run mule-call-graph /path/to/apps --layer-config layers.yaml
Example layers.yaml:
# Override layer segment keywords (split on - and _)
layers:
experience: [web, frontend, ui]
process: [orch, bpm, workflow]
system: [db, adapter, connector]
# Override CloudHub hostname patterns (regex with capture group)
hostname_patterns:
- 'mule-worker-(?:internal-)?(?:\\w{2,5}-)(.+?)-\\d+-\\d+\\.'
- 'mu-alb-(\\w+)\\.'
# Override external backend hostname indicators
external_indicators:
- oracle
- salesforce
- sap
Any section can be omitted to keep the defaults for that section. For example, to only add custom layer segments while keeping the default hostname patterns:
layers:
experience: [el, exp, eapi, xapi, experience, web]
process: [pl, prc, papi, process, orch]
system: [sl, sys, sapi, system, db]
Metadata
Release files for mule-analysis 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mule_analysis-1.0.0.tar.gz | 83.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mule_analysis-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 118.0 kB
Release files / mule_analysis-1.0.0.tar.gz
| Download URL | mule_analysis-1.0.0.tar.gz |
|---|---|
| Size | 83.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7b852a3c205439247a93d5fbd9a925694b7b0eb68a3bd9664d70aaad311e5df0
|
|
BLAKE2b-256 checksum How to use checksums |
79eaf8133b7c7cb5925fa52a3e34bc7b74776db5e966b1d639bf579cb9404209
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mule_analysis-1.0.0-py3-none-any.whl
| Download URL | mule_analysis-1.0.0-py3-none-any.whl |
|---|---|
| Size | 34.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
43784713e228e330c8bd2c48af580049da5652a75a96cd9e0020351bda9aa55d
|
|
BLAKE2b-256 checksum How to use checksums |
8825310f243db0a5413d70e526b978a11d1d58fcc7c1cd83faacc661304c669b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mule-analysis 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.