Upload Files

This example shows how to upload files to your Athena workspace and manage them using the Tools API. You can upload various file types including PDFs, Excel files, CSVs, and images.

Key features:

  • Upload files from Node.js filesystem or browser
  • Support for multiple file types (PDF, Excel, CSV, images)
  • File management with workspace browsing
  • Retrieve file content and metadata
  • Full TypeScript support with proper error handling
1

Install Package

$pnpm add athena-intelligence
2

Set Up Client

1import { readFileSync } from 'node:fs';
2import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'athena-intelligence';
3
4// Basic client setup (uses default production API)
5const client = new AthenaIntelligenceClient({
6 apiKey: process.env.ATHENA_API_KEY,
7});
8
9// Override baseUrl for custom API endpoints
10const customClient = new AthenaIntelligenceClient({
11 apiKey: process.env.ATHENA_API_KEY,
12 baseUrl: 'https://your-custom-api.example.com', // Custom API endpoint
13});
3

Browse Workspace Contents

Before uploading, you can list existing files and folders in your workspace. The listContents method provides a comprehensive view of your workspace structure:

1// List entire workspace contents
2try {
3 console.log('📂 Listing workspace contents…');
4 const workspaceContents = await client.tools.listContents();
5
6 // The response includes both structured data and a visual tree
7 console.log('Workspace structure (ASCII tree):');
8 console.log(workspaceContents.structure_tree_ascii);
9
10 console.log('Detailed tree data:');
11 console.log(JSON.stringify(workspaceContents.tree_data, null, 2));
12} catch (error) {
13 if (error instanceof AthenaIntelligenceError) {
14 console.error(`Failed to list workspace contents: ${error.statusCode} - ${error.message}`);
15 } else {
16 console.error('Unexpected error:', error);
17 }
18}

Advanced Listing Options

You can customize the listing behavior with optional parameters:

1// List contents of a specific folder with detailed asset information
2const folderContents = await client.tools.listContents({
3 folder_id: 'your-folder-id', // Optional: specific folder to browse
4 include_asset_details: true, // Optional: include detailed asset metadata
5 include_system_files: false, // Optional: exclude system files from results
6});
7
8// List workspace with all details and system files
9const detailedContents = await client.tools.listContents({
10 include_asset_details: true,
11 include_system_files: true,
12});

Response Structure

The listContents method returns a FolderResponse object with:

  • structure_tree_ascii: A visual ASCII tree representation of the folder structure
  • tree_data: Detailed information about each asset and folder, organized as a tree structure
1interface FolderResponse {
2 structure_tree_ascii: string;
3 tree_data: Record<string, AssetNode>;
4}
4

Upload Files from Node.js

Upload files from your local filesystem using the saveAsset method:

1// Upload a file from the filesystem
2const FILE_PATH = process.env.FILE_PATH || 'README.md';
3console.log(`⬆️ Uploading asset: ${FILE_PATH}`);
4
5try {
6 const buffer = readFileSync(FILE_PATH);
7 const file = new File([buffer], FILE_PATH, {
8 type: 'application/octet-stream',
9 });
10
11 const uploadResponse = await client.tools.saveAsset({
12 file,
13 });
14
15 console.log('Upload successful:', JSON.stringify(uploadResponse, null, 2));
16
17 // Save the asset ID for later use
18 const assetId = uploadResponse.asset_id;
19 console.log(`Asset uploaded with ID: ${assetId}`);
20} catch (error) {
21 if (error instanceof AthenaIntelligenceError) {
22 console.error(`Upload failed: ${error.statusCode} - ${error.message}`);
23 } else {
24 console.error('Unexpected error:', error);
25 }
26}
5

Upload Different File Types

Handle various file types with appropriate MIME types:

1// Upload Excel file
2const excelBuffer = readFileSync('data.xlsx');
3const excelFile = new File([excelBuffer], 'data.xlsx', {
4 type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
5});
6
7const excelResult = await client.tools.saveAsset({
8 file: excelFile,
9 name: 'Excel Data File'
10});
11
12// Upload PDF file
13const pdfBuffer = readFileSync('document.pdf');
14const pdfFile = new File([pdfBuffer], 'document.pdf', {
15 type: 'application/pdf'
16});
17
18const pdfResult = await client.tools.saveAsset({
19 file: pdfFile,
20 name: 'PDF Document'
21});
22
23// Upload CSV file
24const csvBuffer = readFileSync('data.csv');
25const csvFile = new File([csvBuffer], 'data.csv', {
26 type: 'text/csv'
27});
28
29const csvResult = await client.tools.saveAsset({
30 file: csvFile,
31 name: 'CSV Data'
32});
33
34// Upload image file
35const imageBuffer = readFileSync('image.png');
36const imageFile = new File([imageBuffer], 'image.png', {
37 type: 'image/png'
38});
39
40const imageResult = await client.tools.saveAsset({
41 file: imageFile,
42 name: 'Image File'
43});
6

Retrieve File Metadata

After uploading, you can retrieve chunk metadata for your files:

1if (assetId) {
2 try {
3 console.log('📑 Fetching chunk metadata…');
4 const chunkMetadata = await client.tools.getAssetChunks({
5 asset_ids: [assetId],
6 });
7 console.log('Chunk metadata:', JSON.stringify(chunkMetadata, null, 2));
8 } catch (error) {
9 if (error instanceof AthenaIntelligenceError) {
10 console.error(`Failed to retrieve chunk metadata: ${error.statusCode} - ${error.message}`);
11 } else {
12 console.error('Unexpected error:', error);
13 }
14 }
15}
7

