Global Files API
Manage global files in the sapienstream-global bucket. Supports component files (GSDML, EDS, datasheets), Nelo knowledge base documents, and miscellaneous files. Includes deduplication, vector indexing, and Nelo AI processing.
Overview
File Categories
- • component_file: Device descriptions, datasheets
- • nelo_knowledge: AI training documents
- • miscellaneous: General purpose files
Features
- • SHA256 content deduplication
- • Vector indexing for Nelo AI
- • Public URLs for component files
- • Bulk upload for archives
File Categories & Limits
Max Size: 50MB
Public: Yes
Extensions: .xml, .gsdml, .csp, .eds, .gds, .edsx, .dcf, .xdd, .xdc, .pdf, etc.
Max Size: 100MB
Public: No
Extensions: .pdf, .md, .txt, .docx, .json, .csv
Max Size: 200MB
Public: No
Extensions: All allowed
File Upload
Admin Only: General upload endpoint requires system administrator privileges.
/v1/global-files/uploadAuth RequiredRequest Body
// multipart/form-data
file: [binary data] // Required: File to upload
category: "component_file" // Required: component_file, nelo_knowledge, or miscellaneous
subcategory: "datasheet" // Optional: Subcategory within category
component_id: "comp_abc123" // Required for component_file: Links to component
relative_path: "vendor/model" // Optional: Folder path within category
description: "Component datasheet" // Optional: File description
tags: "siemens,sensor,temperature" // Optional: Comma-separated tagsResponse
{
"id": "gfile_abc123",
"category": "component_file",
"subcategory": "datasheet",
"bucket_name": "sapienstream-global",
"object_key": "component-files/comp_abc123/datasheet.pdf",
"filename": "TE01_datasheet.pdf",
"mime_type": "application/pdf",
"file_size": 1234567,
"sha256_hash": "a7ffc6f8bf1ed76651c14756a061d662...",
"public_url": "https://minio.sapienstream.com/sapienstream-global/component-files/comp_abc123/datasheet.pdf",
"component_id": "comp_abc123",
"description": "Component datasheet",
"tags": ["siemens", "sensor", "temperature"],
"is_content_duplicate": false,
"vector_indexed": false,
"available_to_nelo": false,
"created_at": "2024-08-26T15:30:00Z",
"uploaded_by": {
"id": "user_001",
"email": "[email protected]"
}
}Try it out
curl -X POST "https://sapienstream.com/api/v1/global-files/upload" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"/v1/global-files/upload-component-fileAuth RequiredRequest Body
// multipart/form-data
file: [binary data] // Required: PDF file to upload
subcategory: "datasheet" // Optional: Type (datasheet, description, manual)
description: "Temperature sensor specs" // Optional: File descriptionResponse
{
"id": "gfile_def456",
"category": "component_file",
"subcategory": "datasheet",
"bucket_name": "sapienstream-global",
"object_key": "component-files/unassigned/datasheet_abc123.pdf",
"filename": "TE01_datasheet.pdf",
"mime_type": "application/pdf",
"file_size": 1234567,
"sha256_hash": "a7ffc6f8bf1ed76651c14756a061d662...",
"component_id": null,
"description": "Temperature sensor specs",
"created_at": "2024-08-26T15:30:00Z"
}Try it out
curl -X POST "https://sapienstream.com/api/v1/global-files/upload-component-file" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"/v1/global-files/bulk-uploadAuth RequiredRequest Body
// multipart/form-data
file: [binary data] // Required: ZIP or TAR archive
category: "component_file" // Required: Category for all files
subcategory: "vendor-files" // Optional: Subcategory
component_id: "comp_abc123" // Optional: Link all to component
description: "Vendor files package" // Optional: Description for all
tags: "vendor,import" // Optional: Tags for all filesResponse
{
"message": "Bulk upload completed",
"archive_type": "zip",
"files_processed": 15,
"files_succeeded": 14,
"files_failed": 1,
"duplicates_found": 3,
"results": [
{
"filename": "device1.gsdml",
"status": "uploaded",
"file_id": "gfile_001"
},
{
"filename": "device2.gsdml",
"status": "duplicate",
"source_id": "gfile_existing"
},
{
"filename": "invalid.exe",
"status": "failed",
"error": "File extension .exe not allowed"
}
]
}Try it out
curl -X POST "https://sapienstream.com/api/v1/global-files/bulk-upload" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"File Listing
/v1/global-filesAuth RequiredParameters
categorystringFilter by category (component_file, nelo_knowledge, miscellaneous)
component_idstringFilter by linked component
searchstringSearch in filename and description
vector_indexedbooleanFilter by indexing status
pageintegerPage number (default: 1)
per_pageintegerItems per page (default: 20)
Response
{
"files": [
{
"id": "gfile_abc123",
"category": "component_file",
"filename": "TE01_datasheet.pdf",
"file_size": 1234567,
"mime_type": "application/pdf",
"component_id": "comp_abc123",
"vector_indexed": true,
"available_to_nelo": true,
"created_at": "2024-08-26T15:30:00Z"
}
],
"total": 125,
"page": 1,
"per_page": 20,
"pages": 7
}Try it out
curl -X GET "https://sapienstream.com/api/v1/global-files" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"/v1/global-files/components-with-filesAuth RequiredResponse
{
"components": [
{
"id": "comp_abc123",
"name": "Temperature Sensor TE01",
"identifier": "6ES7511-1AK02-0AB0",
"file_count": 3,
"files": [
{
"id": "gfile_001",
"filename": "datasheet.pdf",
"subcategory": "datasheet"
},
{
"id": "gfile_002",
"filename": "description.gsdml",
"subcategory": "description"
}
]
}
],
"total_components": 45
}Try it out
curl -X GET "https://sapienstream.com/api/v1/global-files/components-with-files" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"/v1/global-files/component/{component_id}Auth RequiredParameters
component_idstringRequiredComponent ID
Response
{
"component_id": "comp_abc123",
"files": [
{
"id": "gfile_001",
"filename": "datasheet.pdf",
"subcategory": "datasheet",
"file_size": 1234567,
"vector_indexed": true,
"public_url": "https://..."
},
{
"id": "gfile_002",
"filename": "description.gsdml",
"subcategory": "description",
"file_size": 45678,
"vector_indexed": false
}
],
"total": 2
}Try it out
curl -X GET "https://sapienstream.com/api/v1/global-files/component/{component_id}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"File Operations
/v1/global-files/{file_id}Auth RequiredParameters
file_idstringRequiredGlobal file ID
Response
{
"id": "gfile_abc123",
"category": "component_file",
"subcategory": "datasheet",
"bucket_name": "sapienstream-global",
"object_key": "component-files/comp_abc123/datasheet.pdf",
"filename": "TE01_datasheet.pdf",
"mime_type": "application/pdf",
"file_size": 1234567,
"sha256_hash": "a7ffc6f8bf1ed76651c14756a061d662...",
"public_url": "https://minio.sapienstream.com/...",
"component_id": "comp_abc123",
"description": "Temperature sensor datasheet",
"tags": ["siemens", "sensor"],
"is_content_duplicate": false,
"content_hash_source_id": null,
"duplicate_count": 2,
"vector_indexed": true,
"available_to_nelo": true,
"collection_name": "global_files",
"chunk_count": 45,
"indexed_at": "2024-08-26T16:00:00Z",
"created_at": "2024-08-26T15:30:00Z",
"updated_at": "2024-08-26T16:00:00Z",
"uploaded_by": {
"id": "user_001",
"email": "[email protected]"
}
}Try it out
curl -X GET "https://sapienstream.com/api/v1/global-files/{file_id}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"/v1/global-files/{file_id}/downloadAuth RequiredParameters
file_idstringRequiredGlobal file ID
Response
// 302 Redirect to presigned URL
Location: https://minio.sapienstream.com/sapienstream-global/component-files/comp_abc123/datasheet.pdf?X-Amz-Signature=...Try it out
curl -X GET "https://sapienstream.com/api/v1/global-files/{file_id}/download" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"/v1/global-files/{file_id}/viewParameters
file_idstringRequiredGlobal file ID
Response
// Streaming response with inline Content-Disposition
Content-Type: application/pdf
Content-Disposition: inline; filename="datasheet.pdf"
[Binary file data]Try it out
curl -X GET "https://sapienstream.com/api/v1/global-files/{file_id}/view" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Nelo AI Processing
/v1/global-files/{file_id}/process-neloAuth RequiredParameters
file_idstringRequiredGlobal file ID to process
Response
{
"message": "File processing started",
"file_id": "gfile_abc123",
"filename": "datasheet.pdf",
"status": "processing",
"task_id": "task_xyz789",
"estimated_chunks": 45
}Try it out
curl -X POST "https://sapienstream.com/api/v1/global-files/{file_id}/process-nelo" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"File Deletion
/v1/global-files/{file_id}Auth RequiredParameters
file_idstringRequiredGlobal file ID
Response
{
"message": "File deleted successfully",
"file_id": "gfile_abc123",
"filename": "datasheet.pdf"
}Try it out
curl -X DELETE "https://sapienstream.com/api/v1/global-files/{file_id}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"/v1/global-files/components/{component_id}/permanentAuth RequiredParameters
component_idstringRequiredComponent ID
Response
{
"message": "All files for component permanently deleted",
"component_id": "comp_abc123",
"files_deleted": 3,
"storage_freed_bytes": 3456789
}Try it out
curl -X DELETE "https://sapienstream.com/api/v1/global-files/components/{component_id}/permanent" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Upload and Process Example
// 1. Upload component datasheet (any authenticated user)
const formData = new FormData();
formData.append('file', datasheetFile);
formData.append('subcategory', 'datasheet');
formData.append('description', 'Siemens S7-1500 CPU datasheet');
const uploadResponse = await fetch('/v1/global-files/upload-component-file', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token
},
body: formData
});
const { id: fileId } = await uploadResponse.json();
console.log('File uploaded:', fileId);
// 2. Process for Nelo AI (make searchable)
const processResponse = await fetch(`/v1/global-files/${fileId}/process-nelo`, {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token
}
});
const { task_id } = await processResponse.json();
console.log('Processing started:', task_id);
// 3. Check file status
const statusResponse = await fetch(`/v1/global-files/${fileId}`, {
headers: {
'Authorization': 'Bearer ' + token
}
});
const fileInfo = await statusResponse.json();
console.log('Vector indexed:', fileInfo.vector_indexed);
console.log('Available to Nelo:', fileInfo.available_to_nelo);Bulk Upload Example
// Upload ZIP archive of component files (admin only)
const zipFormData = new FormData();
zipFormData.append('file', zipArchive);
zipFormData.append('category', 'component_file');
zipFormData.append('subcategory', 'vendor-package');
zipFormData.append('component_id', 'comp_abc123');
zipFormData.append('tags', 'siemens,import,2024');
const bulkResponse = await fetch('/v1/global-files/bulk-upload', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + adminToken
},
body: zipFormData
});
const result = await bulkResponse.json();
console.log('Files processed:', result.files_processed);
console.log('Succeeded:', result.files_succeeded);
console.log('Duplicates:', result.duplicates_found);
// Check individual results
result.results.forEach(r => {
if (r.status === 'failed') {
console.error(`Failed: ${r.filename} - ${r.error}`);
} else if (r.status === 'duplicate') {
console.log(`Duplicate: ${r.filename} (source: ${r.source_id})`);
} else {
console.log(`Uploaded: ${r.filename} (id: ${r.file_id})`);
}
});