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

# getFileStream()

> Retrieve file content as a streaming response.

<CodeGroup>
  ```typescript TypeScript theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  // Get file from default branch
  const resp = await repo.getFileStream({ path: 'README.md' });
  const text = await resp.text();
  console.log(text);

  // Get file from specific branch, tag, or commit
  const historicalResp = await repo.getFileStream({
    path: 'package.json',
    ref: 'v1.0.0', // branch name, tag, or commit SHA
  });
  const historicalText = await historicalResp.text();

  // Fetch from the ephemeral namespace
  const ephemeralResp = await repo.getFileStream({
    path: 'notes.md',
    ref: 'feature/demo-work',
    ephemeral: true,
  });

  const rangedResp = await repo.getFileStream({
    path: 'README.md',
    headers: { range: 'bytes=0-1023' },
  });
  console.log(rangedResp.status, rangedResp.headers.get('content-range'));
  ```

  ```python Python theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  resp = await repo.get_file_stream(
      path="README.md",
      ref="main",       # optional, defaults to the default branch
      ephemeral=False,   # set True to read from the ephemeral namespace
  )
  text = await resp.aread()
  print(text.decode())

  historical_resp = await repo.get_file_stream(
      path="package.json",
      ref="v1.0.0",  # branch name, tag, or commit SHA
  )
  historical_text = await historical_resp.aread()

  # Fetch from the ephemeral namespace
  ephemeral_resp = await repo.get_file_stream(
      path="notes.md",
      ref="feature/demo-work",
      ephemeral=True,
  )

  ranged_resp = await repo.get_file_stream(
      path="README.md",
      headers={"range": "bytes=0-1023"},
  )
  print(ranged_resp.status_code, ranged_resp.headers.get("content-range"))
  ```

  ```go Go theme={null} theme={"theme":{"light":"github-light","dark":"min-dark"}}
  // Get file content as a stream
  resp, err := repo.FileStream(context.Background(), storage.GetFileOptions{
  	Path: "README.md",
  	Ref:  "main",
  })
  if err != nil {
  	fmt.Printf("Failed to fetch file: %v\n", err)
  	return
  }
  defer resp.Body.Close()
  body, err := io.ReadAll(resp.Body)
  if err != nil {
  	fmt.Printf("Failed to read file: %v\n", err)
  	return
  }
  fmt.Println(string(body))

  // Fetch from the ephemeral namespace
  ephemeral := true
  ephemeralResp, err := repo.FileStream(context.Background(), storage.GetFileOptions{
  	Path:      "notes.md",
  	Ref:       "feature/demo-work",
  	Ephemeral: &ephemeral,
  })
  if err != nil {
  	fmt.Printf("Failed to read ephemeral file: %v\n", err)
  	return
  }
  defer ephemeralResp.Body.Close()

  rangedResp, err := repo.FileStream(context.Background(), storage.GetFileOptions{
  	Path: "README.md",
  	Headers: storage.FileRequestHeaders{
  		Range: "bytes=0-1023",
  	},
  })
  if err != nil {
  	fmt.Printf("Failed to fetch range: %v\n", err)
  	return
  }
  defer rangedResp.Body.Close()
  fmt.Println(rangedResp.StatusCode, rangedResp.Header.Get("Content-Range"))
  ```
</CodeGroup>

## Options

<ParamField path="path" type="string" required>
  Path to the file within the repository
</ParamField>

<ParamField path="ref" type="string">
  Branch name, tag, or commit SHA. Defaults to the default branch.
</ParamField>

<ParamField path="ephemeral" type="boolean">
  When `true`, resolves the ref under the ephemeral namespace.
</ParamField>

<ParamField path="ephemeralBase" type="boolean">
  When `true`, resolves the base branch under the ephemeral namespace. TypeScript: `ephemeralBase`;
  Python: `ephemeral_base`; Go: `EphemeralBase`.
</ParamField>

<ParamField path="headers.range" type="string">
  HTTP `Range` header, such as `bytes=0-1023`. TypeScript/Python: `range`; Go: `Range`.
</ParamField>

<ParamField path="headers.ifMatch" type="string">
  HTTP `If-Match` header. TypeScript: `ifMatch`; Python: `if_match`; Go: `IfMatch`.
</ParamField>

<ParamField path="headers.ifNoneMatch" type="string">
  HTTP `If-None-Match` header. TypeScript: `ifNoneMatch`; Python: `if_none_match`; Go:
  `IfNoneMatch`.
</ParamField>

<ParamField path="headers.ifModifiedSince" type="string">
  HTTP `If-Modified-Since` header. TypeScript: `ifModifiedSince`; Python: `if_modified_since`; Go:
  `IfModifiedSince`.
</ParamField>

<ParamField path="headers.ifUnmodifiedSince" type="string">
  HTTP `If-Unmodified-Since` header. TypeScript: `ifUnmodifiedSince`; Python: `if_unmodified_since`;
  Go: `IfUnmodifiedSince`.
</ParamField>

<ParamField path="headers.ifRange" type="string">
  HTTP `If-Range` header. TypeScript: `ifRange`; Python: `if_range`; Go: `IfRange`.
</ParamField>

<ParamField path="ttl" type="number">
  Token TTL in seconds.
</ParamField>

## Returns

Returns a standard Fetch `Response` object (TypeScript), an async response object (Python), or an
`*http.Response` (Go) that can be used to stream or read the file content.

When range or conditional headers are provided, statuses `206`, `304`, `412`, and `416` are returned
to the caller with their response headers.
