> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siftstack.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Import data from a file

> Import a telemetry file into Sift and start analyzing your data.

export const MintTable = ({columns = [], rows = [], columnWidths = []}) => {
  const pushTextWithLineBreaks = (parts, text, keyBase) => {
    const segments = String(text).split(/\\n|\n/);
    segments.forEach((segment, idx) => {
      if (segment) {
        parts.push(<span key={`${keyBase}-text-${idx}`}>{segment}</span>);
      }
      if (idx < segments.length - 1) {
        parts.push(<br key={`${keyBase}-br-${idx}`} />);
      }
    });
  };
  const parseMarkdown = text => {
    if (text === null || text === undefined) return "";
    const str = String(text);
    const parts = [];
    let lastIndex = 0;
    const pattern = /(`[^`]+`|\*\*[^*]+\*\*|\*[^*]+\*|\[([^\]]+)\]\(([^)]+)\))/g;
    let match;
    while (true) {
      match = pattern.exec(str);
      if (match === null) {
        break;
      }
      if (match.index > lastIndex) {
        pushTextWithLineBreaks(parts, str.substring(lastIndex, match.index), `before-${lastIndex}`);
      }
      const fullMatch = match[0];
      if (fullMatch.startsWith("`") && fullMatch.endsWith("`")) {
        parts.push(<code key={match.index}>{fullMatch.slice(1, -1)}</code>);
      } else if (fullMatch.startsWith("**") && fullMatch.endsWith("**")) {
        parts.push(<strong key={match.index}>{fullMatch.slice(2, -2)}</strong>);
      } else if (fullMatch.startsWith("*") && fullMatch.endsWith("*")) {
        parts.push(<em key={match.index}>{fullMatch.slice(1, -1)}</em>);
      } else if (fullMatch.startsWith("[")) {
        const linkText = match[2];
        const linkUrl = match[3];
        parts.push(<a key={match.index} href={linkUrl} className="text-black-600 dark:text-black-400">
            {linkText}
          </a>);
      }
      lastIndex = pattern.lastIndex;
    }
    if (lastIndex < str.length) {
      pushTextWithLineBreaks(parts, str.substring(lastIndex), `tail-${lastIndex}`);
    }
    if (parts.length > 0) {
      return parts;
    }
    const plainParts = [];
    pushTextWithLineBreaks(plainParts, str, "plain");
    return plainParts.length ? plainParts : str;
  };
  const safeColumns = Array.isArray(columns) ? columns : [];
  const safeRows = Array.isArray(rows) ? rows : [];
  const safeColumnWidths = Array.isArray(columnWidths) ? columnWidths : [];
  const hasColumnWidths = safeColumnWidths.some(w => w !== null && w !== undefined && w !== "");
  const toCssWidth = width => typeof width === "number" ? `${width}px` : String(width);
  const getColumnStyle = idx => {
    const rawWidth = safeColumnWidths[idx];
    if (rawWidth === null || rawWidth === undefined || rawWidth === "") {
      return undefined;
    }
    const width = toCssWidth(rawWidth);
    return {
      width,
      minWidth: width
    };
  };
  const containerStyle = hasColumnWidths ? undefined : {
    overflowX: "auto"
  };
  const tableStyle = hasColumnWidths ? {
    tableLayout: "fixed",
    width: "100%"
  } : {
    width: "max-content",
    minWidth: "100%"
  };
  if (!Array.isArray(columns) || !Array.isArray(rows) || !Array.isArray(columnWidths)) {
    console.warn("MintTable received invalid props:", {
      columns,
      rows,
      columnWidths
    });
  }
  if (!safeColumns.length && !safeRows.length) {
    return null;
  }
  return <div className="mint-table-container" style={containerStyle}>
      <table style={tableStyle}>
        {hasColumnWidths && <colgroup>
            {safeColumns.map((_, idx) => {
    const style = getColumnStyle(idx);
    return <col key={idx} style={style} />;
  })}
          </colgroup>}
        <thead>
          <tr>
            {safeColumns.map((col, idx) => <th key={idx} className="text-left" style={getColumnStyle(idx)}>
                <b>{parseMarkdown(col)}</b>
              </th>)}
          </tr>
        </thead>
        <tbody>
          {safeRows.map((row, rIdx) => {
    const safeRow = Array.isArray(row) ? row : [];
    return <tr key={rIdx}>
                {safeRow.map((cell, cIdx) => <td key={cIdx} style={getColumnStyle(cIdx)}>
                    {parseMarkdown(cell)}
                  </td>)}
              </tr>;
  })}
        </tbody>
      </table>
    </div>;
};

After completing this workflow, you can upload a local file to Sift and have its Channels available for investigation in Explore.

## Before you begin

* Choose the import method that fits your use case. Supported file types vary by method.
  <MintTable
    columns={['Method', 'Best for', 'Requires', 'Supported file types']}
    columnWidths={['20%', '35%', '25%', '20%']}
    rows={[
  ['UI', 'One-off imports; verify mapping visually before committing', 'Browser access', 'CSV, Parquet, TDMS, HDF5, ULog'],
  ['REST API', 'Repeatable or automated ingestion pipelines', '[API key](/documentation/manage/set-up-api-access)', 'CSV, Parquet, TDMS, HDF5, ULog'],
  ['Python client', 'Scripted ingestion, preprocessing, or engineering tool integration', '[API key](/documentation/manage/set-up-api-access); Python environment', 'CSV, Parquet, TDMS, HDF5, ULog'],
  ['[Sift CLI](https://github.com/sift-stack/sift/blob/main/rust/crates/sift_cli/assets/docs/src/introduction.md)', 'Quick command-line imports without writing code', 'Sift CLI installed; [API key](/documentation/manage/set-up-api-access)', 'CSV, Parquet, TDMS, HDF5, ULog'],
  ]}
  />
* Your file includes a timestamp column in a [supported timestamp format](/documentation/reference/supported-file-formats#timestamp-formats).
* You know which Asset and Run the data belongs to, or are prepared to create new ones.

## How data file import works

Importing a file creates a Run under an [Asset](/documentation/ingest/stream/organize-streamed-data-into-assets-and-runs) in Sift. An Asset represents the system that generated the data, such as a vehicle or test rig. A [Run](/documentation/reference/runs-reference) is a single data collection session.

During import, you map the file's timestamp column and data columns to Channels. You do not need to import every column, only map the ones you intend to analyze. You can use an existing Asset and Run or create new ones during import.

If a mapping is wrong or a timestamp format is misidentified, you can archive the Run and reimport without affecting the Asset or other Runs.

## Import a file using the UI

1. On the Sift homepage, click **Import data**.
2. Select your file.
3. Configure the import settings. See [Import file settings](/documentation/reference/supported-file-formats#import-file-settings) for a full description of each setting.
4. Click **Upload**.

## Import a file using the REST API

1. Send a configuration request to the [`CreateDataImportFromUpload`](/api-reference/dataimportservice/createdataimportfromupload) endpoint with your [API key](/documentation/manage/set-up-api-access). The endpoint accepts a format-specific configuration object depending on your file type.
   * **Remote URL**: To import a file from a remote URL instead of uploading it directly, use the [`CreateDataImportFromUrl`](/api-reference/dataimportservice/createdataimportfromurl) endpoint.
2. Upload the file using the returned `uploadUrl`.
3. Optional: Verify the upload using the returned `dataImportId`.

<Note>
  Sift queues the import server-side the moment the request is received. A client-side timeout on the upload request does not indicate the import failed or was not received. To confirm whether an import actually failed, poll the import status and check for `DATA_IMPORT_STATUS_FAILED`. Any other status means the import is queued or in progress. See [DataImportStatus](/api/reference/protocol-buffers/data_imports#dataimportstatus) for more information.
</Note>

## Import a file using the Python client

1. Install the [Python client](https://sift-stack.github.io/sift/python/latest/).
2. Configure the client with your [API key](/documentation/manage/set-up-api-access) and Sift URL.
3. Upload the file using the appropriate upload service for your format. For code examples, see the [Sift public repository](https://github.com/sift-stack/sift/tree/main/python/examples/data_import).

## Import a file using the Sift CLI

Use the `sift-cli import` command to import a file from the command line. See the [Sift CLI getting started guide](https://github.com/sift-stack/sift/blob/main/rust/crates/sift_cli/assets/docs/src/introduction.md) to learn more.

## Verify

Your file appears as a Run under the selected Asset. Open the Run in [Explore](/documentation/reference/explore-settings) to confirm the Channels loaded correctly.

## Reference

* [File formats for import and export](/documentation/reference/supported-file-formats)
