Framework Cloud docs

Publishing artifacts and collections

Publish a research output to give it a reader page and a link. An artifact can be a rendered Quarto report or book, a figure, a table, a model summary, or a file for readers to download. You can publish one output without publishing a notebook or your project code.

Framework Public Cloud includes free publishing with 1 GB of artifact storage per account. All versions share this limit. Self-hosted servers include publishing.

Publishing destinations

Publish to Framework Cloud, GitHub Pages, a local or mounted folder, or object storage. Named destinations are set in project settings:

publish:
  default: lab
  destinations:
    lab:
      driver: folder
      path: /Volumes/lab/published
      visibility: private

Use to="lab" in R or Python, or fw publish --to lab <file>. Explicit destinations override the project default. The account's Publishing settings seed the destination for new projects.

Folder bundles include a reader page and retained versions. They work offline. Folder access follows filesystem or web-server permissions. GitHub Pages sites are public unless the destination API confirms restricted access. Private repositories alone do not restrict Pages.

Cloud tracks external publication metadata when a project token is available. It stores no external files or local paths. Access settings stay at the destination.

Browser uploads

Open a project's Artifacts page and choose Publish an artifact, or use the Published page. Select a file and enter an optional title and description.

For a rendered book or website, zip the contents of the output folder and select This is a zip of rendered HTML and its supporting files. Enter the entry page's path inside the zip, usually index.html. Upload rendered outputs rather than the project folder, which may contain data, credentials, and source files.

An artifact's name identifies it within the project. Uploading with the same name adds a version at the same link. Its display title can change independently.

Uploads currently allow up to 50 MiB. Rendered bundles may contain up to 4,000 entries and 200 MiB of expanded files.

R, Python, and CLI publishing

From a project connected to Framework Cloud:

framework::publish("outputs/figures/effect.png", to = "cloud", slug = "effect")
fw publish outputs/figures/effect.png --slug effect

The R and Python packages also accept rendered HTML, rendered directories, and Quarto documents through their existing notebook publishing functions. The CLI accepts rendered files and folders. Render source documents before uploading.

Explicit to = "cloud" in R or to="cloud" in Python selects Framework Cloud even when the project has a storage bucket. Existing calls that omit to keep their bucket-first behavior. Use to = "bucket" or to="bucket" for a bucket, or to = "github" or to="github" for rendered content on GitHub Pages.

publish() accepts these objects in R and Python:

Object R Python Shown as
Data data frames, tibbles, data.tables, matrices, table and xtabs pandas and polars data frames and series, numpy arrays, crosstabs A table with a profile of each column
Hypothesis tests t.test, chisq.test, wilcox.test, cor.test, and other htest results scipy.stats results such as ttest_ind, pearsonr, and chi2_contingency The statistic, p-value, and confidence interval, with an interval chart
Regression models lm, glm, aov, glm.nb, polr, multinom, lme4, coxph, survreg, fixest, and mgcv::gam statsmodels results, including GLM, discrete models, MixedLM, and QuantReg Coefficients, a forest plot, and fit statistics
ANOVA tables anova() and summary(aov) anova_lm A table
Machine learning models none scikit-learn linear and tree models, xgboost, and lightgbm Coefficients or feature importance, and the model's settings
Figures ggplot and patchwork, base graphics from recordPlot(), and lattice matplotlib and seaborn An SVG image, or a PNG for very large plots
Interactive figures plotly and other htmlwidgets plotly figures and altair charts The interactive figure
Formatted tables gt, gtsummary, and flextable pandas Styler HTML

For Cloud, data, tests, and models become a typed JSON representation. Tables retain supplied rows, column names, types, and missing values, and each column carries a summary computed over all its rows before publishing: missing values, distinct values, summary statistics with a histogram for numbers, and the most frequent values otherwise. Model summaries include coefficients, standard errors, confidence intervals, aggregate fit statistics, and a formula when available. The forest plot leaves out the intercept. For logistic, count, and survival models it shows odds, rate, hazard, or time ratios on a log scale, with a switch back to the model's own scale. Mixed models add their random effects, and tree-based models show feature importance.

Data files publish too. A CSV or TSV becomes the same kind of table: Cloud infers each column's type (numbers, dates, true/false values, or text, with IDs such as 007 kept as text) and summarizes every column over all its rows. Readers see the first 1,000 rows and can download the original file. Files with more than 500,000 rows or 200 columns show a plain preview instead. Excel, Parquet, Feather, Stata, SPSS, SAS, and RDS files are shared for download.

altair charts are drawn in an isolated frame that has no access to the rest of Framework Cloud and can't fetch data from other sites, so a chart's data must be inlined in its specification. altair inlines it when you publish.

Readers can sort columns, search cells, change pages, and export the loaded preview as CSV. Numeric sorting respects numeric values and keeps missing values last. Large integer identifiers are displayed as text to retain their exact digits. The downloaded JSON retains the full representation. Table previews load up to 1,000 rows and 50 columns. Notices identify omitted data and other preview limits. Representations over 8 MiB remain downloadable.

Model summaries do not automatically upload the original model object or observation-level data. Publishing a data frame uploads all the rows supplied to that function. To share a saved model object, publish its file explicitly. Readers can download it. Cloud does not execute it.

Artifact management

Each artifact has its own page. Open it with Manage from Published outputs or a project's Outputs tab. The page links back to its project and has four tabs:

New artifacts are unlisted. Anyone with their link can open them. Unlisted links are not authenticated private access.

Enable a readable link on the artifact's Sharing tab, or use the slug option from a package. A readable link looks like:

https://framework.pub/@ada/nhanes-study/main-results

A readable link needs a handle, set in Account > Account details. The unlisted link continues to work when readable links are turned off.

