Ingest Best Practices
Guidelines and recommendations for effective use of the Fichero ingest module.
General Recommendations
Mode Selection
Use LINK mode when: - Working with very large files (>100MB) - Files are on fast, reliable storage - You want to save storage space - Files may be updated externally - You need to preserve original file locations
Use COPY mode when: - Files should be preserved independently - You need portable libraries - Working with removable media - Files may be deleted from original locations - You want consistent performance
Use MOVE mode when: - You want the library to take ownership of the file and remove the original - Clearing the source location after import is intended (the original is deleted)
Performance Optimization
For large file collections:
- Use batch processing with ingest_folder()
- Enable recursive processing for nested directories
- Consider parallel processing for independent files
- Use progress callbacks for user feedback
For memory management: - Process files in reasonable batches (100-500 at a time) - Disable text extraction for non-searchable files - Use generators for file discovery - Monitor memory usage during large operations
Error Handling
Best practices: - Implement comprehensive try-catch blocks - Log detailed error information - Provide user-friendly error messages - Implement recovery mechanisms - Validate inputs before processing
try:
docs = ingest_folder(Path("/path/to/folder"))
logger.info(f"Successfully ingested {len(docs)} files")
except FileNotFoundError as e:
logger.error(f"Folder not found: {e}")
# Notify user
except Exception as e:
logger.error(f"Ingestion failed: {e}")
# Implement recovery
File Type Specific Guidelines
Image Files
Best practices: - Enable metadata extraction for EXIF data - Use COPY mode for important images - Consider LINK mode for large image libraries - Extract dimensions for thumbnail generation
Example:
# Ingest image with full metadata
doc = ingest_file(
Path("/path/to/photo.jpg"),
mode=IngestMode.COPY,
extract_metadata=True # Includes EXIF data
)
Document Files
Best practices: - Always enable text extraction for searchability - Use COPY mode for important documents - Consider embedding for semantic search - Extract metadata for organization
Example:
# Ingest document with search optimization
doc = ingest_file(
Path("/path/to/document.pdf"),
mode=IngestMode.COPY,
extract_text=True,
auto_embed=True
)
Media Files
Best practices: - Use LINK mode for large video/audio files - Disable text extraction (not applicable) - Extract basic metadata for organization - Consider storage implications
Example:
# Ingest media file efficiently
doc = ingest_file(
Path("/path/to/video.mp4"),
mode=IngestMode.LINK,
extract_text=False # Not applicable for video
)
Folder Ingestion Strategies
Large Folder Processing
Recommendations: - Use recursive processing for nested structures - Implement progress tracking - Consider batch processing - Monitor performance metrics
Example:
def progress_callback(current, total):
if current % 100 == 0: # Update every 100 files
print(f"Processed {current}/{total} files")
docs = ingest_folder(
Path("/large/folder"),
recursive=True,
on_progress=progress_callback
)
Selective File Processing
Recommendations:
- Use discover_files() for filtering
- Process specific file types separately
- Implement custom logic for different types
Example:
# Process only images
image_extensions = {".jpg", ".png", ".gif", ".webp"}
for file_path in discover_files(Path("/folder"), extensions=image_extensions):
ingest_file(file_path, mode=IngestMode.COPY)
Hierarchy Preservation
Recommendations: - Use recursive mode for complex structures - Let system create folder hierarchy automatically - Consider custom parent collections
Example:
# Preserve folder structure
docs = ingest_folder(
Path("/complex/folder/structure"),
recursive=True,
create_collection=True
)
Text Extraction Best Practices
When to Extract Text
Enable text extraction for: - PDF documents - Word processing files (.doc, .docx, .odt) - Text files (.txt, .md, .rst) - EPUB ebooks - Files that need to be searchable
Disable text extraction for: - Image files - Audio/video files - Binary files - Very large documents (>50MB) - Files where text isn’t needed
Memory Management
For large documents: - Process one at a time - Monitor memory usage - Consider file size limits - Implement fallback mechanisms
Example:
# Check file size before text extraction
file_size = path.stat().st_size
if file_size < 50 * 1024 * 1024: # < 50MB
doc = ingest_file(file_path, extract_text=True)
else:
doc = ingest_file(file_path, extract_text=False)
Metadata Extraction Guidelines
Standard Metadata
Always extract: - File size - Checksum (for deduplication) - MIME type - Basic file information
Example:
# Standard metadata extraction
doc = ingest_file(
Path("/path/to/file.jpg"),
extract_metadata=True # Default
)
Specialized Metadata
Extract when applicable: - Image dimensions and EXIF data - Document text length - File creation/modification dates - Custom metadata fields
Deduplication Strategies
Checksum-Based Deduplication
Best practices:
- Use find_duplicates() before ingestion
- Compare checksums for identical files
- Implement user confirmation for duplicates
- Consider file modification dates
Example:
# Check for duplicates before ingestion
existing_docs = db.query(Document, parent_id=collection_id)
duplicates = find_duplicates(existing_docs)
if duplicates:
print(f"Found {len(duplicates)} duplicate sets")
Content-Based Deduplication
Recommendations: - Use checksums for binary comparison - Consider content hashing for text files - Implement fuzzy matching for similar files - Provide user options for handling duplicates
Error Handling Patterns
Common Error Scenarios
File not found:
try:
doc = ingest_file(Path("/missing/file.pdf"))
except FileNotFoundError:
logger.warning("File not found, skipping")
Unsupported file type:
file_type = detect_file_type(file_path)
if file_type == FileType.other:
logger.info(f"Skipping unsupported file type: {file_path}")
Permission errors:
try:
doc = ingest_file(Path("/protected/file.pdf"))
except PermissionError:
logger.error("Permission denied for file")
Recovery Strategies
Partial failure handling:
successful = []
failed = []
for file_path in discover_files(folder):
try:
doc = ingest_file(file_path)
successful.append(doc)
except Exception as e:
failed.append((file_path, str(e)))
print(f"Success: {len(successful)}, Failed: {len(failed)}")
Performance Monitoring
Metrics to Track
- Files processed per second
- Memory usage during operations
- Disk I/O performance
- Text extraction times
- Error rates and types
Optimization Techniques
For slow operations: - Identify bottlenecks - Consider parallel processing - Optimize file system access - Review text extraction performance
For memory issues: - Reduce batch sizes - Disable unnecessary features - Monitor memory usage - Implement memory limits
Security Considerations
File Handling Security
- Validate all file paths
- Check file permissions
- Handle symbolic links carefully
- Implement size limits
- Scan for malicious content
Data Protection
- Secure sensitive metadata
- Handle personal information carefully
- Implement access controls
- Consider encryption for sensitive files
Integration Best Practices
Database Integration
Recommendations: - Use transactions for batch operations - Implement proper indexing - Monitor database performance - Consider batch inserts for large operations
Search Integration
Recommendations: - Enable text extraction for searchable content - Use embeddings for semantic search - Implement proper indexing strategies - Consider search performance implications
UI Integration
Recommendations: - Provide progress feedback - Implement cancellation support - Show error messages clearly - Provide detailed logging options
Maintenance and Updates
Documentation Updates
- Keep documentation current
- Update for new file types
- Document API changes
- Maintain usage examples
Version Compatibility
- Test with new Python versions
- Verify library compatibility
- Update dependencies as needed
- Maintain backward compatibility
Performance Tuning
- Review performance regularly
- Optimize for common use cases
- Update for new hardware
- Monitor resource usage
Troubleshooting Guide
Common Issues
Slow ingestion: - Check disk I/O performance - Review text extraction settings - Monitor memory usage - Consider batch size reduction
Memory errors: - Reduce batch sizes - Disable text extraction - Monitor memory usage - Implement memory limits
File access errors: - Check file permissions - Verify file paths - Handle symbolic links - Implement proper error handling
Deduplication issues: - Verify checksum calculation - Check file content - Review duplicate detection logic - Implement user confirmation
Debugging Techniques
Logging:
import logging
logging.basicConfig(level=logging.DEBUG)
Profiling:
import cProfile
cProfile.run("ingest_folder(folder)")
Unit Testing:
# Test individual components
from fichero_server.importers.ingest import detect_file_type
assert detect_file_type(Path("test.jpg")) == FileType.image
Migration Guide
From Older Versions
Check for: - API changes - New features - Deprecated functionality - Performance improvements
Data Migration
Considerations: - Backup existing data - Test migration process - Verify data integrity - Update documentation
Future Considerations
Potential Enhancements
- Parallel processing support
- Additional file type support
- Enhanced metadata extraction
- Improved error recovery
- Advanced deduplication options
Scalability Planning
- Consider large-scale deployments
- Review performance bottlenecks
- Plan for growth
- Monitor resource usage
Conclusion
Following these best practices will help ensure: - Reliable file ingestion - Optimal performance - Effective error handling - Good user experience - Maintainable code - Scalable solutions
Always consider the specific requirements of your use case and adjust these recommendations accordingly.