Sistema OCR para documentos y PDFs - 100% dockerizado, cero instalaciones locales.
- Vision General
- Arquitectura del Sistema
- Patrones de Diseño
- Principios SOLID
- Requisitos
- Estructura del Proyecto
- Inicio Rapido
- Comandos Docker
- Desarrollo
- Testing
- API del Motor OCR
- ADRs (Architecture Decision Records)
- Troubleshooting
- Licencia
Python-OCR es un sistema de reconocimiento optico de caracteres (OCR) moderno y escalable, diseñado con principios de Clean Architecture y Clean Code. El proyecto implementa extraccion de texto de imagenes y documentos PDF utilizando Tesseract-OCR, con una interfaz web interactiva construida con Streamlit.
- Arquitectura Limpia: Separacion clara de responsabilidades entre capas
- Principios SOLID: Codigo mantenible y extensible
- Test-Driven Development (TDD): Cobertura de pruebas unitarias
- Dockerizado: Despliegue consistente sin dependencias locales
- Type Hints: Codigo Python completamente tipado
- Multi-formato: Soporte para imagenes (JPG, PNG, WEBP) y PDFs
┌─────────────────────────────────────────────────────┐
│ PRESENTATION │
│ (Streamlit UI) │
│ src/ocr/app.py │
├─────────────────────────────────────────────────────┤
│ BUSINESS LOGIC │
│ (OCR Engine Core) │
│ src/ocr/engine.py │
│ ┌──────────────┬──────────────┬──────────────┐ │
│ │ Extract │ Visualize │ Format │ │
│ │ Methods │ Methods │ Methods │ │
│ └──────────────┴──────────────┴──────────────┘ │
├─────────────────────────────────────────────────────┤
│ INFRASTRUCTURE LAYER │
│ ┌──────────────┬──────────────┬──────────────┐ │
│ │ Tesseract │ OpenCV │ PyMuPDF │ │
│ │ OCR │ Processing │ PDF Parse │ │
│ └──────────────┴──────────────┴──────────────┘ │
└─────────────────────────────────────────────────────┘
- Responsabilidad: Interaccion con el usuario
- Componentes: Streamlit UI, File uploads, Results display
- Principio: Separation of Concerns (SoC)
- Responsabilidad: Logica de procesamiento OCR
- Componentes: OCREngine class, Text extraction, Box visualization
- Principio: Single Responsibility Principle (SRP)
- Responsabilidad: Integracion con herramientas externas
- Componentes: Tesseract, OpenCV, PyMuPDF, PIL
- Principio: Dependency Inversion Principle (DIP)
Ubicacion: OCREngine class
Proposito: Proporcionar metodos estaticos para crear y procesar resultados OCR sin necesidad de instanciar la clase.
class OCREngine:
@staticmethod
def extract_text_and_boxes(image_path: str) -> Dict[str, Any]:
# Factory method for text extraction
passBeneficios:
- No requiere instancia de clase
- Simplifica el API
- Cacheo eficiente con
@st.cache_data
Ubicacion: OCREngine class
Proposito: Proporcionar una interfaz simplificada para operaciones complejas de OCR.
# Facade oculta complejidad de pytesseract, OpenCV, PIL
result = OCREngine.extract_text_and_boxes("image.jpg")Beneficios:
- API simple para operaciones complejas
- Encapsula multiples librerias (pytesseract, cv2, PIL)
- Facilita el testing y mantenimiento
Ubicacion: Multiple extraction methods Proposito: Diferentes estrategias para procesar imagenes vs PDFs.
# Strategy 1: Image extraction
extract_text_and_boxes(image_path)
# Strategy 2: PDF extraction
extract_text_from_pdf(pdf_path)Beneficios:
- Flexibilidad para agregar nuevos formatos
- Codigo desacoplado por tipo de archivo
Ubicacion: PDF processing Proposito: Definir estructura algoritmica para procesamiento de PDFs multi-pagina.
def extract_text_from_pdf(pdf_path: str) -> Dict[str, Any]:
# 1. Convert PDF to images
image_paths = OCREngine.pdf_to_images(pdf_path)
# 2. Process each page
for img_path in image_paths:
result = OCREngine.extract_text_and_boxes(img_path)
# 3. Aggregate results
return aggregated_resultUbicacion: Streamlit decorators Proposito: Optimizar rendimiento cacheando configuracion de Tesseract.
@st.cache_data
def configure_tesseract() -> None:
# Configuration cached across reruns
passImplementacion:
OCREngine: Solo maneja logica OCRapp.py: Solo maneja UI y presentaciontest_engine.py: Solo maneja testing
Ejemplo:
# OCREngine tiene una sola razon para cambiar: logica OCR
class OCREngine:
@staticmethod
def extract_text_and_boxes(image_path: str) -> Dict[str, Any]:
# Solo extraccion de texto
passImplementacion: El sistema esta abierto a extension (nuevos formatos) pero cerrado a modificacion.
Ejemplo:
# Facil agregar nuevo formato sin modificar codigo existente
@staticmethod
def extract_text_from_tiff(tiff_path: str) -> Dict[str, Any]:
# Nueva funcionalidad sin modificar metodos existentes
passImplementacion: Metodos estaticos devuelven estructuras de datos consistentes.
Ejemplo:
# Todos los metodos de extraccion devuelven el mismo contrato
result = extract_text_and_boxes(path) # Dict[str, Any]
result = extract_text_from_pdf(path) # Dict[str, Any]
# Ambos retornan: {"file", "full_text", "boxes", "total_lines"}Implementacion: Metodos pequeños y especificos en lugar de una interfaz monolitica.
Ejemplo:
# Metodos especificos en lugar de un metodo gigante
extract_text_and_boxes() # Solo extraccion
visualize_boxes() # Solo visualizacion
generate_markdown() # Solo formato markdown
generate_plain_text() # Solo formato texto planoImplementacion: Dependencia de abstracciones (pytesseract API) en lugar de implementaciones concretas.
Ejemplo:
# OCREngine depende de la abstraccion pytesseract, no de Tesseract directamente
data = pytesseract.image_to_data(image, lang="spa")
# Podria cambiarse a otro engine OCR modificando solo esta linea- Docker Desktop instalado
- Nada mas
python-ocr/
├── src/
│ └── ocr/
│ ├── __init__.py
│ ├── engine.py # Motor OCR con Tesseract
│ └── app.py # Aplicacion Streamlit
├── tests/
│ ├── __init__.py
│ ├── conftest.py # Fixtures de pytest
│ └── test_engine.py # Tests unitarios
├── docs/
│ ├── ARCHITECTURE.md # Documentacion arquitectura
│ ├── CLEAN_CODE_GUIDE.md # Guia Clean Code
│ └── MACOS_SETUP.md # Setup local macOS
├── outputs/ # Resultados OCR (ignorado por git)
├── uploads/ # Archivos temporales
├── Dockerfile
├── docker-compose.yml
├── Makefile # Comandos de desarrollo
├── requirements.txt
├── requirements-dev.txt
├── pyproject.toml
├── LICENSE
└── README.md
# Iniciar aplicación
docker-compose up --buildEl contenedor incluye TODO:
- Python 3.11
- Tesseract-OCR + idioma español
- PyMuPDF para PDFs
- Todas las dependencias
- Streamlit configurado
# Iniciar (primer plano)
docker-compose up --build
# Iniciar (segundo plano)
docker-compose up -d --build
# Detener
docker-compose down
# Ver logs
docker-compose logs -f
# Reconstruir limpio
docker-compose down && docker-compose build --no-cache && docker-compose up- Sube una imagen y extrae todo el texto detectado
- Exporta a JSON, Markdown o TXT
- Muestra estadisticas de lineas detectadas
- Dibuja cajas delimitadoras sobre el texto detectado
- Muestra confianza de cada deteccion
- Descarga imagen anotada
- Procesa multiples imagenes simultaneamente
- Genera tabla resumen con resultados
- Exporta resultados a CSV
| Formato | Extensión | Notas |
|---|---|---|
| JPEG | .jpg, .jpeg | Imágenes estándar |
| PNG | .png | Transparencia soportada |
| WebP | .webp | Formato moderno |
| Multi-página con PyMuPDF |
- Imagen base:
python:3.11-slim - Sistema: Tesseract-OCR + español
- Puerto: 8501
- Volúmenes: outputs, uploads, src (hot reload)
- Streamlit 1.39.0 - Interfaz web
- pytesseract - Wrapper Python para Tesseract
- PyMuPDF - Procesamiento PDFs
- OpenCV-headless - Procesamiento imágenes
- Pillow - Manipulación imágenes
- Motor: Tesseract 5.x
- Idioma: Español (spa)
- Método:
pytesseract.image_to_data() - Output: Texto + coordenadas + confianza
El proyecto implementa Test-Driven Development (TDD) con pytest.
tests/
├── __init__.py
├── conftest.py # Fixtures compartidos
└── test_engine.py # Tests unitarios del motor OCR
class TestOCREngineExtraction:
def test_extract_text_returns_dict()
def test_extract_text_file_field()
def test_extract_text_boxes_is_list()
def test_extract_empty_image()class TestOCREngineFormatters:
def test_generate_markdown_contains_header()
def test_generate_markdown_contains_stats()
def test_generate_plain_text()class TestOCREngineVisualization:
def test_visualize_boxes_creates_file()
def test_visualize_boxes_returns_path()
def test_visualize_boxes_invalid_image_raises()class TestOCREngineBoxStructure:
def test_box_contains_required_fields()
def test_box_confidence_is_float()
def test_box_bbox_is_list()# Todos los tests
make test
# Con detalles verbose
docker-compose exec ocr-app pytest tests/ -v
# Con cobertura
docker-compose exec ocr-app pytest tests/ --cov=src/ocr --cov-report=term
# Test especifico
docker-compose exec ocr-app pytest tests/test_engine.py::TestOCREngineExtraction -v@pytest.fixture
def sample_image() -> Generator[str, None, None]:
"""Create temporary sample image with text for OCR testing."""
# Creates image with "Hello World", "OCR Test Image", "Python 2025"
@pytest.fixture
def empty_image() -> Generator[str, None, None]:
"""Create temporary blank image for testing edge cases."""- Variables:
snake_case(e.g.,image_path,full_text) - Classes:
PascalCase(e.g.,OCREngine) - Constants:
UPPER_SNAKE_CASE(e.g.,OUTPUT_DIR) - Functions: Descriptive verbs (e.g.,
extract_text_and_boxes,visualize_boxes)
def extract_text_and_boxes(image_path: str) -> Dict[str, Any]:
"""Fully typed function signatures."""
pass- Docstrings en formato Google Style
- Comentarios explicativos en ingles
- README completo con ejemplos
- Modularidad: Funciones pequenas y especificas
- DRY (Don't Repeat Yourself): Codigo reutilizable
- YAGNI (You Aren't Gonna Need It): Sin codigo innecesario
- KISS (Keep It Simple, Stupid): Soluciones simples
try:
result = OCREngine.extract_text_and_boxes(temp_path)
except Exception as e:
st.error(f"Error al procesar la imagen: {str(e)}")
finally:
if os.path.exists(temp_path):
os.remove(temp_path)- Backlog: Features organizados por prioridad
- Sprint: Iteraciones de 2 semanas
- Daily Standup: Progreso diario
- Sprint Review: Demo de features completados
- Retrospective: Mejora continua
- Codigo implementado
- Tests unitarios pasando
- Documentacion actualizada
- Code review aprobado
- Sin linter errors
- Dockerfile actualizado si es necesario
- Funcionalidad: Codigo cumple requisitos
- Tests: Cobertura adecuada de pruebas
- SOLID: Principios respetados
- Clean Code: Nombres descriptivos, funciones pequenas
- Type Hints: Tipos declarados correctamente
- Documentacion: Docstrings actualizados
- Error Handling: Excepciones manejadas apropiadamente
- Performance: Sin operaciones innecesarias
- Security: Sin datos sensibles expuestos
## Descripcion
[Descripcion clara del cambio]
## Tipo de Cambio
- [ ] Bug fix
- [ ] Nueva feature
- [ ] Breaking change
- [ ] Documentacion
## Tests
- [ ] Tests unitarios agregados/actualizados
- [ ] Tests locales pasando
## Checklist
- [ ] Codigo sigue guias de estilo
- [ ] Docstrings actualizados
- [ ] No rompe funcionalidad existenteEl directorio src/ esta montado como volumen. Los cambios se reflejan automaticamente:
# Editar codigo
nano src/ocr/engine.py
# Streamlit detecta cambios y recargamake help # Mostrar todos los comandos disponibles
make start # Iniciar aplicacion en segundo plano
make stop # Detener aplicacion
make build # Construir imagen Docker
make rebuild # Reconstruir y reiniciar
make logs # Ver logs en tiempo real
make clean # Limpiar outputs y contenedores
make dev # Modo desarrollo (attached)
make test # Ejecutar tests
make lint # Ejecutar linter (ruff)
make format # Formatear codigo (black/ruff)
make shell # Abrir shell en contenedor
make status # Ver estado de contenedores# Linter (ruff)
make lint
# Formatear codigo
make format
# Pre-commit hooks (opcional)
pip install pre-commit
pre-commit install# Logs en tiempo real
docker-compose logs -f
# Ultimas 100 lineas
docker-compose logs --tail=100# Si cambias requirements.txt o Dockerfile
docker-compose down
docker-compose build --no-cache
docker-compose upfrom ocr.engine import OCREngine
# Extraer texto de imagen
result = OCREngine.extract_text_and_boxes("imagen.jpg")
# result = {
# "file": "imagen.jpg",
# "full_text": "Texto extraido...",
# "boxes": [...],
# "total_lines": 10
# }
# Generar markdown
markdown = OCREngine.generate_markdown(result)
# Generar texto plano
plain_text = OCREngine.generate_plain_text(result)
# Visualizar cajas delimitadoras
OCREngine.visualize_boxes("imagen.jpg", "output.png")Extrae texto y coordenadas de cajas delimitadoras de una imagen.
Parametros:
image_path: Ruta a la imagen de entrada
Retorna:
{
"file": str, # Nombre del archivo
"full_text": str, # Texto completo extraido
"boxes": [ # Lista de cajas detectadas
{
"text": str, # Texto de la caja
"confidence": float, # Confianza (0.0-1.0)
"bbox": [[x,y], [x,y], [x,y], [x,y]] # Coordenadas
}
],
"total_lines": int # Total de lineas detectadas
}Extrae texto de todas las paginas de un PDF.
Parametros:
pdf_path: Ruta al archivo PDF de entrada
Retorna:
{
"file": str,
"full_text": str, # Texto combinado de todas las paginas
"boxes": [...], # Boxes con campo "page" adicional
"total_lines": int,
"total_pages": int # Total de paginas procesadas
}Dibuja cajas delimitadoras sobre la imagen.
Parametros:
image_path: Ruta a la imagen de entradaoutput_path: Ruta donde guardar la imagen anotada
Retorna: Ruta al archivo guardado
Visualizacion:
- Cajas delimitadoras: Verde
(0, 255, 0) - Etiquetas de texto: Rojo
(255, 0, 0) - Fondo de etiquetas: Blanco con transparencia
Genera texto formateado en Markdown.
Parametros:
result: Diccionario de resultados OCR
Retorna: String en formato Markdown
Genera texto plano sin formato.
Parametros:
result: Diccionario de resultados OCR
Retorna: String de texto plano
Convierte paginas de PDF a imagenes temporales.
Parametros:
pdf_path: Ruta al archivo PDF
Retorna: Lista de rutas a imagenes temporales
Fecha: 2025-01-08 Estado: Aceptado
Contexto: Necesitabamos un motor OCR para el sistema. Las opciones consideradas fueron:
- Tesseract-OCR (Google)
- PaddleOCR (Baidu)
- EasyOCR
Decision: Elegimos Tesseract-OCR como motor principal.
Razones:
- Madurez: Tesseract tiene 15+ años de desarrollo y es industry standard
- Instalacion: Facil instalacion via apt-get en Docker
- Tamano: Imagen Docker mas ligera (~200MB vs ~1.5GB con PaddleOCR)
- Mantenimiento: Soporte activo de Google
- Idioma español: Excelente soporte con
tesseract-ocr-spa - Documentacion: Extensa documentacion y comunidad
Consecuencias:
- ✅ Startup rapido del contenedor
- ✅ Menor consumo de recursos
- ✅ Mejor compatibilidad con CI/CD
⚠️ Precision ligeramente menor que PaddleOCR para tablas complejas- 📝 Posible migracion futura a PaddleOCR para casos avanzados
Alternativas Consideradas:
- PaddleOCR: Mejor para tablas, pero imagen Docker muy pesada
- EasyOCR: Buen balance, pero menos maduro
Fecha: 2025-01-08 Estado: Aceptado
Contexto: Necesitabamos una interfaz web para el sistema OCR. Opciones:
- Streamlit
- FastAPI + React
- Flask + Vanilla JS
- Gradio
Decision: Elegimos Streamlit para la interfaz web.
Razones:
- Velocidad de desarrollo: UI compleja en <300 lineas de codigo
- Python puro: Sin JavaScript, HTML o CSS
- Hot reload: Desarrollo iterativo rapido
- Widgets built-in: File upload, downloads, progress bars
- Caching:
@st.cache_dataoptimiza performance - Deployment: Facil deploy con Docker
Consecuencias:
- ✅ Prototipado rapido (MVP en 2 horas)
- ✅ Mantenimiento simple (un solo lenguaje)
- ✅ UX moderna sin esfuerzo frontend
⚠️ Limitado para aplicaciones muy complejas⚠️ Menos control sobre CSS/HTML
Alternativas Consideradas:
- FastAPI + React: Mayor flexibilidad, pero 3x mas codigo
- Gradio: Similar a Streamlit, pero menos features
Fecha: 2025-01-08 Estado: Aceptado
Contexto: Decidir estrategia de deployment y desarrollo local.
Decision: Arquitectura 100% dockerizada sin instalacion local requerida.
Razones:
- Reproducibilidad: Mismo entorno en dev/staging/prod
- Dependencias: Tesseract requiere instalacion nativa compleja
- Onboarding: Desarrolladores nuevos productivos en 5 minutos
- CI/CD: Pipeline de deployment simplificado
- Multi-plataforma: Funciona igual en macOS/Linux/Windows
Consecuencias:
- ✅ Zero setup para nuevos desarrolladores
- ✅ No hay "works on my machine"
- ✅ Rollback instantaneo con
docker-compose down ⚠️ Debugging ligeramente mas complejo⚠️ Requiere Docker Desktop instalado
Implementacion:
volumes:
- ./src:/app/src # Hot reload codigo
- ./outputs:/app/outputs # Persistencia resultados
- ./uploads:/app/uploads # Archivos temporalesFecha: 2025-01-08 Estado: Aceptado
Contexto: Diseñar API del motor OCR: metodos estaticos vs instancia de clase.
Decision:
Usar metodos estaticos (@staticmethod) en clase OCREngine.
Razones:
- Stateless: OCR no requiere estado interno
- Simplicidad: No necesita
__init__ni manejo de instancias - Caching:
@st.cache_datafunciona mejor con funciones stateless - Testing: Tests mas simples sin setup de instancias
- API limpia:
OCREngine.extract_text()mas claro queengine.extract_text()
Consecuencias:
- ✅ API simple y directa
- ✅ No hay overhead de instanciacion
- ✅ Thread-safe por diseño
⚠️ Dificil agregar estado si se requiere en futuro⚠️ No se puede usar herencia facilmente
Ejemplo:
# Simple y directo
result = OCREngine.extract_text_and_boxes("image.jpg")
# vs alternativa con instancia
engine = OCREngine(config)
result = engine.extract_text_and_boxes("image.jpg")Fecha: 2025-01-08 Estado: Aceptado
Contexto: Definir estandares de calidad de codigo Python.
Decision: Todos los metodos publicos deben tener type hints completos.
Razones:
- Documentacion: Type hints son documentacion ejecutable
- IDE Support: Autocompletado y deteccion de errores
- Refactoring: Mayor seguridad al refactorizar codigo
- Mypy: Verificacion estatica de tipos
- Clean Code: Contratos explicitos entre funciones
Consecuencias:
- ✅ Menos bugs por errores de tipo
- ✅ Mejor developer experience en IDE
- ✅ Codigo auto-documentado
⚠️ Leve overhead al escribir codigo inicial- 📝 Requiere mypy en pre-commit hooks
Ejemplo:
def extract_text_and_boxes(image_path: str) -> Dict[str, Any]:
"""Type hints obligatorios."""
passFecha: 2025-01-08 Estado: Aceptado
Contexto: Elegir framework de testing para TDD.
Decision: Usar pytest con fixtures y clases de test organizadas.
Razones:
- Fixtures: Sistema de fixtures potente y reutilizable
- Assertions: Syntax simple con
assert - Parametrization:
@pytest.mark.parametrizepara test cases multiples - Plugins: Ecosistema extenso (pytest-cov, pytest-xdist)
- Discovery: Encuentra tests automaticamente
Consecuencias:
- ✅ Tests legibles y mantenibles
- ✅ Fixtures compartidos en
conftest.py - ✅ Coverage reports automaticos
- ✅ Parallelization con pytest-xdist
Estructura:
class TestOCREngineExtraction:
"""Organizar tests por funcionalidad."""
def test_extract_text_returns_dict(self, sample_image):
"""Test individual con fixture."""
pass| ADR | Decision | Impacto | Estado |
|---|---|---|---|
| ADR-001 | Tesseract-OCR | Performance, Size | ✅ Aceptado |
| ADR-002 | Streamlit UI | Developer Velocity | ✅ Aceptado |
| ADR-003 | Docker-First | Deployment, Consistency | ✅ Aceptado |
| ADR-004 | Static Methods | API Simplicity | ✅ Aceptado |
| ADR-005 | Type Hints | Code Quality | ✅ Aceptado |
| ADR-006 | Pytest | Testing Strategy | ✅ Aceptado |
volumes:
- ./outputs:/app/outputs # Resultados persistentes
- ./uploads:/app/uploads # Archivos temporales
- ./src:/app/src # Hot reload códigoLos resultados OCR se guardan en ./outputs/ y persisten tras detener el contenedor.
environment:
- PYTHONUNBUFFERED=1 # Logs en tiempo real
- PYTHONPATH=/app/src # Import pathHEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl --fail http://localhost:8501/_stcore/health || exit 1Beneficios:
- Docker detecta automaticamente si el contenedor esta saludable
- Reinicio automatico si el servicio falla
- Integracion con orchestrators (Docker Swarm, Kubernetes)
# docker-compose.yml para multiples instancias
services:
ocr-app:
deploy:
replicas: 3
resources:
limits:
cpus: '2'
memory: 2G┌─────────┐
│ Nginx │ Load Balancer
└────┬────┘
│
├─────────┬─────────┬─────────┐
│ │ │ │
┌────▼───┐ ┌──▼────┐ ┌──▼────┐ ┌──▼────┐
│ OCR-1 │ │ OCR-2 │ │ OCR-3 │ │ OCR-4 │
└────────┘ └───────┘ └───────┘ └───────┘
@st.cache_data
def configure_tesseract() -> None:
"""Configuration cached across reruns."""
pass- Procesamiento paralelo de multiples imagenes
- Progress bar para feedback del usuario
- Error handling individual por archivo
try:
result = OCREngine.extract_text_and_boxes(temp_path)
finally:
# Cleanup temporal files
if os.path.exists(temp_path):
os.remove(temp_path)# Solo formatos permitidos
type=["jpg", "jpeg", "png", "webp", "pdf"]- Archivos temporales con nombres unicos
- Cleanup automatico despues de procesamiento
- Directorio
uploads/ignorado por git
.enven.gitignore- No hardcoded secrets
- Environment variables para configuracion sensible
- Contenedor aislado del sistema host
- Solo puertos necesarios expuestos (8501)
- Usuario non-root (future improvement)
# Logs en tiempo real
docker-compose logs -f ocr-app
# Filtrar por nivel
docker-compose logs ocr-app | grep ERROR- Tiempo promedio de procesamiento
- Tasa de errores
- Uso de memoria y CPU
- Numero de imagenes procesadas
# Verificar salud del contenedor
docker inspect ocr-mvp-streamlit | grep -A 5 Health
# Verificar endpoint de salud
curl http://localhost:8501/_stcore/health| Documento | Descripcion | Enlace |
|---|---|---|
| Architecture | Arquitectura del sistema, diagramas, capas | docs/ARCHITECTURE.md |
| Clean Code Guide | Principios Clean Code aplicados | docs/CLEAN_CODE_GUIDE.md |
| macOS Setup | Instalacion local sin Docker | docs/MACOS_SETUP.md |
| ADRs | Architecture Decision Records | Ver seccion ADRs |
Lectura recomendada:
- Nuevos desarrolladores: Empezar con ARCHITECTURE.md para entender el sistema
- Antes de commit: Revisar CLEAN_CODE_GUIDE.md
- Decisiones de diseño: Consultar ADRs
- Setup local: Si necesitas debugging sin Docker, ver MACOS_SETUP.md
- System Overview y diagramas
- Capas arquitectonicas (Presentation, Business Logic, Infrastructure)
- Data Flow y Component Diagram
- Sequence Diagrams
- Design Patterns aplicados
- SOLID Principles detallados
- Testing Strategy
- Security Architecture
- Performance Considerations
- Deployment Architecture
- Extensibility Points
- Naming Conventions completas
- Function Best Practices
- Class Design Guidelines
- Comments y Documentation
- Error Handling Patterns
- Type Hints completos
- Code Organization
- DRY, YAGNI, KISS principles
- Linting y Formatting tools
- Pre-commit hooks setup
# Cambiar puerto en docker-compose.yml
ports:
- "8502:8501" # Usa 8502 en host# Ver logs detallados
docker-compose logs ocr-app
# Limpiar y reconstruir
docker-compose down
docker system prune -a
docker-compose up --build# Verificar permisos
ls -la outputs/
chmod 777 outputs/ uploads/# Reconstruir sin caché
docker-compose build --no-cache# Verificar instalacion en contenedor
docker-compose exec ocr-app tesseract --list-langs
# Deberia incluir 'spa'# Aumentar limites en docker-compose.yml
deploy:
resources:
limits:
memory: 4G- Agregar soporte para TIFF y BMP
- Implementar API REST con FastAPI
- Dashboard de metricas y estadisticas
- Soporte multi-idioma en UI (i18n)
- Procesamiento asíncrono con Celery
- Base de datos para historial (PostgreSQL)
- Autenticacion y autorizacion de usuarios
- CI/CD pipeline con GitHub Actions
- Pre-commit hooks con black, ruff, mypy
- Modelo OCR custom entrenado con datos propios
- Kubernetes deployment
- Microservicios architecture
- Machine learning para post-procesamiento
- Mobile app (React Native)
- Fork el repositorio
- Crear feature branch (
git checkout -b feature/AmazingFeature) - Escribir tests para nueva funcionalidad
- Implementar feature siguiendo SOLID y Clean Code
- Ejecutar tests (
make test) - Commit con mensaje descriptivo (Conventional Commits)
- Push a branch (
git push origin feature/AmazingFeature) - Abrir Pull Request
feat(scope): add new feature
fix(scope): fix bug
docs: update documentation
test: add tests
refactor: refactor code
- Black para formateo
- Ruff para linting
- Type hints obligatorios
- Docstrings en formato Google
Este proyecto esta bajo la Licencia MIT. Ver LICENSE para mas detalles.
Desarrollo local sin Docker: Para casos especiales (testing, debugging), ver docs/MACOS_SETUP.md
Para preguntas, bugs o sugerencias:
- Abrir un Issue en GitHub
- Revisar documentacion en
docs/ - Consultar ADRs para entender decisiones de diseño
Made with ❤️ using Clean Architecture, SOLID Principles, and Test-Driven Development