---
title: hf_store
---

<div class="python-reference">
<a id="fastvideo.performance.hf_store-functions"></a>
<a id="fastvideo.performance.hf_store"></a>
<p>Shared HuggingFace storage utilities for performance tracking.</p>
<p>Provides a single place for:
- Syncing the HF dataset repo to a local directory
- Loading raw JSON records (with optional recency filter)
- Loading records as a normalized pandas DataFrame
- Uploading individual result files back to HF
- Common helpers: sanitize, safe_float</p>
<h2 id="fastvideo.performance.hf_store.resolve_hf_token"><code>fastvideo.performance.hf_store.resolve_hf_token</code></h2>
<pre class="doc-signature"><code>resolve_hf_token() -&gt; str | None</code></pre>
<p>Return the first non-empty Hugging Face token from the environment.</p>
<p>Reads <code>HF_TOKEN</code>, then <code>HUGGING_FACE_HUB_TOKEN</code>, then the deprecated
FastVideo-specific aliases <code>HUGGINGFACE_HUB_TOKEN</code> and <code>HF_API_KEY</code>,
which log a deprecation warning. Does not mutate <code>os.environ</code>.</p>
<h2 id="fastvideo.performance.hf_store.sanitize"><code>fastvideo.performance.hf_store.sanitize</code></h2>
<pre class="doc-signature"><code>sanitize(value: str) -&gt; str</code></pre>
<p>Return a filesystem- and HF-path-safe version of <em>value</em>.</p>
<details><summary>Source</summary><pre><code>def sanitize(value: str) -&gt; str:
    &quot;&quot;&quot;Return a filesystem- and HF-path-safe version of *value*.&quot;&quot;&quot;
    sanitized = re.sub(r&quot;&#91;^A-Za-z0-9._-&#93;&quot;, &quot;_&quot;, value)
    return f&quot;_&#123;sanitized&#125;&quot; if not sanitized or sanitized.startswith(&quot;.&quot;) else sanitized</code></pre></details>
<h2 id="fastvideo.performance.hf_store.safe_float"><code>fastvideo.performance.hf_store.safe_float</code></h2>
<pre class="doc-signature"><code>safe_float(value: Any) -&gt; float | None</code></pre>
<p>Coerce <em>value</em> to float, returning None on failure.</p>
<details><summary>Source</summary><pre><code>def safe_float(value: Any) -&gt; float | None:
    &quot;&quot;&quot;Coerce *value* to float, returning None on failure.&quot;&quot;&quot;
    if value is None:
        return None
    try:
        return float(value)
    except (TypeError, ValueError):
        return None</code></pre></details>
<h2 id="fastvideo.performance.hf_store.is_baseline_eligible_record"><code>fastvideo.performance.hf_store.is_baseline_eligible_record</code></h2>
<pre class="doc-signature"><code>is_baseline_eligible_record(record: dict&#91;str, Any&#93;) -&gt; bool</code></pre>
<p>Return whether <em>record</em> may contribute to rolling baselines.</p>
<p>Legacy records predate <code>baseline_eligible</code> and <code>run_source</code>. They were
uploaded only by the old successful main/full-suite path, so keep them
eligible until the HF history naturally rolls forward.</p>
<details><summary>Source</summary><pre><code>def is_baseline_eligible_record(record: dict&#91;str, Any&#93;) -&gt; bool:
    &quot;&quot;&quot;Return whether *record* may contribute to rolling baselines.

    Legacy records predate ``baseline_eligible`` and ``run_source``. They were
    uploaded only by the old successful main/full-suite path, so keep them
    eligible until the HF history naturally rolls forward.
    &quot;&quot;&quot;
    if record.get(&quot;baseline_eligible&quot;) is True:
        return True
    return &quot;baseline_eligible&quot; not in record and &quot;run_source&quot; not in record</code></pre></details>
<h2 id="fastvideo.performance.hf_store.sync_from_hf"><code>fastvideo.performance.hf_store.sync_from_hf</code></h2>
<pre class="doc-signature"><code>sync_from_hf(local_dir: str, *, strict: bool = False, reuse_existing: bool = False, revision: str | None = None) -&gt; str</code></pre>
<p>Download the HF dataset repo snapshot to <em>local_dir</em>.</p>
<p>Returns <em>local_dir</em> so callers can chain: <code>load_records(sync_from_hf(...))</code>.</p>
<p>By default (<code>strict=False</code>) failures are logged and <em>local_dir</em> is
returned unchanged, so dashboard / PR consumers stay resilient when HF is
unavailable. Callers that depend on the sync for correctness (e.g. the
main-branch baseline writer) must pass <code>strict=True</code> so that misconfig
or transient HF errors fail loud rather than silently reset the baseline.</p>
<p>When <code>reuse_existing=True</code>, a previous successful sync in <code>local_dir</code>
is reused only while its marker is fresh. This avoids duplicate HF
snapshot checks when compare and dashboard scripts run sequentially in the
same CI job, without silently reusing stale data in persistent local or
long-lived runner environments.</p>
<p>Pass <code>revision</code> to pin the snapshot to a previously read Hub commit. This
is used by conditional writers that must validate one exact remote state
before committing with that revision as their parent.</p>
<details><summary>Source</summary><pre><code>def sync_from_hf(
    local_dir: str,
    *,
    strict: bool = False,
    reuse_existing: bool = False,
    revision: str | None = None,
) -&gt; str:
    &quot;&quot;&quot;Download the HF dataset repo snapshot to *local_dir*.

    Returns *local_dir* so callers can chain: ``load_records(sync_from_hf(...))``.

    By default (``strict=False``) failures are logged and *local_dir* is
    returned unchanged, so dashboard / PR consumers stay resilient when HF is
    unavailable. Callers that depend on the sync for correctness (e.g. the
    main-branch baseline writer) must pass ``strict=True`` so that misconfig
    or transient HF errors fail loud rather than silently reset the baseline.

    When ``reuse_existing=True``, a previous successful sync in ``local_dir``
    is reused only while its marker is fresh. This avoids duplicate HF
    snapshot checks when compare and dashboard scripts run sequentially in the
    same CI job, without silently reusing stale data in persistent local or
    long-lived runner environments.

    Pass ``revision`` to pin the snapshot to a previously read Hub commit. This
    is used by conditional writers that must validate one exact remote state
    before committing with that revision as their parent.
    &quot;&quot;&quot;
    marker_path = _sync_marker_path(local_dir)
    if reuse_existing and os.path.exists(marker_path):
        if _sync_marker_is_fresh(marker_path) and _sync_marker_matches_request(marker_path, revision):
            print(f&quot;hf_store: reusing existing sync at &#123;local_dir&#125;&quot;)
            return local_dir
        os.remove(marker_path)
        print(f&quot;hf_store: existing sync at &#123;local_dir&#125; is stale or mismatched; refreshing&quot;)

    if not reuse_existing and os.path.exists(marker_path):
        os.remove(marker_path)

    if not HF_REPO_ID:
        msg = &quot;hf_store: HF_REPO_ID not set&quot;
        if strict:
            raise RuntimeError(f&quot;&#123;msg&#125;; cannot sync.&quot;)
        print(f&quot;&#123;msg&#125;, skipping sync.&quot;)
        return local_dir

    print(f&quot;hf_store: syncing from &#123;HF_REPO_ID&#125; → &#123;local_dir&#125;&quot;)
    try:
        snapshot_download(
            repo_id=HF_REPO_ID,
            repo_type=&quot;dataset&quot;,
            local_dir=local_dir,
            token=resolve_hf_token(),
            allow_patterns=&quot;*.json&quot;,
            revision=revision,
        )
        os.makedirs(local_dir, exist_ok=True)
        with open(marker_path, &quot;w&quot;, encoding=&quot;utf-8&quot;) as marker:
            json.dump(
                &#123;
                    &quot;endpoint&quot;: ENDPOINT,
                    &quot;repo_id&quot;: HF_REPO_ID,
                    &quot;synced_at&quot;: datetime.now(timezone.utc).isoformat(),
                    &quot;revision&quot;: revision,
                &#125;, marker)
    except Exception as exc:
        if strict:
            raise
        print(f&quot;hf_store: sync skipped — &#123;exc&#125;&quot;)

    return local_dir</code></pre></details>
<h2 id="fastvideo.performance.hf_store.upload_record"><code>fastvideo.performance.hf_store.upload_record</code></h2>
<pre class="doc-signature"><code>upload_record(local_path: str, record: dict&#91;str, Any&#93;, *, strict: bool = False) -&gt; None</code></pre>
<p>Upload <em>local_path</em> to the HF repo under <code>&lt;model_id&gt;/&lt;filename&gt;</code>.</p>
<p>By default failures (missing token, network errors) are logged and
swallowed. Pass <code>strict=True</code> when the upload is part of a write-path
that must not silently lose records — otherwise the rolling baseline can
stop advancing without any signal in the build log.</p>
<details><summary>Source</summary><pre><code>def upload_record(
    local_path: str,
    record: dict&#91;str, Any&#93;,
    *,
    strict: bool = False,
) -&gt; None:
    &quot;&quot;&quot;Upload *local_path* to the HF repo under ``&lt;model_id&gt;/&lt;filename&gt;``.

    By default failures (missing token, network errors) are logged and
    swallowed. Pass ``strict=True`` when the upload is part of a write-path
    that must not silently lose records — otherwise the rolling baseline can
    stop advancing without any signal in the build log.
    &quot;&quot;&quot;
    token = resolve_hf_token()
    if not token:
        msg = f&quot;hf_store: none of &#123;&#x27;, &#x27;.join(HF_TOKEN_ENV_VARS + DEPRECATED_HF_TOKEN_ENV_VARS)&#125; set&quot;
        if strict:
            raise RuntimeError(f&quot;&#123;msg&#125;; cannot upload.&quot;)
        print(f&quot;&#123;msg&#125;, skipping upload.&quot;)
        return

    model_id = record.get(&quot;model_id&quot;, &quot;unknown&quot;)
    path_in_repo = f&quot;&#123;sanitize(model_id)&#125;/&#123;os.path.basename(local_path)&#125;&quot;
    commit_sha = (record.get(&quot;commit_sha&quot;) or &quot;unknown&quot;)&#91;:7&#93;

    api = HfApi(token=token)
    try:
        api.upload_file(
            path_or_fileobj=local_path,
            path_in_repo=path_in_repo,
            repo_id=HF_REPO_ID,
            repo_type=&quot;dataset&quot;,
            commit_message=f&quot;Perf: &#123;model_id&#125; at &#123;commit_sha&#125;&quot;,
        )
        print(f&quot;hf_store: uploaded → &#123;HF_REPO_ID&#125;/&#123;path_in_repo&#125;&quot;)
    except Exception as exc:
        if strict:
            raise
        print(f&quot;hf_store: upload failed — &#123;exc&#125;&quot;)</code></pre></details>
<h2 id="fastvideo.performance.hf_store.load_records"><code>fastvideo.performance.hf_store.load_records</code></h2>
<pre class="doc-signature"><code>load_records(local_dir: str, *, days: int | None = None, successful_only: bool = False, baseline_eligible_only: bool = False) -&gt; list&#91;dict&#91;str, Any&#93;&#93;</code></pre>
<p>Return raw JSON dicts from <em>local_dir</em>.</p>
<h3>Parameters</h3>
<dl>
<dt><code>local_dir: str</code></dt><dd><p>Root directory previously populated by :func:<code>sync_from_hf</code>.</p></dd>
<dt><code>days: int | None</code></dt><dd><p>When set, discard records whose <code>timestamp</code> is older than this
many days. Records with a missing/unparsable timestamp are kept.</p></dd>
<dt><code>successful_only: bool</code></dt><dd><p>When True, only records with <code>success=True</code> are
returned. Useful when building a regression baseline.</p></dd>
<dt><code>baseline_eligible_only: bool</code></dt><dd><p>When True, only baseline-eligible records are
returned. Legacy records missing both <code>baseline_eligible</code> and
<code>run_source</code> are treated as eligible.</p></dd>
</dl>
<h3>Returns</h3>
<dl>
<dt><code>list[dict[str, Any]]</code></dt><dd><p>List of raw dicts sorted by <code>timestamp</code> ascending (records that could</p></dd>
<dt><code>list[dict[str, Any]]</code></dt><dd><p>not be parsed are silently skipped).</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def load_records(
    local_dir: str,
    *,
    days: int | None = None,
    successful_only: bool = False,
    baseline_eligible_only: bool = False,
) -&gt; list&#91;dict&#91;str, Any&#93;&#93;:
    &quot;&quot;&quot;Return raw JSON dicts from *local_dir*.

    Args:
        local_dir: Root directory previously populated by :func:`sync_from_hf`.
        days: When set, discard records whose ``timestamp`` is older than this
            many days. Records with a missing/unparsable timestamp are kept.
        successful_only: When True, only records with ``success=True`` are
            returned. Useful when building a regression baseline.
        baseline_eligible_only: When True, only baseline-eligible records are
            returned. Legacy records missing both ``baseline_eligible`` and
            ``run_source`` are treated as eligible.

    Returns:
        List of raw dicts sorted by ``timestamp`` ascending (records that could
        not be parsed are silently skipped).
    &quot;&quot;&quot;
    cutoff: datetime | None = None
    if days is not None:
        cutoff = datetime.now(timezone.utc) - timedelta(days=days)

    records: list&#91;tuple&#91;datetime, str, dict&#91;str, Any&#93;&#93;&#93; = &#91;&#93;

    for path in sorted(glob.glob(os.path.join(local_dir, &quot;**&quot;, &quot;*.json&quot;), recursive=True)):
        try:
            with open(path, encoding=&quot;utf-8&quot;) as fh:
                data: dict&#91;str, Any&#93; = json.load(fh)
        except (OSError, json.JSONDecodeError):
            continue

        if successful_only and not data.get(&quot;success&quot;, True):
            continue

        if baseline_eligible_only and not is_baseline_eligible_record(data):
            continue

        ts = _parse_record_timestamp(data)
        if cutoff is not None and ts is not None and ts &lt; cutoff:
            continue

        records.append((
            ts or datetime.min.replace(tzinfo=timezone.utc),
            path,
            data,
        ))

    return &#91;data for _ts, _path, data in sorted(records)&#93;</code></pre></details>
<h2 id="fastvideo.performance.hf_store.load_records_for_model"><code>fastvideo.performance.hf_store.load_records_for_model</code></h2>
<pre class="doc-signature"><code>load_records_for_model(local_dir: str, model_id: str, gpu_type: str | None = None, *, workload_id: str | None = None, variant_id: str | None = None, benchmark_version: str | None = None, recipe_fingerprint: str | None = None, hardware_profile_id: str | None = None, software_profile_id: str | None = None, last_n: int | None = None, successful_only: bool = True, baseline_eligible_only: bool = False) -&gt; list&#91;dict&#91;str, Any&#93;&#93;</code></pre>
<p>Return records for a specific <em>model_id</em>, optionally filtered by cohort.</p>
<h3>Parameters</h3>
<dl>
<dt><code>local_dir: str</code></dt><dd><p>Root directory previously populated by :func:<code>sync_from_hf</code>.</p></dd>
<dt><code>model_id: str</code></dt><dd><p>Matches the <code>model_id</code> field inside each JSON record.</p></dd>
<dt><code>gpu_type: str | None</code></dt><dd><p>When set, only records whose <code>gpu_type</code> matches are returned.</p></dd>
<dt><code>workload_id: str | None</code></dt><dd><p>When set, only records from the same workload are returned.</p></dd>
<dt><code>variant_id: str | None</code></dt><dd><p>When set, only records from the same workload variant are returned.</p></dd>
<dt><code>benchmark_version: str | None</code></dt><dd><p>When set, only records from the same benchmark version are returned.</p></dd>
<dt><code>recipe_fingerprint: str | None</code></dt><dd><p>When set, only records from the same benchmark
recipe are returned.</p></dd>
<dt><code>hardware_profile_id: str | None</code></dt><dd><p>When set, only records from the same hardware
cohort are returned.</p></dd>
<dt><code>software_profile_id: str | None</code></dt><dd><p>When set, only records from the same software
cohort are returned.</p></dd>
<dt><code>last_n: int | None</code></dt><dd><p>When set, return only the most recent <em>n</em> records (after all
other filters). Useful for sliding-window baseline calculations.</p></dd>
<dt><code>successful_only: bool</code></dt><dd><p>Passed through to :func:<code>load_records</code>.</p></dd>
<dt><code>baseline_eligible_only: bool</code></dt><dd><p>Passed through to :func:<code>load_records</code>.</p></dd>
</dl>
<h3>Returns</h3>
<dl>
<dt><code>list[dict[str, Any]]</code></dt><dd><p>List of matching dicts sorted by timestamp ascending.</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def load_records_for_model(
    local_dir: str,
    model_id: str,
    gpu_type: str | None = None,
    *,
    workload_id: str | None = None,
    variant_id: str | None = None,
    benchmark_version: str | None = None,
    recipe_fingerprint: str | None = None,
    hardware_profile_id: str | None = None,
    software_profile_id: str | None = None,
    last_n: int | None = None,
    successful_only: bool = True,
    baseline_eligible_only: bool = False,
) -&gt; list&#91;dict&#91;str, Any&#93;&#93;:
    &quot;&quot;&quot;Return records for a specific *model_id*, optionally filtered by cohort.

    Args:
        local_dir: Root directory previously populated by :func:`sync_from_hf`.
        model_id: Matches the ``model_id`` field inside each JSON record.
        gpu_type: When set, only records whose ``gpu_type`` matches are returned.
        workload_id: When set, only records from the same workload are returned.
        variant_id: When set, only records from the same workload variant are returned.
        benchmark_version: When set, only records from the same benchmark version are returned.
        recipe_fingerprint: When set, only records from the same benchmark
            recipe are returned.
        hardware_profile_id: When set, only records from the same hardware
            cohort are returned.
        software_profile_id: When set, only records from the same software
            cohort are returned.
        last_n: When set, return only the most recent *n* records (after all
            other filters). Useful for sliding-window baseline calculations.
        successful_only: Passed through to :func:`load_records`.
        baseline_eligible_only: Passed through to :func:`load_records`.

    Returns:
        List of matching dicts sorted by timestamp ascending.
    &quot;&quot;&quot;
    model_dir = os.path.join(local_dir, sanitize(model_id))
    if not os.path.isdir(model_dir):
        return &#91;&#93;

    records = load_records(
        model_dir,
        successful_only=successful_only,
        baseline_eligible_only=baseline_eligible_only,
    )

    if gpu_type is not None:
        records = &#91;r for r in records if r.get(&quot;gpu_type&quot;) == gpu_type&#93;

    identity_filters = &#123;
        &quot;workload_id&quot;: workload_id,
        &quot;variant_id&quot;: variant_id,
        &quot;benchmark_version&quot;: benchmark_version,
        &quot;recipe_fingerprint&quot;: recipe_fingerprint,
        &quot;hardware_profile_id&quot;: hardware_profile_id,
        &quot;software_profile_id&quot;: software_profile_id,
    &#125;
    for key, expected in identity_filters.items():
        if expected is not None:
            records = &#91;r for r in records if str(r.get(key)) == str(expected)&#93;

    if last_n is not None:
        records = records&#91;-last_n:&#93;

    return records</code></pre></details>
<h2 id="fastvideo.performance.hf_store.load_records_for_identity"><code>fastvideo.performance.hf_store.load_records_for_identity</code></h2>
<pre class="doc-signature"><code>load_records_for_identity(local_dir: str, identity_filters: dict&#91;str, str&#93;, *, last_n: int | None = None, successful_only: bool = True, baseline_eligible_only: bool = False) -&gt; list&#91;dict&#91;str, Any&#93;&#93;</code></pre>
<p>Return records matching comparable identity fields.</p>
<p>V2 performance comparison is intentionally independent from the legacy
<code>model_id</code> directory and <code>gpu_type</code> display string. The comparable
identity filters usually contain the full v2 comparison key, and may also
contain a subset when looking for same-cohort recipe mismatches.</p>
<details><summary>Source</summary><pre><code>def load_records_for_identity(
    local_dir: str,
    identity_filters: dict&#91;str, str&#93;,
    *,
    last_n: int | None = None,
    successful_only: bool = True,
    baseline_eligible_only: bool = False,
) -&gt; list&#91;dict&#91;str, Any&#93;&#93;:
    &quot;&quot;&quot;Return records matching comparable identity fields.

    V2 performance comparison is intentionally independent from the legacy
    ``model_id`` directory and ``gpu_type`` display string. The comparable
    identity filters usually contain the full v2 comparison key, and may also
    contain a subset when looking for same-cohort recipe mismatches.
    &quot;&quot;&quot;
    records = load_records(
        local_dir,
        successful_only=successful_only,
        baseline_eligible_only=baseline_eligible_only,
    )

    for key, expected in identity_filters.items():
        records = &#91;r for r in records if str(r.get(key)) == str(expected)&#93;

    if last_n is not None:
        records = records&#91;-last_n:&#93;

    return records</code></pre></details>
<h2 id="fastvideo.performance.hf_store.normalize_dataframe"><code>fastvideo.performance.hf_store.normalize_dataframe</code></h2>
<pre class="doc-signature"><code>normalize_dataframe(df: pd.DataFrame) -&gt; pd.DataFrame</code></pre>
<p>Apply standard type coercions to a raw records DataFrame.</p>
<ul>
<li>Parses <code>timestamp</code> to UTC-aware datetime.</li>
<li>Coerces <code>latency</code>, <code>throughput</code>, <code>memory</code>, <code>text_encoder_time_s</code>,
  <code>dit_time_s</code>, <code>vae_decode_time_s</code> to float.</li>
<li>Adds a <code>config_id</code> column (first 7 chars of <code>commit_sha</code>).</li>
</ul>
<p>Returns the mutated DataFrame (also modifies in place for efficiency).</p>
<details><summary>Source</summary><pre><code>def normalize_dataframe(df: pd.DataFrame) -&gt; pd.DataFrame:
    &quot;&quot;&quot;Apply standard type coercions to a raw records DataFrame.

    - Parses ``timestamp`` to UTC-aware datetime.
    - Coerces ``latency``, ``throughput``, ``memory``, ``text_encoder_time_s``,
      ``dit_time_s``, ``vae_decode_time_s`` to float.
    - Adds a ``config_id`` column (first 7 chars of ``commit_sha``).

    Returns the mutated DataFrame (also modifies in place for efficiency).
    &quot;&quot;&quot;
    if df.empty:
        return df

    df&#91;&quot;timestamp&quot;&#93; = pd.to_datetime(df&#91;&quot;timestamp&quot;&#93;, utc=True, errors=&quot;coerce&quot;)
    df&#91;&quot;config_id&quot;&#93; = df.get(&quot;commit_sha&quot;, pd.Series(dtype=str)).fillna(&quot;unknown&quot;).str&#91;:7&#93;

    for col in _NUMERIC_COLS:
        if col in df.columns:
            df&#91;col&#93; = pd.to_numeric(df&#91;col&#93;, errors=&quot;coerce&quot;)

    return df</code></pre></details>
<h2 id="fastvideo.performance.hf_store.load_as_dataframe"><code>fastvideo.performance.hf_store.load_as_dataframe</code></h2>
<pre class="doc-signature"><code>load_as_dataframe(local_dir: str, *, days: int | None = None, successful_only: bool = False) -&gt; pd.DataFrame</code></pre>
<p>Load and normalize records from <em>local_dir</em> into a pandas DataFrame.</p>
<p>Combines :func:<code>load_records</code> + :func:<code>normalize_dataframe</code> into a single
call for consumers (e.g. the dashboard) that work exclusively with
DataFrames.</p>
<h3>Parameters</h3>
<dl>
<dt><code>local_dir: str</code></dt><dd><p>Root directory previously populated by :func:<code>sync_from_hf</code>.</p></dd>
<dt><code>days: int | None</code></dt><dd><p>Passed through to :func:<code>load_records</code>.</p></dd>
<dt><code>successful_only: bool</code></dt><dd><p>Passed through to :func:<code>load_records</code>.</p></dd>
</dl>
<h3>Returns</h3>
<dl>
<dt><code>pd.DataFrame</code></dt><dd><p>Normalized DataFrame, or an empty DataFrame if no records were found.</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def load_as_dataframe(
    local_dir: str,
    *,
    days: int | None = None,
    successful_only: bool = False,
) -&gt; pd.DataFrame:
    &quot;&quot;&quot;Load and normalize records from *local_dir* into a pandas DataFrame.

    Combines :func:`load_records` + :func:`normalize_dataframe` into a single
    call for consumers (e.g. the dashboard) that work exclusively with
    DataFrames.

    Args:
        local_dir: Root directory previously populated by :func:`sync_from_hf`.
        days: Passed through to :func:`load_records`.
        successful_only: Passed through to :func:`load_records`.

    Returns:
        Normalized DataFrame, or an empty DataFrame if no records were found.
    &quot;&quot;&quot;
    records = load_records(local_dir, days=days, successful_only=successful_only)
    if not records:
        return pd.DataFrame()

    df = pd.DataFrame(records)
    return normalize_dataframe(df)</code></pre></details>
</div>
