Skip to main content

dxp-analyzer-doc

Analyze TIBCO Spotfire .dxp dashboards and assess their migration to Power BI (with Databricks as the data back-end).

A .dxp file is a ZIP archive of XML documents. dxp-analyzer-doc walks that structure and produces:

  • a structured inventory (pages, visuals, IronPython/JavaScript scripts, data functions, document properties, calculated columns, custom queries, source tables, connections) exported as .xlsx (or .csv);
  • a migration assessment: every Spotfire capability mapped to its Power BI / Databricks equivalent and classified as native, workaround or not native;
  • a normalized complexity index (0–100) and a migration effort estimate (person-days, min / likely / max);
  • a migration document in Markdown with a pros/cons synthesis per dashboard.

Output language is selectable: English (default) or Italian (--lang it).

Italiano: libreria per analizzare dashboard Spotfire .dxp e valutarne la migrazione a Power BI. Output in inglese (default) o italiano (--lang it).

Install

pip install -e .            # no dependencies; tables are written as .csv

The migration document is always Markdown (.md). Tables default to .csv (;-separated, UTF-8-BOM so Excel opens them directly). If you prefer .xlsx output instead, add the optional extra:

pip install -e ".[xlsx]"    # pulls in openpyxl for .xlsx tables

Command line

# Inventory tables + extracted code files
dxp-analyzer-doc analyze dashboard.dxp -o out --lang en

# Migration document (Markdown) for one or many dashboards
dxp-analyzer-doc document a.dxp b.dxp -o migration.md --lang it

# Both, for every .dxp in a folder
dxp-analyzer-doc all ./dashboards -o out

files accepts .dxp files, glob patterns, or directories (all *.dxp inside). Add --extract-archive to also unpack the raw .dxp contents.

Output location. By default the output is written next to the input .dxp files, not in the current working directory: analyze/all create <input folder>/dxp-output/, and document writes <input folder>/migration_documentation.md. A relative -o also resolves under the input folder; pass an absolute -o to write anywhere.

Python API

from dxp_analyzer_doc import analyze, assess, build_report

# 1. Structured inventory
result = analyze("dashboard.dxp")
print(len(result.pages), result.total_visuals, len(result.scripts))

# 2. Migration assessment (complexity + effort + capability mapping)
a = assess("dashboard.dxp")
print(a.score.index, a.score.level)        # e.g. 42.5 "medium"
print(a.effort.min_days, a.effort.likely_days, a.effort.max_days)

# 3. Markdown migration document (one or many assessments)
md = build_report([a], lang="it")

Export helpers:

from dxp_analyzer_doc.export import export_result, write_summary
export_result(result, "out/dashboard", lang="en")
write_summary([result], "out", lang="en")

The complexity & effort model

The complexity index does not sum raw counts. It groups the incidence variables into five normalized dimensions, each mapped to 0..1 with a saturating function so no single factor can dominate, then combines them with configurable weights into a 0–100 index:

Dimension What it captures Weight
Breadth / size pages, total visuals, text areas 0.15
Data model source tables, custom queries (weighted by difficulty), calculated columns, data functions 0.20
Custom code IronPython/JavaScript scripts and their lines 0.25
Interactivity text-area controls, user properties, workaround visuals 0.15
Migration gap non-native features/visuals, workarounds, reworked columns 0.25

Levels: Low ≤ 25, Medium ≤ 50, High ≤ 75, Very high > 75.

Effort estimate (parametric)

The effort is returned in person-days with a min/likely/max band, from a single parametric formula with diminishing returns:

effort = base + score_coeff · index
       + Σ coeff_i · ln(1 + n_i)            # generic drivers (scripts, data functions, non-native features, …)
       + q_easy · ln(1 + n_easy)            # easy custom queries (diminishing)
       + q_medium · ln(1 + n_medium)        # medium custom queries (diminishing)
       + q_complex · n_complex              # complex custom queries (linear)

