89 lines
3.0 KiB
Python
89 lines
3.0 KiB
Python
from fastapi import FastAPI, Request, Form
|
|
from fastapi.responses import HTMLResponse
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.templating import Jinja2Templates
|
|
import re
|
|
from typing import Dict, Optional
|
|
|
|
app = FastAPI(title="Business Model Canvas Parser")
|
|
|
|
# Montar static files y templates
|
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
|
templates = Jinja2Templates(directory="templates")
|
|
|
|
# Mapeo de secciones del BMC
|
|
BMC_SECTIONS = {
|
|
"socios_clave": "Socios Clave",
|
|
"actividades_clave": "Actividades Clave",
|
|
"recursos_clave": "Recursos Clave",
|
|
"propuesta_de_valor": "Propuesta de valor",
|
|
"relacion_con_clientes": "Relación Con Clientes",
|
|
"canales": "Canales",
|
|
"segmentos": "Segmentos",
|
|
"estructura_de_costos": "Estructura de Costos",
|
|
"fuentes_de_ingresos": "Fuentes de Ingresos",
|
|
}
|
|
|
|
|
|
def parse_markdown_to_bmc(markdown_text: str) -> Dict[str, str]:
|
|
"""
|
|
Parsea el markdown y extrae el contenido de cada sección del BMC
|
|
"""
|
|
bmc_data = {key: "" for key in BMC_SECTIONS.keys()}
|
|
|
|
# Patrones para buscar cada sección (case insensitive)
|
|
patterns = {
|
|
"socios_clave": r"##\s*Socios\s*Clave.*?(?=##|$)",
|
|
"actividades_clave": r"##\s*Actividades\s*Clave.*?(?=##|$)",
|
|
"recursos_clave": r"##\s*Recursos\s*Clave.*?(?=##|$)",
|
|
"propuesta_de_valor": r"##\s*Propuesta\s*de\s*valor.*?(?=##|$)",
|
|
"relacion_con_clientes": r"##\s*Relacion\s*Con\s*Clientes.*?(?=##|$)",
|
|
"canales": r"##\s*Canales.*?(?=##|$)",
|
|
"segmentos": r"##\s*Segmentos.*?(?=##|$)",
|
|
"estructura_de_costos": r"##\s*Estructura\s*de\s*Costos.*?(?=##|$)",
|
|
"fuentes_de_ingresos": r"##\s*Fuentes\s*de\s*Ingresos.*?(?=##|$)",
|
|
}
|
|
|
|
for key, pattern in patterns.items():
|
|
match = re.search(pattern, markdown_text, re.IGNORECASE | re.DOTALL)
|
|
if match:
|
|
content = match.group(0)
|
|
# Remover el header y limpiar
|
|
content = re.sub(r"^##.*\n", "", content, flags=re.IGNORECASE)
|
|
# Remover numeración inicial si existe
|
|
content = re.sub(r"^\d+\s*", "", content.strip())
|
|
key2 = key
|
|
bmc_data[key2] = content.strip()
|
|
|
|
return bmc_data
|
|
|
|
|
|
@app.get("/")
|
|
def home(request: Request):
|
|
return templates.TemplateResponse(request=request, name="bmc.html")
|
|
|
|
|
|
@app.post("/render", response_class=HTMLResponse)
|
|
async def render_bmc(request: Request, markdown_text: str = Form()):
|
|
"""Procesa el markdown y renderiza el BMC"""
|
|
bmc_data = parse_markdown_to_bmc(markdown_text)
|
|
|
|
return templates.TemplateResponse(
|
|
request=request,
|
|
name="bmc.html",
|
|
context={"markdown_text": markdown_text, "bmc_data": bmc_data},
|
|
)
|
|
|
|
|
|
@app.post("/api/parse")
|
|
async def api_parse_bmc(markdown_text: str = Form(...)):
|
|
"""API endpoint que retorna JSON con los datos parseados"""
|
|
bmc_data = parse_markdown_to_bmc(markdown_text)
|
|
return {"bmc": bmc_data}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
|
|
uvicorn.run(app, host="0.0.0.0", port=8001)
|