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

# Upload

You can use the `files.write()` method to upload data to the sandbox.

Before running the example code in this document, please ensure you have properly configured environment variables. For details, please refer to Configure Environment Variables.

***

## Upload single file

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import fs from 'fs'
  import { Novita } from 'novita-sandbox'

  const novita = new Novita()
  const sandbox = await novita.codeInterpreter.create()

  // Read file from local filesystem
  const localFilePath = '../local-test-file'
  const content = fs.readFileSync(localFilePath, 'utf8')

  // Upload file to sandbox
  const filePathInSandbox = '/tmp/test-file'
  const result = await sandbox.files.write(filePathInSandbox, content)
  console.log(result)

  await sandbox.kill()
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox import Novita

  novita = Novita()
  sandbox = novita.code_interpreter.create()

  local_file_path = '../local-test-file'
  with open(local_file_path, 'rb') as file:
      file_path_in_sandbox = '/tmp/test-file'
      result = sandbox.files.write(file_path_in_sandbox, file)
      print(result)

  sandbox.kill()
  ```
</CodeGroup>

***

## Upload with pre-signed URL

Pre-signed upload URLs allow users to upload files securely from environments that do not hold Novita SDK credentials, such as web browsers. Create the sandbox with the `secure: true` option, then use the SDK on your trusted backend to generate the upload URL. Return it only to users authorized by your application, and set a short expiration time. The URL acts as a temporary bearer credential until it expires.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Novita } from 'novita-sandbox'

  const novita = new Novita()
  const sandbox = await novita.codeInterpreter.create({ secure: true })

  const filePathInSandbox = '/tmp/test-file'

  // Generate pre signature upload URL
  const publicUploadUrl = await sandbox.uploadUrl(filePathInSandbox, {
    useSignatureExpiration: 120, // optional, in seconds
  })

  // Simulate browser behavior
  const form = new FormData()
  form.append('file', new Blob(['file content']), 'test-file')

  const uploadRes = await fetch(publicUploadUrl, {
    method: 'POST',
    body: form,
  })
  if (!uploadRes.ok) {
    throw new Error(`Upload failed: ${uploadRes.status} ${await uploadRes.text()}`)
  }

  // SDK Read Back Verification
  const result = await sandbox.files.read(filePathInSandbox)
  console.log(result)

  await sandbox.kill()
  ```

  ```python Python icon="python" theme={"system"}
  from pathlib import Path

  import requests
  from novita_sandbox import Novita

  novita = Novita()
  sandbox = novita.code_interpreter.create(secure=True)

  local_file_path = Path('../local-test-file')
  file_path_in_sandbox = '/tmp/test-file'

  # Generate pre signature upload URL
  signed_url = sandbox.upload_url(
      path=file_path_in_sandbox,
      use_signature_expiration=120,  # optional, in seconds
  )

  # Simulate browser behavior
  with open(local_file_path, 'rb') as f:
      response = requests.post(
          signed_url,
          files={'file': (local_file_path.name, f)},
          timeout=60,
      )
  response.raise_for_status()

  # SDK Read Back Verification
  result = sandbox.files.read(file_path_in_sandbox)
  print(result)

  sandbox.kill()
  ```
</CodeGroup>

***

## Upload directory / multiple files

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import fs from 'fs'
  import path from 'path'
  import { Novita } from 'novita-sandbox'

  const novita = new Novita()
  const sandbox = await novita.codeInterpreter.create()

  const readDirectoryFiles = (directoryPath) => {
    const files = fs.readdirSync(directoryPath)

    const filesArray = files
      .filter((file) => {
        const fullPath = path.join(directoryPath, file)
        return fs.statSync(fullPath).isFile()
      })
      .map((file) => {
        const filePath = path.join(directoryPath, file)

        return {
          path: filePath,
          data: fs.readFileSync(filePath, 'utf8'),
        }
      })

    return filesArray
  }

  const localDirectoryPath = '../local-test-dir'
  const files = readDirectoryFiles(localDirectoryPath)
  console.log(files)

  files.forEach((file) => {
    file.path = file.path.replace('../local-test-dir', '/tmp')
  })

  const result = await sandbox.files.write(files)
  console.log(result)

  await sandbox.kill()
  ```

  ```python Python icon="python" theme={"system"}
  import os
  from novita_sandbox import Novita

  novita = Novita()
  sandbox = novita.code_interpreter.create()

  def read_directory_files(directory_path):
      files = []

      for filename in os.listdir(directory_path):
          file_path = os.path.join(directory_path, filename)

          if os.path.isfile(file_path):
              with open(file_path, 'rb') as file:
                  files.append({
                      'path': file_path,
                      'data': file.read(),
                  })
      return files

  local_directory_path = '../local-test-dir'
  files = read_directory_files(local_directory_path)
  print(files)

  for file in files:
      file['path'] = file['path'].replace('../local-test-dir', '/tmp')

  result = sandbox.files.write_files(files)
  print(result)

  sandbox.kill()
  ```
</CodeGroup>
