Remove a source from your project using the Graphor SDK
The delete method (same name as the API endpoint) permanently removes a source from your project. You must pass the source’s file_id (from list or get build status). The operation is irreversible and removes all associated data including partition nodes and metadata.
Verify the source exists (by file_id) before deleting:
Python
TypeScript
from graphor import Graphorimport graphorclient = Graphor()def safe_delete(file_id: str) -> bool: sources = client.sources.list() file_ids = [s.file_id for s in sources] if file_id not in file_ids: print(f"Source '{file_id}' not found") return False info = next(s for s in sources if s.file_id == file_id) print(f"Source to delete: {info.file_name} ({info.file_id})") confirm = input("Proceed? (yes/no): ") if confirm.lower() != "yes": return False try: result = client.sources.delete(file_id=file_id) print(f"Success: {result.message}") return True except graphor.APIStatusError as e: print(f"Deletion failed: {e}") return Falsesafe_delete("file_abc123")
const sources = await client.sources.list();const fileIds = sources.map((s) => s.file_id);if (!fileIds.includes(fileId)) { console.log('Source not found'); return;}const info = sources.find((s) => s.file_id === fileId)!;console.log(`Source to delete: ${info.file_name} (${info.file_id})`);const result = await client.sources.delete({ fileId });console.log('Success:', result.message);
from graphor import Graphorimport graphorimport timeclient = Graphor()def batch_delete(file_ids: list[str], confirm: bool = True) -> dict: """Delete multiple sources by file_id.""" sources = client.sources.list() by_id = {s.file_id: s for s in sources} missing = [f for f in file_ids if f not in by_id] if missing: print(f"Sources not found: {missing}") return {"error": f"Missing: {missing}"} total_size = sum(by_id[f].file_size for f in file_ids) print(f"Deletion: {len(file_ids)} sources, {total_size / (1024*1024):.2f} MB") for fid in file_ids: print(f" - {by_id[fid].file_name} ({by_id[fid].file_id})") if confirm: if input("Type 'DELETE' to confirm: ") != "DELETE": return {"cancelled": True} results = {"successful": [], "failed": []} for i, fid in enumerate(file_ids, 1): try: result = client.sources.delete(file_id=fid) results["successful"].append({"file_id": fid, "message": result.message}) except graphor.APIStatusError as e: results["failed"].append({"file_id": fid, "error": str(e)}) if i < len(file_ids): time.sleep(0.5) return resultsfile_ids_to_delete = ["file_1", "file_2", "file_3"]results = batch_delete(file_ids_to_delete)
from graphor import Graphorimport graphorfrom dataclasses import dataclassfrom typing import Optional@dataclassclass DeletionResult: success: bool file_name: str message: str error: Optional[str] = Noneclass DocumentManager: def __init__(self, api_key: Optional[str] = None): self.client = Graphor(api_key=api_key) if api_key else Graphor() def list_sources(self): """Get all sources.""" return self.client.sources.list() def find_source(self, file_id: str): """Find a source by file_id.""" sources = self.list_sources() for source in sources: if source.file_id == file_id: return source return None def delete(self, file_id: str, verify: bool = True) -> DeletionResult: """Delete a source by file_id with optional verification.""" if verify: source = self.find_source(file_id) if not source: return DeletionResult( success=False, file_name=file_id, message="Source not found", error="NotFoundError" ) try: result = self.client.sources.delete(file_id=file_id) return DeletionResult( success=True, file_name=result.file_name, message=result.message ) except graphor.NotFoundError as e: return DeletionResult(success=False, file_name=file_id, message="Source not found", error=str(e)) except graphor.APIStatusError as e: return DeletionResult(success=False, file_name=file_id, message=f"API error: {e.status_code}", error=str(e)) def delete_by_type(self, file_type: str, confirm: bool = True) -> list[DeletionResult]: """Delete all sources of a specific type.""" sources = self.list_sources() targets = [s for s in sources if s.file_type == file_type] if not targets: print(f"No sources with type '{file_type}' found") return [] print(f"Found {len(targets)} sources with type '{file_type}':") for source in targets: print(f" - {source.file_name}") if confirm: confirmation = input(f"\nDelete all {len(targets)} {file_type} files? (yes/no): ") if confirmation.lower() != "yes": print("Cancelled") return [] results = [] for source in targets: result = self.delete(source.file_id, verify=False) results.append(result) status = "OK" if result.success else "FAIL" print(f"{status} {source.file_name}: {result.message}") return results def delete_by_status(self, status: str, confirm: bool = True) -> list[DeletionResult]: """Delete all sources with a specific status.""" sources = self.list_sources() targets = [s for s in sources if s.status == status] if not targets: print(f"No sources with status '{status}' found") return [] print(f"Found {len(targets)} sources with status '{status}':") for source in targets: print(f" - {source.file_name}") if confirm: confirmation = input(f"\nDelete all {len(targets)} {status} sources? (yes/no): ") if confirmation.lower() != "yes": print("Cancelled") return [] results = [] for source in targets: result = self.delete(source.file_id, verify=False) results.append(result) status_icon = "OK" if result.success else "FAIL" print(f"{status_icon} {source.file_name}: {result.message}") return results# Usagemanager = DocumentManager()# Delete a single fileresult = manager.delete("file_abc123")print(f"Deleted: {result.success}")# Delete all PDFsresults = manager.delete_by_type("pdf")# Delete all failed sourcesresults = manager.delete_by_status("Failed")
import Graphor from 'graphor';interface DeletionResult { success: boolean; fileName: string; message: string; error?: string;}class DocumentManager { private client: Graphor; constructor(apiKey?: string) { this.client = apiKey ? new Graphor({ apiKey }) : new Graphor(); } async listSources() { return this.client.sources.list(); } async findSource(fileId: string) { const sources = await this.listSources(); return sources.find((s) => s.file_id === fileId) ?? null; } async delete(fileId: string, verify = true): Promise<DeletionResult> { if (verify) { const source = await this.findSource(fileId); if (!source) { return { success: false, fileName: fileId, message: 'Source not found', error: 'NotFoundError' }; } } try { const result = await this.client.sources.delete({ fileId }); return { success: true, fileName: result.file_name, message: result.message }; } catch (err) { if (err instanceof Graphor.NotFoundError) { return { success: false, fileName: fileId, message: 'Source not found', error: err.message }; } if (err instanceof Graphor.APIError) { return { success: false, fileName: fileId, message: `API error: ${err.status}`, error: err.message }; } throw err; } } async deleteByType(fileType: string): Promise<DeletionResult[]> { const sources = await this.listSources(); const targets = sources.filter((s) => s.file_type === fileType); if (targets.length === 0) { console.log(`No sources with type '${fileType}' found`); return []; } console.log(`Found ${targets.length} sources with type '${fileType}':`); for (const source of targets) { console.log(` - ${source.file_name}`); } const results: DeletionResult[] = []; for (const source of targets) { const result = await this.delete(source.file_id, false); results.push(result); const status = result.success ? 'OK' : 'FAIL'; console.log(`${status} ${source.file_name}: ${result.message}`); } return results; } async deleteByStatus(status: string): Promise<DeletionResult[]> { const sources = await this.listSources(); const targets = sources.filter((s) => s.status === status); if (targets.length === 0) { console.log(`No sources with status '${status}' found`); return []; } console.log(`Found ${targets.length} sources with status '${status}':`); for (const source of targets) { console.log(` - ${source.file_name}`); } const results: DeletionResult[] = []; for (const source of targets) { const result = await this.delete(source.file_id, false); results.push(result); const statusIcon = result.success ? 'OK' : 'FAIL'; console.log(`${statusIcon} ${source.file_name}: ${result.message}`); } return results; }}// Usageconst manager = new DocumentManager();// Delete a single fileconst result = await manager.delete('file_abc123');console.log(`Deleted: ${result.success}`);// Delete all PDFsawait manager.deleteByType('pdf');// Delete all failed sourcesawait manager.deleteByStatus('Failed');
from graphor import Graphorimport graphorfrom typing import Optionalclient = Graphor()def archive_sources( file_types: Optional[list[str]] = None, statuses: Optional[list[str]] = None, min_size_mb: Optional[float] = None, max_size_mb: Optional[float] = None, dry_run: bool = True) -> dict: """ Archive sources based on criteria. Use dry_run=True to see what would be deleted without actually deleting. """ print("Analyzing sources for archival...") sources = client.sources.list() # Apply filters candidates = [] for source in sources: # File type filter if file_types and source.file_type not in file_types: continue # Status filter if statuses and source.status not in statuses: continue # Size filters size_mb = source.file_size / (1024 * 1024) if min_size_mb and size_mb < min_size_mb: continue if max_size_mb and size_mb > max_size_mb: continue candidates.append(source) if not candidates: print("No sources match the criteria") return {"candidates": 0} # Show summary total_size = sum(s.file_size for s in candidates) total_size_mb = total_size / (1024 * 1024) print(f"\nFound {len(candidates)} sources matching criteria:") for source in candidates: size_mb = source.file_size / (1024 * 1024) print(f" - {source.file_name} ({source.file_type}, {size_mb:.1f}MB, {source.status})") print(f"\nTotal size to be freed: {total_size_mb:.1f}MB") if dry_run: print("\nDRY RUN - No files will be deleted") print("Set dry_run=False to perform actual deletion") return { "dry_run": True, "candidates": len(candidates), "total_size_mb": total_size_mb, "files": [s.file_name for s in candidates] } # Confirm and delete confirmation = input(f"\nDelete {len(candidates)} sources permanently? (type 'DELETE'): ") if confirmation != "DELETE": print("Archival cancelled") return {"cancelled": True} deleted = [] failed = [] for source in candidates: try: client.sources.delete(file_id=source.file_id) deleted.append(source.file_name) print(f"Archived: {source.file_name}") except graphor.APIStatusError as e: failed.append({"file_name": source.file_name, "error": str(e)}) print(f"Failed: {source.file_name} - {e}") return { "deleted": deleted, "failed": failed, "total_deleted": len(deleted), "size_freed_mb": sum( s.file_size for s in candidates if s.file_name in deleted ) / (1024 * 1024) }# Usage examples# Dry run: see what would be deletedarchive_sources( file_types=["tmp", "test"], dry_run=True)# Archive all failed sources (dry run first)archive_sources( statuses=["Failed"], dry_run=True)# Archive large files over 50MB (dry run)archive_sources( min_size_mb=50, dry_run=True)# Actually delete failed sourcesarchive_sources( statuses=["Failed"], dry_run=False # This will delete!)
import Graphor from 'graphor';const client = new Graphor();interface ArchiveOptions { fileTypes?: string[]; statuses?: string[]; minSizeMb?: number; maxSizeMb?: number; dryRun?: boolean;}async function archiveSources(options: ArchiveOptions = {}) { const { fileTypes, statuses, minSizeMb, maxSizeMb, dryRun = true } = options; console.log('Analyzing sources for archival...'); const sources = await client.sources.list(); // Apply filters const candidates = sources.filter((source) => { if (fileTypes && !fileTypes.includes(source.file_type)) return false; if (statuses && !statuses.includes(source.status)) return false; const sizeMb = source.file_size / (1024 * 1024); if (minSizeMb && sizeMb < minSizeMb) return false; if (maxSizeMb && sizeMb > maxSizeMb) return false; return true; }); if (candidates.length === 0) { console.log('No sources match the criteria'); return { candidates: 0 }; } // Show summary const totalSize = candidates.reduce((sum, s) => sum + s.file_size, 0); const totalSizeMb = totalSize / (1024 * 1024); console.log(`\nFound ${candidates.length} sources matching criteria:`); for (const source of candidates) { const sizeMb = source.file_size / (1024 * 1024); console.log( ` - ${source.file_name} (${source.file_type}, ${sizeMb.toFixed(1)}MB, ${source.status})`, ); } console.log(`\nTotal size to be freed: ${totalSizeMb.toFixed(1)}MB`); if (dryRun) { console.log('\nDRY RUN - No files will be deleted'); console.log('Set dryRun: false to perform actual deletion'); return { dryRun: true, candidates: candidates.length, totalSizeMb, files: candidates.map((s) => s.file_name), }; } // Perform deletions const deleted: string[] = []; const failed: { fileName: string; error: string }[] = []; for (const source of candidates) { try { await client.sources.delete({ fileId: source.file_id }); deleted.push(source.file_name); console.log(`Archived: ${source.file_name}`); } catch (err) { const message = err instanceof Graphor.APIError ? err.message : String(err); failed.push({ fileName: source.file_name, error: message }); console.log(`Failed: ${source.file_name} - ${message}`); } } const sizeFreed = candidates .filter((s) => deleted.includes(s.file_name)) .reduce((sum, s) => sum + s.file_size, 0) / (1024 * 1024); return { deleted, failed, totalDeleted: deleted.length, sizeFreedMb: sizeFreed };}// Usage examples// Dry run: see what would be deletedawait archiveSources({ fileTypes: ['tmp', 'test'], dryRun: true });// Archive all failed sources (dry run first)await archiveSources({ statuses: ['Failed'], dryRun: true });// Archive large files over 50MB (dry run)await archiveSources({ minSizeMb: 50, dryRun: true });// Actually delete failed sourcesawait archiveSources({ statuses: ['Failed'], dryRun: false }); // This will delete!
Verify the source exists (by file_id) before deleting:
Python
TypeScript
sources = client.sources.list()file_ids = [s.file_id for s in sources]if file_id in file_ids: client.sources.delete(file_id=file_id)else: print("Source not found")