Download File Content

Retrieve the processed content of uploaded files:

1if (assetId) {
2 try {
3 console.log('📥 Downloading asset content…');
4 const contentResponse = await client.tools.getAssetContent({
5 asset_id: assetId,
6 });
7 console.log('Asset content:', JSON.stringify(contentResponse, null, 2));
8 } catch (error) {
9 if (error instanceof AthenaIntelligenceError) {
10 console.error(`Failed to download asset content: ${error.statusCode} - ${error.message}`);
11 } else {
12 console.error('Unexpected error:', error);
13 }
14 }
15}
8

Upload from Browser

When working in a browser environment with file inputs:

1// HTML: <input type="file" id="fileInput" />
2const fileInput = document.getElementById('fileInput') as HTMLInputElement;
3
4fileInput.addEventListener('change', async (event) => {
5 const file = (event.target as HTMLInputElement).files?.[0];
6
7 if (file) {
8 try {
9 const result = await client.tools.saveAsset({
10 file: file,
11 name: file.name
12 });
13 console.log('Upload successful:', result);
14 } catch (error) {
15 if (error instanceof AthenaIntelligenceError) {
16 console.error(`Upload failed: ${error.statusCode} - ${error.message}`);
17 } else {
18 console.error('Unexpected error:', error);
19 }
20 }
21 }
22});
9

Upload to Specific Folder

You can organize files by uploading to specific folders:

1const result = await client.tools.saveAsset({
2 file: file,
3 name: "My Document",
4 parent_folder_id: "folder_123456"
5});
10

Complete File Management Example

Here’s a complete example that demonstrates the full file management workflow:

1import { readFileSync } from 'node:fs';
2import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'athena-intelligence';
3
4async function runFileManagementExample() {
5 try {
6 const client = new AthenaIntelligenceClient({
7 apiKey: process.env.ATHENA_API_KEY,
8 // Optional: override baseUrl for custom environments
9 // baseUrl: 'https://your-custom-api.example.com',
10 });
11
12 let assetId: string | undefined;
13
14 // Step 1: List workspace contents
15 console.log('📂 Listing workspace contents…');
16 const listResponse = await client.tools.listContents();
17 console.log('Workspace contents:', JSON.stringify(listResponse, null, 2));
18
19 // Step 2: Upload a file
20 const FILE_PATH = process.env.FILE_PATH || 'README.md';
21 console.log(`⬆️ Uploading asset: ${FILE_PATH}`);
22
23 const buffer = readFileSync(FILE_PATH);
24 const file = new File([buffer], FILE_PATH, {
25 type: 'application/octet-stream',
26 });
27
28 const uploadResponse = await client.tools.saveAsset({
29 file,
30 });
31
32 console.log('Upload successful:', JSON.stringify(uploadResponse, null, 2));
33 assetId = uploadResponse.asset_id;
34
35 if (!assetId) {
36 console.warn('Could not determine asset_id from upload response');
37 return;
38 }
39
40 // Step 3: Retrieve chunk metadata
41 console.log('📑 Fetching chunk metadata…');
42 const chunkMetadata = await client.tools.getAssetChunks({
43 asset_ids: [assetId],
44 });
45 console.log('Chunk metadata:', JSON.stringify(chunkMetadata, null, 2));
46
47 // Step 4: Download asset content
48 console.log('📥 Downloading asset content…');
49 const contentResponse = await client.tools.getAssetContent({
50 asset_id: assetId,
51 });
52 console.log('Asset content:', JSON.stringify(contentResponse, null, 2));
53
54 console.log('âś… File management example completed');
55 } catch (error) {
56 if (error instanceof AthenaIntelligenceError) {
57 console.error(`Athena API error (${error.statusCode}): ${error.message}`);
58 } else {
59 console.error('Unexpected error:', error);
60 }
61 }
62}
63
64runFileManagementExample();
11

Using with Express.js

If you’re building a web application with Express.js and multer:

1import express from 'express';
2import multer from 'multer';
3import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'athena-intelligence';
4
5const app = express();
6const upload = multer();
7const client = new AthenaIntelligenceClient({
8 apiKey: process.env.ATHENA_API_KEY,
9 // Optional: override baseUrl for custom environments
10 // baseUrl: 'https://your-custom-api.example.com',
11});
12
13app.post('/upload', upload.single('file'), async (req, res) => {
14 if (!req.file) {
15 return res.status(400).json({ error: 'No file provided' });
16 }
17
18 try {
19 const file = new File([req.file.buffer], req.file.originalname, {
20 type: req.file.mimetype
21 });
22
23 const result = await client.tools.saveAsset({
24 file: file,
25 name: req.file.originalname
26 });
27
28 res.json({
29 message: 'File uploaded successfully',
30 asset_id: result.asset_id,
31 result
32 });
33 } catch (error) {
34 if (error instanceof AthenaIntelligenceError) {
35 console.error(`Upload error: ${error.statusCode} - ${error.message}`);
36 res.status(error.statusCode || 500).json({
37 error: 'Upload failed',
38 message: error.message
39 });
40 } else {
41 console.error('Unexpected upload error:', error);
42 res.status(500).json({ error: 'Upload failed' });
43 }
44 }
45});
46
47app.listen(3000, () => {
48 console.log('Server running on port 3000');
49});