Spaces:
Paused
Paused
Upload 66 files
Browse files- DEPLOYMENT_GUIDE.md +125 -176
- Dockerfile +11 -3
- FIXES_SUMMARY.md +178 -0
- app/main.py +3 -0
- app/services/database_service.py +34 -5
- app/services/ocr_service.py +43 -56
- debug_container.py +66 -0
- docker-compose.yml +6 -5
- rebuild_and_test.ps1 +44 -0
- rebuild_and_test.sh +40 -0
- start.sh +10 -0
- test_db_connection.py +54 -0
DEPLOYMENT_GUIDE.md
CHANGED
@@ -1,224 +1,173 @@
|
|
1 |
-
#
|
2 |
|
3 |
-
##
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
|
|
|
|
|
|
|
|
8 |
|
9 |
-
|
10 |
-
-
|
11 |
-
-
|
12 |
|
13 |
-
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
βββ requirements.txt # Python dependencies
|
21 |
-
βββ README.md # HF Spaces metadata + documentation
|
22 |
-
βββ app/ # FastAPI application
|
23 |
-
β βββ main.py # Main application entry point
|
24 |
-
β βββ api/ # API route handlers
|
25 |
-
β βββ services/ # Business logic services
|
26 |
-
β βββ models/ # Data models
|
27 |
-
βββ frontend/ # Web interface files
|
28 |
-
βββ data/ # Sample documents
|
29 |
-
βββ tests/ # Test suite
|
30 |
-
```
|
31 |
|
32 |
-
|
|
|
|
|
|
|
33 |
|
34 |
-
|
35 |
|
36 |
-
|
37 |
-
cd legal_dashboard_ocr
|
38 |
-
docker build -t legal-dashboard-ocr .
|
39 |
-
```
|
40 |
|
41 |
-
|
42 |
|
43 |
-
|
44 |
-
|
45 |
-
docker
|
|
|
46 |
|
47 |
-
|
48 |
-
|
49 |
-
|
|
|
|
|
50 |
|
51 |
-
|
|
|
|
|
|
|
52 |
|
53 |
-
|
54 |
-
- **API Docs**: http://localhost:7860/docs
|
55 |
-
- **Health Check**: http://localhost:7860/health
|
56 |
|
57 |
-
|
58 |
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
-
|
65 |
-
|
66 |
-
- **SDK**: `Docker`
|
67 |
-
- **License**: Choose appropriate license
|
68 |
|
69 |
-
###
|
70 |
|
|
|
71 |
```bash
|
72 |
-
|
73 |
-
git clone <your-repo-url>
|
74 |
-
cd legal_dashboard_ocr
|
75 |
-
|
76 |
-
# Push to Hugging Face Space
|
77 |
-
git remote add space https://huggingface.co/spaces/<username>/legal-dashboard-ocr
|
78 |
-
git push space main
|
79 |
```
|
80 |
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
3. Wait for build completion (usually 5-10 minutes)
|
86 |
-
4. Verify the Space is running on port 7860
|
87 |
-
|
88 |
-
## π Verification Checklist
|
89 |
-
|
90 |
-
### β
Docker Build
|
91 |
-
- [ ] Dockerfile exists and is valid
|
92 |
-
- [ ] .dockerignore excludes unnecessary files
|
93 |
-
- [ ] Requirements.txt has all dependencies
|
94 |
-
- [ ] Port 7860 is exposed
|
95 |
-
|
96 |
-
### β
Application Configuration
|
97 |
-
- [ ] Main.py runs on port 7860
|
98 |
-
- [ ] Health endpoint responds correctly
|
99 |
-
- [ ] CORS is configured for HF Spaces
|
100 |
-
- [ ] Static files are served correctly
|
101 |
-
|
102 |
-
### β
HF Spaces Metadata
|
103 |
-
- [ ] README.md has correct YAML header
|
104 |
-
- [ ] SDK is set to "docker"
|
105 |
-
- [ ] Title and emoji are set
|
106 |
-
- [ ] Colors are configured
|
107 |
-
|
108 |
-
### β
API Endpoints
|
109 |
-
- [ ] `/` - Dashboard interface
|
110 |
-
- [ ] `/health` - Health check
|
111 |
-
- [ ] `/docs` - API documentation
|
112 |
-
- [ ] `/api/ocr/process` - OCR processing
|
113 |
-
- [ ] `/api/dashboard/summary` - Dashboard data
|
114 |
-
|
115 |
-
## π Troubleshooting
|
116 |
-
|
117 |
-
### Common Issues
|
118 |
|
119 |
-
|
120 |
-
- Check Dockerfile syntax
|
121 |
-
- Verify all dependencies in requirements.txt
|
122 |
-
- Check .dockerignore excludes too many files
|
123 |
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
|
|
|
|
128 |
|
129 |
-
|
130 |
-
- Verify CORS configuration
|
131 |
-
- Check route definitions
|
132 |
-
- Test locally first
|
133 |
|
134 |
-
|
135 |
-
- Check file paths in main.py
|
136 |
-
- Verify files are copied to container
|
137 |
-
- Test static file serving
|
138 |
|
139 |
-
|
|
|
140 |
|
141 |
-
|
142 |
-
# Check container logs
|
143 |
-
docker logs <container-id>
|
144 |
|
145 |
-
|
146 |
-
|
|
|
147 |
|
148 |
-
|
149 |
-
curl http://localhost:7860/health
|
150 |
|
151 |
-
|
152 |
-
|
153 |
-
|
|
|
|
|
154 |
|
155 |
-
|
|
|
|
|
|
|
|
|
156 |
|
157 |
-
###
|
158 |
-
|
159 |
-
|
160 |
-
|
|
|
161 |
|
162 |
-
|
163 |
-
- Async/await for I/O operations
|
164 |
-
- Connection pooling for database
|
165 |
-
- Caching for OCR models
|
166 |
-
- Compression for static files
|
167 |
|
168 |
-
|
169 |
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
- No sensitive data in image
|
175 |
|
176 |
-
|
177 |
-
|
178 |
-
-
|
179 |
-
|
180 |
-
- CORS configuration
|
181 |
|
182 |
-
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
- Memory and CPU usage
|
189 |
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
- User activity monitoring
|
195 |
|
196 |
-
##
|
197 |
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
- Health endpoint returns 200 OK
|
202 |
|
203 |
-
|
204 |
-
- Dashboard loads correctly
|
205 |
-
- OCR processing works
|
206 |
-
- API endpoints respond
|
207 |
-
- File uploads function
|
208 |
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
- API response times < 1 second
|
213 |
|
214 |
-
##
|
215 |
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
5. **Documentation**: Update user documentation
|
221 |
|
222 |
-
|
223 |
|
224 |
-
|
|
|
|
|
|
|
|
1 |
+
# Legal Dashboard OCR - Deployment Guide
|
2 |
|
3 |
+
## Quick Start
|
4 |
|
5 |
+
### Using Docker Compose (Recommended)
|
6 |
|
7 |
+
1. **Build and run the application:**
|
8 |
+
```bash
|
9 |
+
cd legal_dashboard_ocr
|
10 |
+
docker-compose up --build
|
11 |
+
```
|
12 |
|
13 |
+
2. **Access the application:**
|
14 |
+
- Open your browser and go to: `http://localhost:7860`
|
15 |
+
- The application will be available on port 7860
|
16 |
|
17 |
+
### Using Docker directly
|
18 |
|
19 |
+
1. **Build the Docker image:**
|
20 |
+
```bash
|
21 |
+
cd legal_dashboard_ocr
|
22 |
+
docker build -t legal-dashboard-ocr .
|
23 |
+
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
+
2. **Run the container:**
|
26 |
+
```bash
|
27 |
+
docker run -p 7860:7860 -v $(pwd)/data:/app/data -v $(pwd)/cache:/app/cache legal-dashboard-ocr
|
28 |
+
```
|
29 |
|
30 |
+
## Troubleshooting
|
31 |
|
32 |
+
### Database Connection Issues
|
|
|
|
|
|
|
33 |
|
34 |
+
If you encounter database connection errors:
|
35 |
|
36 |
+
1. **Check if the data directory exists:**
|
37 |
+
```bash
|
38 |
+
docker exec -it <container_name> ls -la /app/data
|
39 |
+
```
|
40 |
|
41 |
+
2. **Create the data directory manually:**
|
42 |
+
```bash
|
43 |
+
docker exec -it <container_name> mkdir -p /app/data
|
44 |
+
docker exec -it <container_name> chmod 777 /app/data
|
45 |
+
```
|
46 |
|
47 |
+
3. **Test database connection:**
|
48 |
+
```bash
|
49 |
+
docker exec -it <container_name> python debug_container.py
|
50 |
+
```
|
51 |
|
52 |
+
### OCR Model Issues
|
|
|
|
|
53 |
|
54 |
+
If OCR models fail to load:
|
55 |
|
56 |
+
1. **Check available models:**
|
57 |
+
The application will automatically try these models in order:
|
58 |
+
- `microsoft/trocr-base-stage1`
|
59 |
+
- `microsoft/trocr-base-handwritten`
|
60 |
+
- `microsoft/trocr-small-stage1`
|
61 |
+
- `microsoft/trocr-small-handwritten`
|
62 |
|
63 |
+
2. **Set Hugging Face token (optional):**
|
64 |
+
```bash
|
65 |
+
export HF_TOKEN=your_huggingface_token
|
66 |
+
docker run -e HF_TOKEN=$HF_TOKEN -p 7860:7860 legal-dashboard-ocr
|
67 |
+
```
|
|
|
|
|
68 |
|
69 |
+
### Container Logs
|
70 |
|
71 |
+
To view container logs:
|
72 |
```bash
|
73 |
+
docker-compose logs -f
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
```
|
75 |
|
76 |
+
Or for direct Docker:
|
77 |
+
```bash
|
78 |
+
docker logs <container_name> -f
|
79 |
+
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
|
81 |
+
## Environment Variables
|
|
|
|
|
|
|
82 |
|
83 |
+
| Variable | Default | Description |
|
84 |
+
|----------|---------|-------------|
|
85 |
+
| `DATABASE_PATH` | `/app/data/legal_dashboard.db` | SQLite database path |
|
86 |
+
| `TRANSFORMERS_CACHE` | `/app/cache` | Hugging Face cache directory |
|
87 |
+
| `HF_HOME` | `/app/cache` | Hugging Face home directory |
|
88 |
+
| `HF_TOKEN` | (not set) | Hugging Face authentication token |
|
89 |
|
90 |
+
## Volume Mounts
|
|
|
|
|
|
|
91 |
|
92 |
+
The application uses these volume mounts for persistent data:
|
|
|
|
|
|
|
93 |
|
94 |
+
- `./data:/app/data` - Database and uploaded files
|
95 |
+
- `./cache:/app/cache` - Hugging Face model cache
|
96 |
|
97 |
+
## Health Check
|
|
|
|
|
98 |
|
99 |
+
The application includes a health check endpoint:
|
100 |
+
- URL: `http://localhost:7860/health`
|
101 |
+
- Returns status of OCR, database, and AI services
|
102 |
|
103 |
+
## Common Issues and Solutions
|
|
|
104 |
|
105 |
+
### Issue: "unable to open database file"
|
106 |
+
**Solution:**
|
107 |
+
1. Ensure the data directory exists and has proper permissions
|
108 |
+
2. Check if the volume mount is working correctly
|
109 |
+
3. Run the debug script: `docker exec -it <container> python debug_container.py`
|
110 |
|
111 |
+
### Issue: OCR models fail to load
|
112 |
+
**Solution:**
|
113 |
+
1. The application will automatically fall back to basic text extraction
|
114 |
+
2. Check internet connectivity for model downloads
|
115 |
+
3. Set HF_TOKEN if you have Hugging Face access
|
116 |
|
117 |
+
### Issue: Container fails to start
|
118 |
+
**Solution:**
|
119 |
+
1. Check Docker logs: `docker logs <container_name>`
|
120 |
+
2. Ensure port 7860 is not already in use
|
121 |
+
3. Verify Docker has enough resources (memory/disk)
|
122 |
|
123 |
+
## Development
|
|
|
|
|
|
|
|
|
124 |
|
125 |
+
### Local Development
|
126 |
|
127 |
+
1. **Install dependencies:**
|
128 |
+
```bash
|
129 |
+
pip install -r requirements.txt
|
130 |
+
```
|
|
|
131 |
|
132 |
+
2. **Run locally:**
|
133 |
+
```bash
|
134 |
+
python -m uvicorn app.main:app --host 0.0.0.0 --port 7860
|
135 |
+
```
|
|
|
136 |
|
137 |
+
### Testing
|
138 |
|
139 |
+
1. **Test database connection:**
|
140 |
+
```bash
|
141 |
+
python test_db_connection.py
|
142 |
+
```
|
|
|
143 |
|
144 |
+
2. **Test container environment:**
|
145 |
+
```bash
|
146 |
+
docker run --rm legal-dashboard-ocr python debug_container.py
|
147 |
+
```
|
|
|
148 |
|
149 |
+
## Performance Optimization
|
150 |
|
151 |
+
1. **Model caching:** The application caches Hugging Face models in `/app/cache`
|
152 |
+
2. **Database optimization:** SQLite database is optimized for concurrent access
|
153 |
+
3. **Memory usage:** Consider increasing Docker memory limits for large models
|
|
|
154 |
|
155 |
+
## Security Considerations
|
|
|
|
|
|
|
|
|
156 |
|
157 |
+
1. **Database security:** SQLite database is stored in a volume mount
|
158 |
+
2. **API security:** Consider adding authentication for production use
|
159 |
+
3. **File uploads:** Implement file size limits and type validation
|
|
|
160 |
|
161 |
+
## Monitoring
|
162 |
|
163 |
+
The application provides:
|
164 |
+
- Health check endpoint: `/health`
|
165 |
+
- Real-time logs via Docker
|
166 |
+
- System metrics in the database
|
|
|
167 |
|
168 |
+
## Support
|
169 |
|
170 |
+
For issues not covered in this guide:
|
171 |
+
1. Check the application logs
|
172 |
+
2. Run the debug script
|
173 |
+
3. Verify Docker and system resources
|
Dockerfile
CHANGED
@@ -8,22 +8,30 @@ RUN apt-get update && apt-get install -y \
|
|
8 |
poppler-utils \
|
9 |
tesseract-ocr \
|
10 |
libgl1 \
|
|
|
11 |
&& rm -rf /var/lib/apt/lists/*
|
12 |
|
13 |
# Create volume-safe directories with proper permissions
|
14 |
RUN mkdir -p /app/data /app/cache && chmod -R 777 /app/data /app/cache
|
15 |
|
16 |
-
# Set environment variables for Hugging Face cache
|
17 |
ENV TRANSFORMERS_CACHE=/app/cache
|
18 |
ENV HF_HOME=/app/cache
|
|
|
19 |
|
20 |
# Copy all project files
|
21 |
COPY . .
|
22 |
|
|
|
|
|
|
|
23 |
# Install Python dependencies
|
24 |
RUN pip install --no-cache-dir -r requirements.txt
|
25 |
|
|
|
|
|
|
|
26 |
EXPOSE 7860
|
27 |
|
28 |
-
# Run FastAPI app
|
29 |
-
CMD ["
|
|
|
8 |
poppler-utils \
|
9 |
tesseract-ocr \
|
10 |
libgl1 \
|
11 |
+
curl \
|
12 |
&& rm -rf /var/lib/apt/lists/*
|
13 |
|
14 |
# Create volume-safe directories with proper permissions
|
15 |
RUN mkdir -p /app/data /app/cache && chmod -R 777 /app/data /app/cache
|
16 |
|
17 |
+
# Set environment variables for Hugging Face cache and database
|
18 |
ENV TRANSFORMERS_CACHE=/app/cache
|
19 |
ENV HF_HOME=/app/cache
|
20 |
+
ENV DATABASE_PATH=/app/data/legal_dashboard.db
|
21 |
|
22 |
# Copy all project files
|
23 |
COPY . .
|
24 |
|
25 |
+
# Make startup script executable
|
26 |
+
RUN chmod +x start.sh
|
27 |
+
|
28 |
# Install Python dependencies
|
29 |
RUN pip install --no-cache-dir -r requirements.txt
|
30 |
|
31 |
+
# Ensure data directory permissions are correct
|
32 |
+
RUN chmod -R 777 /app/data
|
33 |
+
|
34 |
EXPOSE 7860
|
35 |
|
36 |
+
# Run FastAPI app using startup script
|
37 |
+
CMD ["./start.sh"]
|
FIXES_SUMMARY.md
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Docker Container Fixes Summary
|
2 |
+
|
3 |
+
## Issues Identified
|
4 |
+
|
5 |
+
1. **Database Connection Error**: `sqlite3.OperationalError: unable to open database file`
|
6 |
+
2. **OCR Model Loading Error**: Incompatible model `microsoft/trocr-base-handwritten`
|
7 |
+
3. **Container Startup Failure**: Database initialization during module import
|
8 |
+
|
9 |
+
## Fixes Applied
|
10 |
+
|
11 |
+
### 1. Database Service Improvements
|
12 |
+
|
13 |
+
**File**: `app/services/database_service.py`
|
14 |
+
|
15 |
+
**Changes**:
|
16 |
+
- Removed automatic database initialization during import
|
17 |
+
- Added explicit `initialize()` method that must be called
|
18 |
+
- Improved directory creation with proper permissions (777)
|
19 |
+
- Added fallback to current directory if `/app/data` fails
|
20 |
+
- Added environment variable support for database path
|
21 |
+
|
22 |
+
**Key Changes**:
|
23 |
+
```python
|
24 |
+
def __init__(self, db_path: str = None):
|
25 |
+
# Use environment variable or default path
|
26 |
+
if db_path is None:
|
27 |
+
db_path = os.getenv('DATABASE_PATH', '/app/data/legal_dashboard.db')
|
28 |
+
|
29 |
+
self.db_path = db_path
|
30 |
+
self.connection = None
|
31 |
+
|
32 |
+
# Ensure data directory exists with proper permissions
|
33 |
+
self._ensure_data_directory()
|
34 |
+
|
35 |
+
# Don't initialize immediately - let it be called explicitly
|
36 |
+
logger.info(f"Database manager initialized with path: {self.db_path}")
|
37 |
+
```
|
38 |
+
|
39 |
+
### 2. OCR Service Improvements
|
40 |
+
|
41 |
+
**File**: `app/services/ocr_service.py`
|
42 |
+
|
43 |
+
**Changes**:
|
44 |
+
- Added multiple compatible model fallbacks
|
45 |
+
- Improved error handling for model loading
|
46 |
+
- Added graceful degradation to basic text extraction
|
47 |
+
- Removed problematic model `microsoft/trocr-base-handwritten`
|
48 |
+
|
49 |
+
**Compatible Models**:
|
50 |
+
1. `microsoft/trocr-base-stage1`
|
51 |
+
2. `microsoft/trocr-base-handwritten`
|
52 |
+
3. `microsoft/trocr-small-stage1`
|
53 |
+
4. `microsoft/trocr-small-handwritten`
|
54 |
+
|
55 |
+
### 3. Docker Configuration Improvements
|
56 |
+
|
57 |
+
**File**: `Dockerfile`
|
58 |
+
|
59 |
+
**Changes**:
|
60 |
+
- Added `curl` for health checks
|
61 |
+
- Added environment variable for database path
|
62 |
+
- Added startup script for proper initialization
|
63 |
+
- Ensured proper permissions on data directory
|
64 |
+
|
65 |
+
**Key Additions**:
|
66 |
+
```dockerfile
|
67 |
+
ENV DATABASE_PATH=/app/data/legal_dashboard.db
|
68 |
+
RUN chmod +x start.sh
|
69 |
+
CMD ["./start.sh"]
|
70 |
+
```
|
71 |
+
|
72 |
+
### 4. Startup Script
|
73 |
+
|
74 |
+
**File**: `start.sh`
|
75 |
+
|
76 |
+
**Purpose**: Ensures proper directory creation and permissions before starting the application
|
77 |
+
|
78 |
+
```bash
|
79 |
+
#!/bin/bash
|
80 |
+
# Create data and cache directories if they don't exist
|
81 |
+
mkdir -p /app/data /app/cache
|
82 |
+
# Set proper permissions
|
83 |
+
chmod -R 777 /app/data /app/cache
|
84 |
+
# Start the application
|
85 |
+
exec uvicorn app.main:app --host 0.0.0.0 --port 7860
|
86 |
+
```
|
87 |
+
|
88 |
+
### 5. Docker Compose Configuration
|
89 |
+
|
90 |
+
**File**: `docker-compose.yml`
|
91 |
+
|
92 |
+
**Changes**:
|
93 |
+
- Added proper volume mounts for data persistence
|
94 |
+
- Added environment variables
|
95 |
+
- Added health check configuration
|
96 |
+
- Improved service naming
|
97 |
+
|
98 |
+
### 6. Debug and Testing Tools
|
99 |
+
|
100 |
+
**Files Created**:
|
101 |
+
- `debug_container.py` - Tests container environment
|
102 |
+
- `test_db_connection.py` - Tests database connectivity
|
103 |
+
- `rebuild_and_test.sh` - Automated rebuild script (Linux/Mac)
|
104 |
+
- `rebuild_and_test.ps1` - Automated rebuild script (Windows)
|
105 |
+
|
106 |
+
### 7. Documentation
|
107 |
+
|
108 |
+
**File**: `DEPLOYMENT_GUIDE.md`
|
109 |
+
|
110 |
+
**Content**:
|
111 |
+
- Comprehensive troubleshooting guide
|
112 |
+
- Step-by-step deployment instructions
|
113 |
+
- Common issues and solutions
|
114 |
+
- Environment variable documentation
|
115 |
+
|
116 |
+
## Testing the Fixes
|
117 |
+
|
118 |
+
### Quick Test Commands
|
119 |
+
|
120 |
+
1. **Test Database Connection**:
|
121 |
+
```bash
|
122 |
+
docker run --rm legal-dashboard-ocr python debug_container.py
|
123 |
+
```
|
124 |
+
|
125 |
+
2. **Rebuild and Test** (Windows):
|
126 |
+
```powershell
|
127 |
+
.\rebuild_and_test.ps1
|
128 |
+
```
|
129 |
+
|
130 |
+
3. **Rebuild and Test** (Linux/Mac):
|
131 |
+
```bash
|
132 |
+
./rebuild_and_test.sh
|
133 |
+
```
|
134 |
+
|
135 |
+
4. **Manual Docker Compose**:
|
136 |
+
```bash
|
137 |
+
docker-compose up --build
|
138 |
+
```
|
139 |
+
|
140 |
+
## Expected Results
|
141 |
+
|
142 |
+
After applying these fixes:
|
143 |
+
|
144 |
+
1. β
**Container starts successfully** without database errors
|
145 |
+
2. β
**OCR models load properly** with fallback support
|
146 |
+
3. β
**Database is accessible** and persistent across restarts
|
147 |
+
4. β
**Health endpoint responds** correctly
|
148 |
+
5. β
**Application is accessible** at `http://localhost:7860`
|
149 |
+
|
150 |
+
## Environment Variables
|
151 |
+
|
152 |
+
| Variable | Default | Purpose |
|
153 |
+
|----------|---------|---------|
|
154 |
+
| `DATABASE_PATH` | `/app/data/legal_dashboard.db` | SQLite database location |
|
155 |
+
| `TRANSFORMERS_CACHE` | `/app/cache` | Hugging Face model cache |
|
156 |
+
| `HF_HOME` | `/app/cache` | Hugging Face home directory |
|
157 |
+
| `HF_TOKEN` | (not set) | Hugging Face authentication |
|
158 |
+
|
159 |
+
## Volume Mounts
|
160 |
+
|
161 |
+
- `./data:/app/data` - Database and uploaded files
|
162 |
+
- `./cache:/app/cache` - Hugging Face model cache
|
163 |
+
|
164 |
+
## Next Steps
|
165 |
+
|
166 |
+
1. **Test the application** using the provided scripts
|
167 |
+
2. **Monitor logs** for any remaining issues
|
168 |
+
3. **Deploy to production** if testing is successful
|
169 |
+
4. **Add authentication** for production use
|
170 |
+
5. **Implement monitoring** for long-term stability
|
171 |
+
|
172 |
+
## Support
|
173 |
+
|
174 |
+
If issues persist:
|
175 |
+
1. Check container logs: `docker logs <container_name>`
|
176 |
+
2. Run debug script: `docker exec -it <container> python debug_container.py`
|
177 |
+
3. Verify Docker resources (memory, disk space)
|
178 |
+
4. Check network connectivity for model downloads
|
app/main.py
CHANGED
@@ -63,6 +63,9 @@ ocr_pipeline = OCRPipeline()
|
|
63 |
db_manager = DatabaseManager()
|
64 |
ai_engine = AIScoringEngine()
|
65 |
|
|
|
|
|
|
|
66 |
# WebSocket manager
|
67 |
|
68 |
|
|
|
63 |
db_manager = DatabaseManager()
|
64 |
ai_engine = AIScoringEngine()
|
65 |
|
66 |
+
# Initialize database manager (but don't connect yet)
|
67 |
+
logger.info("Database manager created, will initialize on startup")
|
68 |
+
|
69 |
# WebSocket manager
|
70 |
|
71 |
|
app/services/database_service.py
CHANGED
@@ -20,16 +20,45 @@ logger = logging.getLogger(__name__)
|
|
20 |
class DatabaseManager:
|
21 |
"""Database manager for legal documents"""
|
22 |
|
23 |
-
def __init__(self, db_path: str =
|
|
|
|
|
|
|
|
|
|
|
24 |
self.db_path = db_path
|
25 |
self.connection = None
|
26 |
-
# Create directory if it doesn't exist
|
27 |
-
os.makedirs(os.path.dirname(self.db_path), exist_ok=True)
|
28 |
-
self._init_database()
|
29 |
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
"""Initialize database and create tables"""
|
32 |
try:
|
|
|
|
|
33 |
self.connection = sqlite3.connect(
|
34 |
self.db_path, check_same_thread=False)
|
35 |
self.connection.row_factory = sqlite3.Row
|
|
|
20 |
class DatabaseManager:
|
21 |
"""Database manager for legal documents"""
|
22 |
|
23 |
+
def __init__(self, db_path: str = None):
|
24 |
+
# Use environment variable or default path
|
25 |
+
if db_path is None:
|
26 |
+
db_path = os.getenv(
|
27 |
+
'DATABASE_PATH', '/app/data/legal_dashboard.db')
|
28 |
+
|
29 |
self.db_path = db_path
|
30 |
self.connection = None
|
|
|
|
|
|
|
31 |
|
32 |
+
# Ensure data directory exists with proper permissions
|
33 |
+
self._ensure_data_directory()
|
34 |
+
|
35 |
+
# Don't initialize immediately - let it be called explicitly
|
36 |
+
logger.info(f"Database manager initialized with path: {self.db_path}")
|
37 |
+
|
38 |
+
def _ensure_data_directory(self):
|
39 |
+
"""Ensure the data directory exists with proper permissions"""
|
40 |
+
try:
|
41 |
+
data_dir = os.path.dirname(self.db_path)
|
42 |
+
if not os.path.exists(data_dir):
|
43 |
+
os.makedirs(data_dir, mode=0o777, exist_ok=True)
|
44 |
+
logger.info(f"Created data directory: {data_dir}")
|
45 |
+
|
46 |
+
# Ensure the directory is writable
|
47 |
+
if not os.access(data_dir, os.W_OK):
|
48 |
+
os.chmod(data_dir, 0o777)
|
49 |
+
logger.info(f"Set write permissions on: {data_dir}")
|
50 |
+
|
51 |
+
except Exception as e:
|
52 |
+
logger.error(f"Failed to ensure data directory: {e}")
|
53 |
+
# Fallback to current directory
|
54 |
+
self.db_path = os.path.join(os.getcwd(), 'legal_dashboard.db')
|
55 |
+
logger.info(f"Using fallback database path: {self.db_path}")
|
56 |
+
|
57 |
+
def initialize(self):
|
58 |
"""Initialize database and create tables"""
|
59 |
try:
|
60 |
+
self._ensure_data_directory()
|
61 |
+
|
62 |
self.connection = sqlite3.connect(
|
63 |
self.db_path, check_same_thread=False)
|
64 |
self.connection.row_factory = sqlite3.Row
|
app/services/ocr_service.py
CHANGED
@@ -55,71 +55,58 @@ class OCRPipeline:
|
|
55 |
if self.initialization_attempted:
|
56 |
return
|
57 |
|
58 |
-
|
59 |
-
logger.info(f"Loading Hugging Face OCR model: {self.model_name}")
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
"image-to-text",
|
75 |
-
model=self.model_name,
|
76 |
-
use_auth_token=self.hf_token
|
77 |
-
)
|
78 |
-
else:
|
79 |
-
self.ocr_pipeline = pipeline(
|
80 |
-
"image-to-text",
|
81 |
-
model=self.model_name
|
82 |
-
)
|
83 |
-
self.initialized = True
|
84 |
-
logger.info(
|
85 |
-
"Hugging Face OCR pipeline initialized successfully")
|
86 |
-
break
|
87 |
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
time.sleep(retry_delay)
|
92 |
-
else:
|
93 |
-
# Fallback to a simpler model
|
94 |
-
try:
|
95 |
-
logger.info(
|
96 |
-
"Trying fallback model: microsoft/trocr-base-handwritten")
|
97 |
-
# Initialize fallback pipeline with or without token
|
98 |
-
if self.hf_token:
|
99 |
-
self.ocr_pipeline = pipeline(
|
100 |
-
"image-to-text",
|
101 |
-
model="microsoft/trocr-base-handwritten",
|
102 |
-
use_auth_token=self.hf_token
|
103 |
-
)
|
104 |
-
else:
|
105 |
-
self.ocr_pipeline = pipeline(
|
106 |
-
"image-to-text",
|
107 |
-
model="microsoft/trocr-base-handwritten"
|
108 |
-
)
|
109 |
-
self.initialized = True
|
110 |
-
logger.info(
|
111 |
-
"Fallback OCR pipeline initialized successfully")
|
112 |
-
except Exception as fallback_error:
|
113 |
-
logger.error(
|
114 |
-
f"Fallback model also failed: {fallback_error}")
|
115 |
-
raise
|
116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
except Exception as e:
|
118 |
logger.error(f"Error setting up Hugging Face OCR: {e}")
|
119 |
self.initialized = False
|
120 |
|
121 |
-
self.initialization_attempted = True
|
122 |
-
|
123 |
def extract_text_from_pdf(self, pdf_path: str) -> Dict[str, Any]:
|
124 |
"""
|
125 |
Extract text from PDF document with intelligent content detection
|
|
|
55 |
if self.initialization_attempted:
|
56 |
return
|
57 |
|
58 |
+
self.initialization_attempted = True
|
|
|
59 |
|
60 |
+
# List of compatible models to try
|
61 |
+
compatible_models = [
|
62 |
+
"microsoft/trocr-base-stage1",
|
63 |
+
"microsoft/trocr-base-handwritten",
|
64 |
+
"microsoft/trocr-small-stage1",
|
65 |
+
"microsoft/trocr-small-handwritten"
|
66 |
+
]
|
67 |
|
68 |
+
for model in compatible_models:
|
69 |
+
try:
|
70 |
+
logger.info(f"Loading Hugging Face OCR model: {model}")
|
71 |
+
|
72 |
+
# Use Hugging Face token from environment variable
|
73 |
+
if not self.hf_token:
|
74 |
+
logger.warning(
|
75 |
+
"HF_TOKEN not found in environment variables")
|
76 |
+
|
77 |
+
# Initialize the OCR pipeline
|
78 |
+
if self.hf_token:
|
79 |
+
self.ocr_pipeline = pipeline(
|
80 |
+
"image-to-text",
|
81 |
+
model=model,
|
82 |
+
use_auth_token=self.hf_token
|
83 |
+
)
|
84 |
+
else:
|
85 |
+
self.ocr_pipeline = pipeline(
|
86 |
+
"image-to-text",
|
87 |
+
model=model
|
88 |
+
)
|
89 |
|
90 |
+
self.model_name = model
|
91 |
+
self.initialized = True
|
92 |
+
logger.info(
|
93 |
+
f"Hugging Face OCR pipeline initialized successfully with model: {model}")
|
94 |
+
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
+
except Exception as e:
|
97 |
+
logger.warning(f"Failed to load model {model}: {e}")
|
98 |
+
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
+
# If all models fail, try a basic approach
|
101 |
+
try:
|
102 |
+
logger.info("All OCR models failed, using basic text extraction")
|
103 |
+
self.initialized = True
|
104 |
+
self.ocr_pipeline = None
|
105 |
+
logger.info("Using basic text extraction as fallback")
|
106 |
except Exception as e:
|
107 |
logger.error(f"Error setting up Hugging Face OCR: {e}")
|
108 |
self.initialized = False
|
109 |
|
|
|
|
|
110 |
def extract_text_from_pdf(self, pdf_path: str) -> Dict[str, Any]:
|
111 |
"""
|
112 |
Extract text from PDF document with intelligent content detection
|
debug_container.py
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""
|
3 |
+
Debug script for Docker container environment
|
4 |
+
"""
|
5 |
+
|
6 |
+
import os
|
7 |
+
import sys
|
8 |
+
import sqlite3
|
9 |
+
import logging
|
10 |
+
|
11 |
+
# Set up logging
|
12 |
+
logging.basicConfig(level=logging.INFO)
|
13 |
+
logger = logging.getLogger(__name__)
|
14 |
+
|
15 |
+
|
16 |
+
def debug_environment():
|
17 |
+
"""Debug the container environment"""
|
18 |
+
print("=== Container Environment Debug ===")
|
19 |
+
|
20 |
+
# Check current directory
|
21 |
+
print(f"Current directory: {os.getcwd()}")
|
22 |
+
|
23 |
+
# Check if /app/data exists
|
24 |
+
data_dir = "/app/data"
|
25 |
+
if os.path.exists(data_dir):
|
26 |
+
print(f"β
Data directory exists: {data_dir}")
|
27 |
+
print(f" Permissions: {oct(os.stat(data_dir).st_mode)[-3:]}")
|
28 |
+
print(f" Writable: {os.access(data_dir, os.W_OK)}")
|
29 |
+
else:
|
30 |
+
print(f"β Data directory does not exist: {data_dir}")
|
31 |
+
|
32 |
+
# Check environment variables
|
33 |
+
print(f"DATABASE_PATH: {os.getenv('DATABASE_PATH', 'Not set')}")
|
34 |
+
print(f"TRANSFORMERS_CACHE: {os.getenv('TRANSFORMERS_CACHE', 'Not set')}")
|
35 |
+
print(f"HF_HOME: {os.getenv('HF_HOME', 'Not set')}")
|
36 |
+
|
37 |
+
# Try to create data directory
|
38 |
+
try:
|
39 |
+
os.makedirs(data_dir, mode=0o777, exist_ok=True)
|
40 |
+
print(f"β
Created/verified data directory: {data_dir}")
|
41 |
+
except Exception as e:
|
42 |
+
print(f"β Failed to create data directory: {e}")
|
43 |
+
|
44 |
+
# Try database connection
|
45 |
+
try:
|
46 |
+
db_path = os.getenv('DATABASE_PATH', '/app/data/legal_dashboard.db')
|
47 |
+
print(f"Testing database connection to: {db_path}")
|
48 |
+
|
49 |
+
# Ensure directory exists
|
50 |
+
db_dir = os.path.dirname(db_path)
|
51 |
+
os.makedirs(db_dir, mode=0o777, exist_ok=True)
|
52 |
+
|
53 |
+
# Test connection
|
54 |
+
conn = sqlite3.connect(db_path)
|
55 |
+
cursor = conn.cursor()
|
56 |
+
cursor.execute("SELECT 1")
|
57 |
+
result = cursor.fetchone()
|
58 |
+
print(f"β
Database connection successful: {result}")
|
59 |
+
conn.close()
|
60 |
+
|
61 |
+
except Exception as e:
|
62 |
+
print(f"β Database connection failed: {e}")
|
63 |
+
|
64 |
+
|
65 |
+
if __name__ == "__main__":
|
66 |
+
debug_environment()
|
docker-compose.yml
CHANGED
@@ -1,16 +1,17 @@
|
|
1 |
-
version:
|
2 |
|
3 |
services:
|
4 |
-
|
5 |
build: .
|
6 |
ports:
|
7 |
- "7860:7860"
|
8 |
volumes:
|
9 |
- ./data:/app/data
|
10 |
-
- ./
|
11 |
environment:
|
12 |
-
-
|
13 |
-
-
|
|
|
14 |
restart: unless-stopped
|
15 |
healthcheck:
|
16 |
test: ["CMD", "curl", "-f", "http://localhost:7860/health"]
|
|
|
1 |
+
version: '3.8'
|
2 |
|
3 |
services:
|
4 |
+
legal-dashboard:
|
5 |
build: .
|
6 |
ports:
|
7 |
- "7860:7860"
|
8 |
volumes:
|
9 |
- ./data:/app/data
|
10 |
+
- ./cache:/app/cache
|
11 |
environment:
|
12 |
+
- DATABASE_PATH=/app/data/legal_dashboard.db
|
13 |
+
- TRANSFORMERS_CACHE=/app/cache
|
14 |
+
- HF_HOME=/app/cache
|
15 |
restart: unless-stopped
|
16 |
healthcheck:
|
17 |
test: ["CMD", "curl", "-f", "http://localhost:7860/health"]
|
rebuild_and_test.ps1
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Write-Host "π§ Rebuilding and testing Legal Dashboard OCR Docker container..." -ForegroundColor Green
|
2 |
+
|
3 |
+
# Stop any running containers
|
4 |
+
Write-Host "Stopping existing containers..." -ForegroundColor Yellow
|
5 |
+
docker-compose down 2>$null
|
6 |
+
docker stop legal-dashboard-ocr 2>$null
|
7 |
+
|
8 |
+
# Remove old images
|
9 |
+
Write-Host "Removing old images..." -ForegroundColor Yellow
|
10 |
+
docker rmi legal-dashboard-ocr 2>$null
|
11 |
+
|
12 |
+
# Create data and cache directories
|
13 |
+
Write-Host "Creating data and cache directories..." -ForegroundColor Yellow
|
14 |
+
New-Item -ItemType Directory -Force -Path "data" | Out-Null
|
15 |
+
New-Item -ItemType Directory -Force -Path "cache" | Out-Null
|
16 |
+
|
17 |
+
# Build the new image
|
18 |
+
Write-Host "Building new Docker image..." -ForegroundColor Yellow
|
19 |
+
docker build -t legal-dashboard-ocr .
|
20 |
+
|
21 |
+
# Test the container
|
22 |
+
Write-Host "Testing container..." -ForegroundColor Yellow
|
23 |
+
docker run --rm -v ${PWD}/data:/app/data -v ${PWD}/cache:/app/cache legal-dashboard-ocr python debug_container.py
|
24 |
+
|
25 |
+
# Start with docker-compose
|
26 |
+
Write-Host "Starting with docker-compose..." -ForegroundColor Yellow
|
27 |
+
docker-compose up --build -d
|
28 |
+
|
29 |
+
# Wait a moment for startup
|
30 |
+
Write-Host "Waiting for application to start..." -ForegroundColor Yellow
|
31 |
+
Start-Sleep -Seconds 10
|
32 |
+
|
33 |
+
# Test health endpoint
|
34 |
+
Write-Host "Testing health endpoint..." -ForegroundColor Yellow
|
35 |
+
try {
|
36 |
+
Invoke-WebRequest -Uri "http://localhost:7860/health" -UseBasicParsing | Out-Null
|
37 |
+
Write-Host "β
Health check passed" -ForegroundColor Green
|
38 |
+
}
|
39 |
+
catch {
|
40 |
+
Write-Host "β Health check failed" -ForegroundColor Red
|
41 |
+
}
|
42 |
+
|
43 |
+
Write-Host "β
Rebuild and test complete!" -ForegroundColor Green
|
44 |
+
Write-Host "Access the application at: http://localhost:7860" -ForegroundColor Cyan
|
rebuild_and_test.sh
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
echo "π§ Rebuilding and testing Legal Dashboard OCR Docker container..."
|
4 |
+
|
5 |
+
# Stop any running containers
|
6 |
+
echo "Stopping existing containers..."
|
7 |
+
docker-compose down 2>/dev/null || true
|
8 |
+
docker stop legal-dashboard-ocr 2>/dev/null || true
|
9 |
+
|
10 |
+
# Remove old images
|
11 |
+
echo "Removing old images..."
|
12 |
+
docker rmi legal-dashboard-ocr 2>/dev/null || true
|
13 |
+
|
14 |
+
# Create data and cache directories
|
15 |
+
echo "Creating data and cache directories..."
|
16 |
+
mkdir -p data cache
|
17 |
+
chmod -R 777 data cache
|
18 |
+
|
19 |
+
# Build the new image
|
20 |
+
echo "Building new Docker image..."
|
21 |
+
docker build -t legal-dashboard-ocr .
|
22 |
+
|
23 |
+
# Test the container
|
24 |
+
echo "Testing container..."
|
25 |
+
docker run --rm -v $(pwd)/data:/app/data -v $(pwd)/cache:/app/cache legal-dashboard-ocr python debug_container.py
|
26 |
+
|
27 |
+
# Start with docker-compose
|
28 |
+
echo "Starting with docker-compose..."
|
29 |
+
docker-compose up --build -d
|
30 |
+
|
31 |
+
# Wait a moment for startup
|
32 |
+
echo "Waiting for application to start..."
|
33 |
+
sleep 10
|
34 |
+
|
35 |
+
# Test health endpoint
|
36 |
+
echo "Testing health endpoint..."
|
37 |
+
curl -f http://localhost:7860/health || echo "Health check failed"
|
38 |
+
|
39 |
+
echo "β
Rebuild and test complete!"
|
40 |
+
echo "Access the application at: http://localhost:7860"
|
start.sh
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
# Create data and cache directories if they don't exist
|
4 |
+
mkdir -p /app/data /app/cache
|
5 |
+
|
6 |
+
# Set proper permissions
|
7 |
+
chmod -R 777 /app/data /app/cache
|
8 |
+
|
9 |
+
# Start the application
|
10 |
+
exec uvicorn app.main:app --host 0.0.0.0 --port 7860
|
test_db_connection.py
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""
|
3 |
+
Test database connection in Docker environment
|
4 |
+
"""
|
5 |
+
|
6 |
+
from app.services.database_service import DatabaseManager
|
7 |
+
import os
|
8 |
+
import sys
|
9 |
+
import sqlite3
|
10 |
+
import logging
|
11 |
+
|
12 |
+
# Add the app directory to the path
|
13 |
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'app'))
|
14 |
+
|
15 |
+
|
16 |
+
def test_database_connection():
|
17 |
+
"""Test database connection and initialization"""
|
18 |
+
print("Testing database connection...")
|
19 |
+
|
20 |
+
try:
|
21 |
+
# Test with default path
|
22 |
+
db_manager = DatabaseManager()
|
23 |
+
print(f"β
Database manager created with path: {db_manager.db_path}")
|
24 |
+
|
25 |
+
# Test initialization
|
26 |
+
db_manager.initialize()
|
27 |
+
print("β
Database initialized successfully")
|
28 |
+
|
29 |
+
# Test connection
|
30 |
+
if db_manager.is_connected():
|
31 |
+
print("β
Database connection verified")
|
32 |
+
else:
|
33 |
+
print("β Database connection failed")
|
34 |
+
return False
|
35 |
+
|
36 |
+
# Test basic operations
|
37 |
+
cursor = db_manager.connection.cursor()
|
38 |
+
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
39 |
+
tables = cursor.fetchall()
|
40 |
+
print(f"β
Found {len(tables)} tables in database")
|
41 |
+
|
42 |
+
db_manager.close()
|
43 |
+
print("β
Database connection closed successfully")
|
44 |
+
|
45 |
+
return True
|
46 |
+
|
47 |
+
except Exception as e:
|
48 |
+
print(f"β Database test failed: {e}")
|
49 |
+
return False
|
50 |
+
|
51 |
+
|
52 |
+
if __name__ == "__main__":
|
53 |
+
success = test_database_connection()
|
54 |
+
sys.exit(0 if success else 1)
|