ln (natural log) means the 10th script costs less than the 1st. Custom queries are classified as easy / medium / complex (see below), and every complex query adds a linear cost, because a complex query implies the underlying semantic model has to be decomposed. Defaults: base=0.5, score_coeff=0.05, scripts=0.5, data_functions=0.9, non_native_features=1.2, q_easy=0.4, q_medium=0.8, q_complex=1.5.

Every coefficient is overridable:

from dxp_analyzer_doc import ComplexityModel, ParametricEffortConfig, assess

model = ComplexityModel(parametric_effort=ParametricEffortConfig(
    score_coeff=0.06, query_complex_coeff=2.0,
    log_coeffs={"scripts": 0.5, "data_functions": 1.0, "non_native_features": 1.2},
))
a = assess("dashboard.dxp", model=model)
print(a.effort.min_days, a.effort.likely_days, a.effort.max_days)

Custom query classification

Each custom query behind the data model is scored (dependency-free SQL heuristics: joins, subqueries, CTEs, window functions, conditions, group-by, aggregations, length, …) and bucketed into easy / medium / complex. The level drives both the effort (above) and the data_model dimension of the index. Thresholds and weights live in QueryComplexityConfig:

from dxp_analyzer_doc import ComplexityModel, QueryComplexityConfig
from dxp_analyzer_doc.migration import classify_query

level, score, metrics = classify_query("SELECT a FROM t JOIN u ON t.id = u.id")
model = ComplexityModel(query_config=QueryComplexityConfig(easy_max=2, medium_max=6))

Migration rules

The Spotfire→Power BI mapping lives in dxp_analyzer_doc/migration/rules.py (bilingual). Each rule is a regex over scripts/expressions/properties plus its Power BI and Databricks guidance. Add or tune rules there.

Project layout

src/dxp_analyzer_doc/
  analyzer.py        # DxpAnalyzer: the .dxp parsing engine
  model.py           # AnalysisResult and its dataclasses
  export.py          # xlsx/csv tables + extracted files
  i18n.py            # en/it string catalog
  migration/
    rules.py            # bilingual Spotfire -> Power BI rules
    complexity.py       # normalized index + parametric effort model
    query_complexity.py # SQL custom-query difficulty classifier
    assessment.py       # DashboardAssessment
    report.py           # Markdown migration document
  cli.py             # dxp-analyzer-doc command
legacy/              # original standalone scripts (reference only)
tests/               # pytest suite + synthetic .dxp

Development

pip install -e ".[dev]"
pytest -q

The test suite builds a synthetic .dxp (see tests/_sample.py) and exercises the full pipeline in both languages.

License

MIT — see LICENSE.

Metadata

Release files for dxp-analyzer-doc 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dxp-analyzer-doc 0.2.0
File Size Uploaded Provenance
dxp_analyzer_doc-0.2.0.tar.gz 54.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dxp-analyzer-doc 0.2.0
File Interpreter ABI Platform
dxp_analyzer_doc-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 108.4 kB

Release files / dxp_analyzer_doc-0.2.0.tar.gz

Download URL dxp_analyzer_doc-0.2.0.tar.gz
Size 54.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c5c9b6b3021737629f00e24f7ef4ca09e69a91e880fb25911f232941105b771f
BLAKE2b-256 checksum
How to use checksums
aa6c0c0186338264f32c8bdd370ebd606b1e13c2320ebf31dcb650b450644ad0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / dxp_analyzer_doc-0.2.0-py3-none-any.whl

Download URL dxp_analyzer_doc-0.2.0-py3-none-any.whl
Size 53.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1281f405e8b8b5d432ce7e004cdabb436d6c9beac835daa1a2c1d1c78dc8519f
BLAKE2b-256 checksum
How to use checksums
5e97d931bda926044ac215097acc7adac9d97e6bbcccfd46536cf941e436e23a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Security for dxp-analyzer-doc 0.2.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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page