Collect model outputs, tables, diagnostics, and graphs into reproducible research-output bundles.
Project description
Universal Output Hub
universal-output-hub is a lightweight Python reporting layer for collecting model results, regression tables, statistical tables, diagnostics, notes, and graphs into one reproducible output bundle.
It is designed as a broader Python alternative to Stata-style reporting tools such as outreg2, esttab, and asdoc, but with a wider scope: not only regression tables, but also ordinary tables, figures, metadata, diagnostics, table notes, and complete report exports.
The core idea is simple:
Run your models anywhere. Collect your outputs once. Export them everywhere.
Purpose
Statistical and applied research workflows often produce outputs from many sources:
- Python models from
statsmodels,linearmodels,pyfixest, or custom estimators; - external statistical software such as Stata, R, MATLAB, SPSS, EViews, SAS, Excel, or CSV exports;
- regression tables, descriptive statistics, robustness checks, diagnostics, and plots;
- final outputs needed in Excel, LaTeX, HTML, Word, PDF, Markdown, CSV, or JSON.
universal-output-hub provides one consistent interface for collecting those outputs and exporting them into publication-ready and review-friendly formats.
Core capabilities
| Capability | Status |
|---|---|
| Add Python model results | Yes |
| Add custom model dictionaries | Yes |
| Add coefficient tables from external software | Yes |
| Add ordinary pandas tables | Yes |
Add CSV, Excel, Stata .dta, TSV, and Parquet tables |
Yes |
| Add graph/image files | Yes |
| Save matplotlib-style figures | Yes |
| Build publication-style regression tables | Yes |
| Put models side-by-side in columns | Yes |
| Show coefficient estimates | Yes |
| Show standard errors below coefficients | Yes |
| Add configurable significance stars | Yes |
| Add table notes below model tables | Yes |
| Store diagnostics and model statistics | Yes |
| Export CSV | Yes |
Export Excel .xlsx |
Yes |
| Export HTML | Yes |
| Export Markdown | Yes |
Export LaTeX .tex tables and reports |
Yes |
| Export JSON | Yes |
Export Word .docx reports |
Yes |
| Export PDF tables and reports | Yes |
| Export combined Excel workbook | Yes |
| Create reproducible output bundles | Yes |
Outreg-style reporting
universal-output-hub supports outreg2-style model reporting in Python.
That means it can:
| Question | Answer |
|---|---|
Export regression/model results like outreg2? |
Yes, broadly |
| Put models side-by-side in columns? | Yes |
| Show coefficient estimates? | Yes |
| Show standard errors below coefficients? | Yes |
| Add significance stars? | Yes |
| Customize star thresholds? | Yes |
| Include diagnostics/statistics like N, R², Hansen p, Sargan p, AR tests, instruments? | Yes |
| Add notes under the table? | Yes |
| Export to Excel? | Yes |
| Export to LaTeX? | Yes |
| Export to PDF? | Yes |
| Export to Word/DOCX? | Yes |
| Export to HTML, Markdown, CSV, JSON? | Yes |
Accept statsmodels results? |
Yes |
| Accept custom model dictionaries? | Yes |
| Accept Stata/R/MATLAB/SPSS/EViews outputs? | Yes, if exported as structured coefficient tables |
This package is not a full clone of Stata’s outreg2. It provides outreg2-style reporting for Python and external coefficient-table workflows.
Current limitations and roadmap
| Capability | Status |
|---|---|
Native MATLAB .mat model-object parser |
Planned |
Native Stata .ster parser |
Planned |
Native R .rds model-object parser |
Planned |
Exact Stata outreg2 command compatibility |
Planned |
Full esttab-level formatting grammar |
Planned |
| Multi-equation models with separate panels | Planned |
| Automatic fixed-effect yes/no row detection from native model objects | Planned |
| Journal templates | Planned |
External software compatibility currently works through structured coefficient tables with at least a term column and a coefficient column. Standard errors, p-values, statistics, diagnostics, and notes can also be supplied.
Installation
Install from PyPI:
bash python -m pip install universal-output-hub
Install from GitHub:
python -m pip install git+https://github.com/Akanom/universal-output-hub.git
Development installation:
python -m pip install -e ".[dev,examples]"
pytest -q
Windows PowerShell:
cd "<UNIVERSAL_OUTPUT_HUB_REPO>"
py -3.13 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip setuptools wheel
python -m pip install -e ".[dev,examples]"
pytest -q
Basic example
from universal_output_hub import OutputHub
hub = OutputHub(
"Model Output Report",
metadata={
"project": "Panel-data model comparison",
"software": "Python / Stata / R compatible",
},
)
hub.add_model(
{
"name": "System GMM",
"depvar": "growth_rate",
"params": {
"L.growth_rate": 0.31,
"lPA": 0.08,
"s_techshare": 0.16,
"s_tech_frag_polity": -0.022,
},
"std_errors": {
"L.growth_rate": 0.12,
"lPA": 0.03,
"s_techshare": 0.07,
"s_tech_frag_polity": 0.012,
},
"pvalues": {
"L.growth_rate": 0.011,
"lPA": 0.007,
"s_techshare": 0.041,
"s_tech_frag_polity": 0.078,
},
"statistics": {
"N": 946,
"Instruments": 42,
},
"diagnostics": {
"AR(1) p": 0.085,
"AR(2) p": 0.316,
"Hansen p": 0.190,
"Sargan p": 0.098,
"Diff-Hansen p": 0.089,
},
}
)
hub.add_table_note("Standard errors are reported in parentheses.")
hub.add_table_note("Hansen, Sargan, and AR tests are reported as p-values.")
hub.export_bundle("outputs/model_output")
Output bundle structure
outputs/model_output/
├── index.html
├── manifest.json
├── regression_tables/
│ ├── regression_table.csv
│ ├── regression_table.xlsx
│ ├── regression_table.html
│ ├── regression_table.md
│ ├── regression_table.tex
│ ├── regression_table.pdf
│ └── regression_table.json
├── tables/
├── figures/
├── workbooks/
│ └── output_workbook.xlsx
└── reports/
├── output_report.docx
├── output_report.pdf
└── output_report.tex
The default output filenames are generic:
output_report.docx
output_report.pdf
output_report.tex
output_workbook.xlsx
The package does not assume that the project is a thesis, dissertation, academic paper, business report, or internal analysis.
Regression tables
Export regression/model tables to multiple formats:
hub.export_regression_table("outputs/regression_table.xlsx")
hub.export_regression_table("outputs/regression_table.tex")
hub.export_regression_table("outputs/regression_table.pdf")
hub.export_regression_table("outputs/regression_table.html")
hub.export_regression_table("outputs/regression_table.md")
hub.export_regression_table("outputs/regression_table.csv")
hub.export_regression_table("outputs/regression_table.json")
A typical table includes:
System GMM
L.growth_rate 0.310**
(0.120)
lPA 0.080***
(0.030)
N 946
Instruments 42
AR(1) p 0.085
AR(2) p 0.316
Hansen p 0.190
Sargan p 0.098
Diff-Hansen p 0.089
Significance *** p≤0.01, ** p≤0.05, * p≤0.10
Notes Standard errors are reported in parentheses.
Hansen, Sargan, and AR tests are reported as p-values.
Significance stars
Stars are enabled by default:
*** p≤0.01
** p≤0.05
* p≤0.10
Disable stars:
hub.export_regression_table(
"outputs/regression_table.tex",
stars=False,
)
Use custom thresholds:
hub.export_regression_table(
"outputs/regression_table.tex",
star_levels={"***": 0.001, "**": 0.01, "*": 0.05},
)
Table notes
Use table notes for outreg2-style notes under regression/model tables:
hub.add_table_note("Standard errors in parentheses.")
hub.add_table_note("Country and year fixed effects included.")
hub.add_table_note("Hansen, Sargan, and AR tests are reported as p-values.")
Table notes are included in:
- regression/model tables;
- Excel exports;
- LaTeX exports;
- PDF exports;
- DOCX reports;
- PDF reports;
- LaTeX reports;
- manifest files.
You can also pass notes directly when building a regression table:
table = hub.regression_table(
table_notes=[
"Standard errors in parentheses.",
"Country and year fixed effects included.",
]
)
Diagnostics and model statistics
Diagnostics and statistics can be supplied directly:
hub.add_model(
{
"name": "System GMM",
"params": {"L.y": 0.42, "x": 0.11},
"std_errors": {"L.y": 0.10, "x": 0.04},
"pvalues": {"L.y": 0.001, "x": 0.030},
"statistics": {
"N": 946,
"Instruments": 42,
},
"diagnostics": {
"AR(1) p": 0.085,
"AR(2) p": 0.316,
"Hansen p": 0.190,
"Sargan p": 0.098,
"Diff-Hansen p": 0.089,
},
}
)
Supported diagnostic/statistic rows include, among others:
N
R2
Adj. R2
Within R2
Overall R2
AIC
BIC
Log Likelihood
F statistic
F p-value
AR(1) p
AR(2) p
Hansen p
Sargan p
Diff-Hansen p
Instruments
Entity FE
Time FE
Fixed effects
Clustered SE
The package exports diagnostics. It does not compute Hansen, Sargan, AR tests, or other estimator-specific tests by itself unless a backend or model object supplies them.
External model outputs
External statistical software can be used by exporting coefficient tables into a structured format.
Minimum structure:
| term | coef | se | pvalue |
|---|---|---|---|
| lPA | 0.080 | 0.022 | 0.001 |
| s_techshare | 0.161 | 0.071 | 0.024 |
Then import:
hub.add_model_file(
"stata_fe_results.csv",
name="Stata FE",
term_col="term",
coef_col="coef",
se_col="se",
pvalue_col="pvalue",
statistics={"N": 885, "Within R2": 0.21},
diagnostics={"Clustered SE": "country"},
source="Stata export",
)
Supported model/table file formats:
.csv
.tsv
.txt
.xlsx
.xls
.dta
.parquet
.pq
Embedded diagnostics from imported regression tables
Some tools export diagnostics as rows below the coefficients. For example:
term,coef,se,pvalue
L.y,0.42,0.10,0.001
x,0.11,0.04,0.030
N,946,,
Instruments,42,,
AR(1) p,0.085,,
AR(2) p,0.316,,
Hansen p,0.190,,
Sargan p,0.098,,
Diff-Hansen p,0.089,,
Entity FE,Yes,,
Time FE,Yes,,
The package can treat these as table statistics/diagnostics rather than coefficients when the embedded-diagnostics extractor is enabled in the adapter layer.
This is useful for Stata/R/MATLAB/SPSS/EViews-style result exports.
Python models
import statsmodels.api as sm
from universal_output_hub import OutputHub
hub = OutputHub("Python Model Output")
fit = sm.OLS(y, X).fit()
hub.add_model(fit, name="OLS", adapter="statsmodels")
hub.export_bundle("outputs/python_models")
The package extracts common model information such as coefficients, standard errors, p-values, N, R², AIC, BIC, log likelihood, and related statistics when available.
Custom model dictionaries
Custom estimators can be passed directly:
hub.add_model(
{
"name": "Custom Estimator",
"depvar": "y",
"params": {
"x1": 1.25,
"x2": -0.40,
},
"std_errors": {
"x1": 0.20,
"x2": 0.15,
},
"pvalues": {
"x1": 0.004,
"x2": 0.080,
},
"statistics": {
"N": 100,
"R2": 0.45,
},
"diagnostics": {
"Hansen p": 0.31,
"AR(2) p": 0.42,
},
}
)
This is the recommended interface for custom econometric packages, including dynamic-panel GMM workflows.
Ordinary tables
Add descriptive statistics, robustness checks, correlations, or any pandas-compatible table:
hub.add_table("Descriptive statistics", df.describe())
hub.add_table("Correlation matrix", df.corr())
hub.add_table("Robustness summary", robustness_df)
hub.export_tables(
"outputs/tables",
formats=("csv", "xlsx", "html", "md", "tex", "pdf", "json"),
)
Figures and graphs
Add an existing graph file:
hub.add_figure(
"Marginal effects plot",
path="figures/marginal_effects.png",
caption="Estimated marginal effects across institutional quality.",
)
Save a matplotlib-style figure directly:
hub.add_figure(
"Model comparison",
fig=fig,
output_dir="outputs/figures",
filename="model_comparison.png",
)
Figures are copied into reproducible output bundles and included in full reports where supported.
Complete reports
Export full reports:
hub.export_report("outputs/output_report.docx")
hub.export_report("outputs/output_report.pdf")
hub.export_report("outputs/output_report.tex")
hub.export_excel_workbook("outputs/output_workbook.xlsx")
With a bundle:
hub.export_bundle(
"outputs/model_output",
report_filename="output_report",
workbook_filename="output_workbook",
)
Use custom generic names:
hub.export_bundle(
"outputs/project_run_001",
report_filename="model_output_report",
workbook_filename="model_output_workbook",
)
Recommended workflow
from universal_output_hub import OutputHub
hub = OutputHub("Model Output Report")
hub.add_model(model_1, name="OLS")
hub.add_model(model_2, name="Fixed Effects")
hub.add_model(model_3, name="System GMM")
hub.add_table_note("Standard errors in parentheses.")
hub.add_table_note("Country and year fixed effects included.")
hub.add_table("Descriptive statistics", descriptives)
hub.add_table("Robustness checks", robustness)
hub.add_figure("Coefficient plot", path="figures/coefplot.png")
hub.export_bundle("outputs/run_001")
Design philosophy
- Model-agnostic: accept Python models, custom dictionaries, and structured external coefficient tables.
- Research-friendly: support regression tables, diagnostics, notes, tables, figures, and reproducible bundles.
- Format-flexible: export to Excel, LaTeX, PDF, Word, HTML, Markdown, CSV, and JSON.
- Transparent: avoid pretending to be a native parser for every statistical software object.
- Simple API: collect outputs once and export them everywhere.
Project status
Current release: 0.2.0
This is an early-stage package. The public API is usable, but some internals may still change as the package matures.
License
MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file universal_output_hub-0.2.0.tar.gz.
File metadata
- Download URL: universal_output_hub-0.2.0.tar.gz
- Upload date:
- Size: 27.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e70b288c3d20fc49be16562a9c10397f82f3f6da55e752bb999986aac4dfdc78
|
|
| MD5 |
10e0a90b9335ced1b727782e4aefd98b
|
|
| BLAKE2b-256 |
75316dcbeaed1daeb231a4424c079d4703e0d805442a6a503356e7745dd93d71
|
Provenance
The following attestation bundles were made for universal_output_hub-0.2.0.tar.gz:
Publisher:
publish.yml on Akanom/universal-output-hub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
universal_output_hub-0.2.0.tar.gz -
Subject digest:
e70b288c3d20fc49be16562a9c10397f82f3f6da55e752bb999986aac4dfdc78 - Sigstore transparency entry: 1740221419
- Sigstore integration time:
-
Permalink:
Akanom/universal-output-hub@b79eb934d66f7541541401d69c6a6e609537f5af -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Akanom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b79eb934d66f7541541401d69c6a6e609537f5af -
Trigger Event:
release
-
Statement type:
File details
Details for the file universal_output_hub-0.2.0-py3-none-any.whl.
File metadata
- Download URL: universal_output_hub-0.2.0-py3-none-any.whl
- Upload date:
- Size: 23.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb85c0abf780fb8ecaaca008069f0e9f4c13f012360cbaf52ffa86ee48a7c987
|
|
| MD5 |
1c95c2e585a6a78ec01e3eda9bd6902d
|
|
| BLAKE2b-256 |
3f8a78128752ed6983834c61cf689c07ef0489b73445b295c02f3281c828a043
|
Provenance
The following attestation bundles were made for universal_output_hub-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on Akanom/universal-output-hub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
universal_output_hub-0.2.0-py3-none-any.whl -
Subject digest:
cb85c0abf780fb8ecaaca008069f0e9f4c13f012360cbaf52ffa86ee48a7c987 - Sigstore transparency entry: 1740221423
- Sigstore integration time:
-
Permalink:
Akanom/universal-output-hub@b79eb934d66f7541541401d69c6a6e609537f5af -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Akanom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b79eb934d66f7541541401d69c6a6e609537f5af -
Trigger Event:
release
-
Statement type: