Skip to main content

Work with storage objects

Upload files, download them, update their metadata, and delete them. The examples use a bucket with slug BUCKET_SLUG and a file at users/123/avatar.png.

Choose an interface below. REST examples use a server-side API key; keep it out of browser code.

Configure client with the JavaScript SDK setup or the synchronous Python client setup. For Refine, register the named storage provider and initialize these hooks inside a React component or custom hook under <Refine>. Browser examples use the signed-in user session; keep API keys in server code. Replace BUCKET_SLUG with your bucket slug.

Upload a file#

import {Storage} from '@taruvi/sdk';
import type {StorageUploadBatchResponse} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG').upload({
files: [file],
paths: ['users/123/avatar.png'],
metadatas: [{user_id: '123'}],
}).execute<StorageUploadBatchResponse>();

file is a browser File. The response’s data.successful lists uploaded objects; check data.failed for per-file errors.

The SDK upload methods call POST …/objects/batch-upload/. The call succeeds with 200 when every file uploads and 207 when some don't, and a rejected file doesn't raise: check the response’s data.failed in JavaScript or the returned dictionary’s failed list in Python for each file's error.

The single-file REST upload returns 201 Created; uploading to an existing path replaces the file. The response includes the file's file_path, size, mimetype, metadata, and effective visibility. A file is rejected, with 400 from the single-file upload or an entry in failed from a batch, when:

  • the file is empty;
  • the file is larger than the bucket's file size limit;
  • the bucket restricts file types and this type isn't allowed (wildcards such as image/* are supported);
  • the metadata is larger than 2 KB.

Download a file#

import {Storage} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG')
.download('users/123/avatar.png').execute<Blob>();

The result is the file's content as a Blob.

Anyone can download a public file without a credential. A private file needs a caller whom the bucket's policy allows to read it; otherwise the request returns 403. A 404 means no file exists at that path — paths are case-sensitive.

Update metadata#

import {Storage} from '@taruvi/sdk';
import type {StorageResponse} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG')
.update('users/123/avatar.png', {metadata: {status: 'verified'}})
.execute<StorageResponse>();

The response’s data contains the updated object.

PATCH changes details only. To replace the file itself, upload to the same path again. A file's visibility always follows its bucket; to change it, update the bucket's visibility.

Delete a file#

File deletion is permanent

Deleting removes the file from TaruviBase and from the storage provider. There is no recycle bin. The caller needs a policy rule that allows delete — neither default bucket policy includes one. The SDK delete methods call POST …/objects/batch-delete/ and don't raise when a file is missing or the policy denies the delete; those paths come back in failed. Check that deleted_count equals the number of paths you sent. See Security and limits.

import {Storage} from '@taruvi/sdk';
import type {StorageDeleteBatchResponse} from '@taruvi/sdk';

await new Storage(client).from('BUCKET_SLUG')
.delete(['users/123/avatar.png']).execute<StorageDeleteBatchResponse>();