Skip to content

Commit 58bd2b5

Browse files
authored
[recipe] Add DocumentLens Recipe for structured parsing of rich documents (#980)
2 parents 1d62ac0 + ebccc06 commit 58bd2b5

11 files changed

Lines changed: 2540 additions & 0 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
*.png
3+
*.log
4+
src_v2
5+
*.pdf
6+
*.json
7+
*.db
8+
*.csv
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Contributing to Structured Document Parser
2+
3+
Thank you for your interest in contributing to the Structured Document Parser! This document provides guidelines and instructions for contributors.
4+
5+
## Development Setup
6+
7+
1. Fork the repository and clone it locally.
8+
2. Install dependencies:
9+
```bash
10+
pip install -r requirements.txt
11+
```
12+
3. Install development dependencies:
13+
```bash
14+
pip install pytest black flake8 mypy
15+
```
16+
17+
## Project Structure
18+
19+
```
20+
structured_parser/
21+
├── src/
22+
│ ├── structured_extraction.py # Main entry point
23+
│ ├── utils.py # Utility functions
24+
│ ├── typedicts.py # Type definitions
25+
│ ├── json_to_sql.py # Database integration
26+
│ └── config.yaml # Configuration
27+
├── tests/ # Test cases
28+
├── README.md # Project overview
29+
└── requirements.txt # Dependencies
30+
```
31+
32+
## Development Workflow
33+
34+
### Code Style
35+
36+
We follow the PEP 8 style guide for Python code. Please use `black` for formatting:
37+
38+
```bash
39+
black src/
40+
```
41+
42+
### Type Checking
43+
44+
We use type hints and `mypy` for type checking:
45+
46+
```bash
47+
mypy src/
48+
```
49+
50+
### Testing
51+
52+
Please add tests for new features and ensure all tests pass:
53+
54+
```bash
55+
pytest tests/
56+
```
57+
58+
## Areas for Contribution
59+
60+
Here are some areas where contributions are especially welcome:
61+
62+
### 1. Artifact Extraction Improvements
63+
64+
- Adding support for new artifact types
65+
- Improving extraction accuracy for existing types
66+
- Optimizing prompts for better results
67+
68+
### 2. Performance Optimization
69+
70+
- Improving inference speed
71+
- Reducing memory usage
72+
- Implementing efficient batching strategies
73+
74+
### 3. New Features
75+
76+
- Supporting additional document types (beyond PDF)
77+
- Adding new output formats
78+
- Implementing document comparison functionality
79+
- Enhancing vector search capabilities
80+
81+
### 4. Documentation and Examples
82+
83+
- Improving documentation
84+
- Adding usage examples
85+
- Creating tutorials or guides
86+
87+
## Submitting Changes
88+
89+
1. Create a new branch for your changes
90+
2. Make your changes and commit with clear commit messages
91+
3. Push your branch and submit a pull request
92+
4. Ensure CI tests pass
93+
94+
## Pull Request Guidelines
95+
96+
- Provide a clear description of the problem and solution
97+
- Include any relevant issue numbers
98+
- Add tests for new functionality
99+
- Update documentation as needed
100+
- Keep pull requests focused on a single topic
101+
102+
## Prompt Engineering Guidelines
103+
104+
When modifying prompts in `config.yaml`, consider:
105+
106+
1. **Clarity**: Provide clear and specific instructions
107+
2. **Examples**: Include examples where helpful
108+
3. **Structure**: Use structured formatting to guide the model
109+
4. **Schema alignment**: Ensure prompts align with output schemas
110+
5. **Testing**: Test prompts with diverse document types
111+
112+
## Output Schema Guidelines
113+
114+
When defining output schemas:
115+
116+
1. Keep properties focused and well-defined
117+
2. Use descriptive field names
118+
3. Include descriptions for complex fields
119+
4. Consider required vs. optional fields carefully
120+
5. Test schemas with different document layouts
121+
122+
## License
123+
124+
By contributing, you agree that your contributions will be licensed under the project's license.
125+
126+
## Questions or Issues?
127+
128+
If you have questions or encounter issues, please:
129+
130+
1. Check existing issues to see if it's been addressed
131+
2. Open a new issue with a clear description and steps to reproduce
132+
3. Tag relevant project maintainers
133+
134+
Thank you for your contributions!
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# Getting Started with Structured Document Parser
2+
3+
This guide walks you through setting up and using the Structured Document Parser tool to extract text, tables, and images from PDF documents.
4+
5+
## Setup
6+
7+
### 1. Install Dependencies
8+
9+
```bash
10+
pip install -r requirements.txt
11+
```
12+
13+
### 2. Configure the Tool
14+
15+
Edit the `src/config.yaml` file to configure the tool:
16+
17+
```yaml
18+
# Choose your inference backend
19+
model:
20+
backend: openai-compat # Use "offline-vllm" for local inference
21+
22+
# If using openai-compat
23+
base_url: "https://api.llama.com/compat/v1"
24+
api_key: "YOUR_API_KEY"
25+
model_id: "Llama-4-Maverick-17B-128E-Instruct-FP8" # Or your preferred model
26+
```
27+
28+
## Basic Usage Examples
29+
30+
### Extract Text from a PDF
31+
32+
```bash
33+
python src/structured_extraction.py path/to/document.pdf --text
34+
```
35+
36+
This will:
37+
1. Convert each PDF page to an image
38+
2. Run LLM inference to extract text
39+
3. Save extracted text as JSON in the `extracted` directory
40+
41+
### Extract Text and Tables
42+
43+
```bash
44+
python src/structured_extraction.py path/to/document.pdf --text --tables
45+
```
46+
47+
### Extract All Types of Content
48+
49+
```bash
50+
python src/structured_extraction.py path/to/document.pdf --text --tables --images
51+
```
52+
53+
### Process Multiple PDFs
54+
55+
```bash
56+
python src/structured_extraction.py path/to/pdf_directory --text --tables
57+
```
58+
59+
## Working with Extraction Results
60+
61+
### Export Tables to CSV
62+
63+
```bash
64+
python src/structured_extraction.py path/to/document.pdf --tables --save_tables_as_csv
65+
```
66+
67+
Tables will be saved as individual CSV files in `extracted/tables_TIMESTAMP/`.
68+
69+
### Export Tables to Excel
70+
71+
```bash
72+
python src/structured_extraction.py path/to/document.pdf --tables --export_excel
73+
```
74+
75+
Tables will be combined into a single Excel file with multiple sheets.
76+
77+
### Save to Database
78+
79+
```bash
80+
python src/structured_extraction.py path/to/document.pdf --text --tables --save_to_db
81+
```
82+
83+
Extracted content will be stored in an SQLite database for structured querying.
84+
85+
## Python API Examples
86+
87+
### Extract Content Programmatically
88+
89+
```python
90+
from src.structured_extraction import ArtifactExtractor
91+
from src.utils import PDFUtils
92+
93+
# Extract pages from a PDF
94+
pdf_pages = PDFUtils.extract_pages("document.pdf")
95+
96+
# Process each page
97+
for page in pdf_pages:
98+
# Extract text
99+
text_artifacts = ArtifactExtractor.from_image(
100+
page["image_path"], ["text"]
101+
)
102+
103+
# Or extract multiple artifact types
104+
all_artifacts = ArtifactExtractor.from_image(
105+
page["image_path"], ["text", "tables", "images"]
106+
)
107+
108+
# Process the extracted artifacts
109+
print(all_artifacts)
110+
```
111+
112+
### Query the Database
113+
114+
```python
115+
from src.json_to_sql import DatabaseManager
116+
117+
# Query all text artifacts
118+
text_df = DatabaseManager.sql_query(
119+
"sqlite3.db",
120+
"SELECT * FROM document_artifacts WHERE artifact_type = 'text'"
121+
)
122+
123+
# Query tables containing specific content
124+
revenue_tables = DatabaseManager.sql_query(
125+
"sqlite3.db",
126+
"SELECT * FROM document_artifacts WHERE artifact_type = 'table' AND table_info LIKE '%revenue%'"
127+
)
128+
```
129+
130+
### Semantic Search
131+
132+
```python
133+
from src.json_to_sql import VectorIndexManager
134+
135+
# Search for relevant content
136+
results = VectorIndexManager.knn_query(
137+
"What is the revenue growth for Q2?",
138+
"chroma.db",
139+
n_results=5
140+
)
141+
142+
# Display results
143+
for i, (doc_id, distance, content) in enumerate(zip(
144+
results['ids'], results['distances'], results['documents']
145+
)):
146+
print(f"Result {i+1} (similarity: {1-distance:.2f}):")
147+
print(content[:200] + "...\n")
148+
```
149+
150+
## Customizing Extraction
151+
152+
### Modify Prompts
153+
154+
Edit the prompts in `src/config.yaml` to improve extraction for your specific document types:
155+
156+
```yaml
157+
artifacts:
158+
text:
159+
prompts:
160+
system: "You are an OCR expert. Your task is to extract all text sections..."
161+
user: "TARGET SCHEMA:\n```json\n{schema}\n```"
162+
```
163+
164+
### Add a Custom Artifact Type
165+
166+
1. Add configuration to `src/config.yaml`:
167+
168+
```yaml
169+
artifacts:
170+
my_custom_type:
171+
prompts:
172+
system: "Your custom system prompt..."
173+
user: "Your custom user prompt with {schema} placeholder..."
174+
output_schema: {
175+
# Your schema definition here
176+
}
177+
use_json_decoding: true
178+
```
179+
180+
2. Update the CLI in `src/structured_extraction.py`:
181+
182+
```python
183+
def main(
184+
target_path: str,
185+
text: bool = True,
186+
tables: bool = False,
187+
images: bool = False,
188+
my_custom_type: bool = False, # Add your type here
189+
save_to_db: bool = False,
190+
...
191+
):
192+
# Update artifact types logic
193+
to_extract = []
194+
if text:
195+
to_extract.append("text")
196+
if tables:
197+
to_extract.append("tables")
198+
if images:
199+
to_extract.append("images")
200+
if my_custom_type:
201+
to_extract.append("my_custom_type") # Add your type here
202+
```
203+
204+
## Troubleshooting
205+
206+
### LLM Response Format Issues
207+
208+
If the LLM responses aren't being correctly parsed, check:
209+
1. Your output schema in `config.yaml`
210+
2. The `use_json_decoding` setting (set to `true` for more reliable parsing)
211+
3. Consider using a larger model or reducing extraction complexity
212+
213+
### Database Issues
214+
215+
If you encounter database errors:
216+
1. Ensure SQLite is properly installed
217+
2. Check database file permissions
218+
3. Use `DatabaseManager.create_artifact_table()` to reinitialize the table schema
219+
220+
### PDF Rendering Issues
221+
222+
If PDF extraction quality is poor:
223+
1. Try adjusting the DPI setting in `PDFUtils.extract_pages()`
224+
2. For complex layouts, split extraction into smaller chunks (per section)
225+
3. Consider pre-processing PDFs with OCR tools for better text layer quality
226+
227+
## Next Steps
228+
229+
- Try extracting from different types of documents
230+
- Adjust prompts and schemas for your specific use cases
231+
- Explore the vector search capabilities for semantic document queries
232+
- Integrate with your existing document processing workflows

0 commit comments

Comments
 (0)