Add a password on the artifact's Sharing tab to require readers to unlock the page. The password also gates originals, downloads, supporting assets, and earlier versions. Passwords need at least eight characters. Changing a password revokes existing reader sessions. Owners can open their artifacts while signed in.

Older artifacts may have files already exposed on a separate public storage host. Cloud refuses to add a password while those external versions remain. A password on the reader page cannot revoke a public file URL.

Versions and merging

Each successful publish adds a version. The stable artifact link opens the newest remaining version. A version-specific link identifies that exact version:

https://framework.pub/d/q7w2k9m4x8c1v5b3n6z0p2rt/versions/2

Deleting a version takes down its links. Deleting the newest version makes the previous one current. Version numbers are never reused. Deleting the only version takes down the artifact.

On an artifact's Settings tab, use Merge another artifact into this one to append another artifact's versions to the destination's history. Both artifacts must belong to the same project. The source retains its original links and versions, and future publishing uses the destination. The copied versions use the destination's sharing settings. Merging combines version histories only. The contents of two reports or statistical models are not combined.

Collections

Open Collections within a project to create a collection. The title and introduction save as you type. Add artifact searches the project's published artifacts. Each entry's edit button sets its caption and version. Drag an entry by its handle to reorder it, or focus the handle and use the up and down arrow keys. An artifact can appear in several collections without duplicating its files.

R, Python, and the CLI can attach a publication to an existing collection by ID or slug using collection or --collection. To share an unlisted artifact through an unlisted collection, explicitly pass share_unlisted = TRUE, share_unlisted=True, or --share-unlisted. Collections are not created automatically. If attachment fails after a successful publication, the client returns the artifact URL and explains how to attach it from the web interface.

Each entry can follow the latest artifact version or pin an existing version. Pin versions when you want reviewers to read a particular set of results. A deleted pinned version becomes unavailable. Its entry does not move to another version.

Collections start private, visible only to their owner. You can share them as unlisted or public and optionally set a collection password. Sharing changes apply when you choose Save sharing.

A shared collection's link can expire after a day, a week, 30 or 90 days, or on a date you choose. It works through the end of that day in your time zone. After that, readers see a page saying the link has expired. You can still open the collection, and clearing the expiry restores the link. Public collections require public artifacts. Sharing an unlisted artifact in an unlisted collection requires explicit consent for that entry.

A collection's password protects its listing. Individual artifacts retain their own access rules. Protect an artifact itself if its direct link and files also need a password. Unlocking a collection never unlocks its artifacts.

A collection can organize materials for collaboration, peer review, or publication. It does not currently provide reviewer accounts, comments, DOI registration, or an archival guarantee.

Report builder

Open Reports within a project and create a report. The editor shows the report as readers will see it: a title, an introduction, and sections of text and artifacts in order.

Shortcut Mac Windows and Linux
Bold, italic, underline ⌘B, ⌘I, ⌘U Ctrl+B, Ctrl+I, Ctrl+U
Link ⌘K Ctrl+K
Heading, subheading, body text ⌘⌥2, ⌘⌥3, ⌘⌥0 Ctrl+Alt+2, Ctrl+Alt+3, Ctrl+Alt+0
Bulleted and numbered list ⌘⇧8, ⌘⇧7 Ctrl+Shift+8, Ctrl+Shift+7
Save now ⌘S Ctrl+S

Drafts save automatically a moment after you stop typing. Adding or removing a password applies only when you choose Save draft. Use Preview to read the saved draft as readers will.

Saving a draft updates the editor. Publishing creates a numbered report version containing the current text, introduction, captions, and selected artifact versions. When an artifact section follows the latest version in the draft, publishing pins the version available at that moment. Artifact labels and kinds are also preserved. Later changes to the analysis or draft do not alter an existing published report.

Reports start private. You can publish them as unlisted or public and set a report password. Public reports require public artifacts. Unlisted artifacts require explicit permission to share them with report readers. Artifact passwords continue to apply separately, including inside a report.

Changing a report password revokes existing report reader sessions. Leaving its replacement field blank keeps the current password. Select the explicit removal option to remove protection. A removed artifact version shows as unavailable in older reports, without substituting a newer result.

The report reader provides section navigation, formatted text, interactive artifact displays, download links, and access to earlier report versions. Hosted report publishing is free.

Reports from a script or an AI agent

The reports API builds the same reports from R, Python, Stata, or a terminal. Requests go to /api/v1/projects/<project>/reports with the project token from .env (FW_PROJECT_TOKEN) or a personal API token.

Action Request
List reports GET /api/v1/projects/<project>/reports
Read one GET /api/v1/projects/<project>/reports/<report>
Create POST /api/v1/projects/<project>/reports
Update the draft PATCH /api/v1/projects/<project>/reports/<report>
Publish POST /api/v1/projects/<project>/reports/<report>/publish

A report is a list of blocks. Text blocks are Markdown, or HTML with "format": "html", cleaned the same way as in the editor. Artifact blocks name a published artifact by its slug:

{
  "title": "Penguin body mass",
  "publish": true,
  "blocks": [
    {"type": "text", "text": "## Body mass by species\n\nGentoo penguins are heaviest."},
    {"type": "artifact", "artifact": "mass-by-species"},
    {"type": "artifact", "artifact": "penguin-body-mass", "caption": "Linear model"}
  ]
}

Send markdown instead of blocks for a single text block. publish: true publishes after saving. The response includes the report's link and its versions. The Creating Framework reports skill teaches an AI agent to use this API.

Storage

New artifact files live on a private filesystem disk and are served through Framework Cloud. Metadata, version histories, collections, and password hashes live in the database. See Server setup for the private storage configuration and backup requirements.

Edit this page on GitHub