Share a ydata-profiling report
ProfileReport(df).to_file("profile.html") produces the single most useful
artifact in exploratory data analysis and the single most annoying one to
send. It is one file, which is good, and it is often 15–40 MB, which is why
it dies in an email filter, gets zipped, gets renamed profile_final_v2.html,
and ends up on one laptop.
Worse, the interesting part of a profile is never the profile. It is the
argument about it: whether a 31% null rate in customer_tier is a bug or a
business rule, whether that bimodal distribution is two products stapled
together. That conversation needs to happen on the numbers, not next to them.
Publish it
from ydata_profiling import ProfileReport
import requests, os
ProfileReport(df, title="Orders — profile", minimal=True).to_file("profile.html")
requests.post(
"https://commareports.com/api/v1/reports",
headers={"Authorization": f"Bearer {os.environ['COMMA_API_TOKEN']}"},
json={"title": "Orders — profile", "html": open("profile.html").read()},
).raise_for_status()
minimal=True is doing real work here. The default config computes pairwise
interactions and every correlation matrix, which is most of the file size and
most of the runtime — and for a first-pass review, nobody reads them. Turn it
off, get a file that fits comfortably under the 5 MB HTML cap, and turn it
back on for the one column pair that turns out to matter.
What the URL changes
- Comments land on columns. Highlight the
customer_tierwarning and pin the reason. See commenting on HTML. - Profiles become a series. PATCH the same report id after each run and every refresh appends a revision — so schema drift and null-rate creep are visible as a diff instead of a vibe.
- Analysts without your environment can read it. No pandas, no kernel, no "can you re-run it and screenshot the summary".
- It can refresh on a schedule. A routine profiles the table weekly and posts the result to the same URL.
Limits
- HTML body: 5 MB.
minimal=True, or profile a subset of columns. - Scripts run, sandboxed:
allow-scripts, noallow-same-origin. - 60 requests/minute per token. Use a
scoped token with
reports:writeonly.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.
Related
- Share an EDA report — the broader analysis pattern
- Great Expectations data docs · Evidently reports
- dbt docs · Jupyter workflow