Framework for Python

Features

Saving Work

Saving tables, figures, models, and reports to the output folders, with public and private outputs

Overview

Framework saves analysis outputs with one function per kind. Each function writes the file to the project's output folder for that kind and records it in the results table of framework.db with its hash. Each returns the path of the saved file.

Function Saves Folder key
save_table() A DataFrame as CSV, Parquet, or Excel outputs_tables
save_figure() A matplotlib, seaborn, or plotnine figure outputs_figures
save_model() A fitted model, with pickle outputs_models
save_report() A finished report file outputs_reports
save_notebook() A rendered Quarto or Jupyter notebook outputs_notebooks

An existing file of the same name is replaced. Pass overwrite=False to raise an error instead.

Tables

save_table() writes a DataFrame without its index. The name is the file name without an extension.

import framework as fw

fw.scaffold()
summary = fw.data_read("inputs.final.analysis").groupby("site").mean(numeric_only=True)

fw.save_table(summary.reset_index(), "site_summary")
fw.save_table(summary.reset_index(), "site_summary", format="parquet")
fw.save_table(summary.reset_index(), "site_summary", format="xlsx")

The formats are csv (the default), parquet, and xlsx, which needs the excel extra. Other keyword arguments go to the pandas writer. CSV files use \n line endings on every platform, so their hashes match the ones R records.

Figures

save_figure() saves any object with a savefig() method, such as a matplotlib or seaborn figure, and any object with a save() method, such as a plotnine plot. Passing None saves the current matplotlib figure. framework-py does not depend on a plotting library.

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(summary.index, summary["score"])

fw.save_figure(fig, "score_by_site")
fw.save_figure(fig, "score_by_site", format="svg", width=10, height=4)
fw.save_figure(None, "current_plot")

The formats are png (the default), pdf, svg, jpg, jpeg, and tiff. width and height are in inches, with defaults of 8 and 6, and dpi defaults to 300.

Models

save_model() saves any Python object with pickle, as <name>.pkl.

from sklearn.linear_model import LinearRegression

model = LinearRegression().fit(features, outcome)
fw.save_model(model, "regression_v1")

Warning

Loading a pickle can run arbitrary code. Load model files only from sources you trust.

R saves models as .rds, which Python cannot read. Models do not cross between the languages.

Reports

save_report() copies a finished file, such as an HTML report or a PDF, into the reports folder. name renames it and keeps its extension. move=True moves the file instead of copying it.

fw.save_report("draft/analysis.html", "quarterly_report")
fw.save_report("draft/analysis.html", "quarterly_report", move=True)

Notebooks

save_notebook() renders a .qmd or .ipynb file with Quarto and saves the output in the notebooks folder.

fw.save_notebook("notebooks/exploration.qmd")
fw.save_notebook("notebooks/exploration.qmd", name="final_analysis", format="docx")

Rendering needs the quarto command and, for Python chunks, Jupyter in the environment. The Quarto guide covers rendering.

Public and Private Outputs

Privacy-sensitive projects keep separate public and private folders for each kind of output. The public argument chooses between them. Outputs are private by default.

# outputs/private/tables/patient_outcomes.csv
fw.save_table(patient_outcomes, "patient_outcomes")

# outputs/public/tables/summary.csv
fw.save_table(aggregated, "summary", public=True)

Private folders are ignored by git and refused by the publishing functions. Save to a public folder only after the data has been aggregated or de-identified.

In other project types, every output of a kind goes to the one folder for that kind. The public flag is still recorded in framework.db, so result_list() can filter on it.

Output Folders

The folders come from the directories section of the settings. These are the defaults of a standard project.

outputs/
├── tables/      # outputs_tables
├── figures/     # outputs_figures
├── models/      # outputs_models
├── reports/     # outputs_reports
└── notebooks/   # outputs_notebooks

A privacy-sensitive project uses keys such as outputs_private_tables and outputs_public_tables.

outputs/
├── private/
│   ├── tables/
│   ├── figures/
│   ├── models/
│   ├── reports/
│   └── notebooks/
└── public/
    ├── tables/
    ├── figures/
    ├── models/
    ├── reports/
    └── notebooks/

A folder that does not exist yet is created the first time something is saved there. Change a folder by editing its key in directories.

The Results Registry

Each save adds or updates a row in the results table with these fields.

Field Contents
name The saved file's name, such as site_summary.csv
type table, figure, model, report, or notebook
public Whether the output was saved as public
hash The file's SHA-256 hash
created_at When the file was first saved
updated_at When the file was last saved

result_list() returns the rows, newest first, and filters by type and by the public flag.

fw.result_list()
fw.result_list(type="figure")
fw.result_list(type="table", public=True)

Rows are keyed by file name. Saving summary.csv to the public folder and later to the private folder updates one row.