Im working on this: Features

Document Upload: Users can upload various documents.
Semantic Search: Search documents using AI and Large Language Models (LLMs).
Text Summarization: Get summaries of document content.
User-Friendly Frontend: Intuitive interface built with Svelte.
RESTful API: Backend implemented with FastAPI.
AI Integration: Utilizes LangChain for advanced AI functionalities.
Containerization: Fully containerized using Docker and Docker Compose for seamless deployment.
Database Migrations: Manage database schema changes effortlessly with Alembic.

Technology Stack

Programming Languages: Python (backend), JavaScript (frontend)
Backend: FastAPI
Frontend: Svelte
Database: PostgreSQL
AI Libraries: LangChain
Database Migrations: Alembic
Containerization: Docker, Docker Compose
Version Control: Git
Code Quality: pre-commit
Development Tools: Rollup, sirv-cli

The only thing that doesnt work yet is the showing of summarization.

Here is the overview of the code base: smart-documents
│
├── backend
│ ├── alembic
│ └── app
│ ├── routers
│ │ ├── init.py
│ │ ├── auth.py
│ │ ├── documents.py
│ │ ├── search.py
│ │ ├── summaries.py
│ │ ├── tags.py
│ │ └── users.py
│ ├── init.py
│ ├── ai.py
│ ├── database.py
│ ├── dependencies.py
│ ├── main.py
│ ├── models.py
│ ├── schemas.py
│ └── utils.py
├── tests
├── uploads
├── .dockerignore
├── alembic.ini
├── Dockerfile
└── requirements.txt
frontend
├── public
│ ├── favicon.png
│ ├── global.css
│ └── index.html
├── scripts
│ └── setupTypeScript.js
└── src
├── App.svelte
├── main.js
├── .dockerignore
├── Dockerfile
├── package.json
├── package-lock.json
├── README.md
└── rollup.config.js
{#if loading}

Loading summary...
{/if}

{#if error}
    <p style="color: red;">{error}</p>
{/if}

{#if summary}
    <h2>Document Summary</h2>
    <p>{summary}</p>
{/if}

{#if loading}

Loading summary...
{/if}

{#if error}
    <p style="color: red;">{error}</p>
{/if}

{#if summary}
    <h2>Summary</h2>
    <p>{summary}</p>
{/if}

backend/app/routers/documents.py

import os
from datetime import datetime
from typing import List, Optional

from app.ai import generate_embeddings, generate_summary
from app.database import get_db
from app.dependencies import get_current_user
from app.models import Document, DocumentVersion, SearchIndex, Tag, User
from app.schemas import DocumentResponse, DocumentUpdate
from app.utils import save_file
from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile
from sqlalchemy.orm import Session

router = APIRouter(
prefix="/documents",
tags=["documents"],
)

UPLOAD_DIR = "uploads/documents/"

@router.post("/upload/", response_model=DocumentResponse)
async def upload_document(
title: str = Form(...),
description: Optional[str] = Form(None),
tags: Optional[List[str]] = Form([]),
file: UploadFile = File(...),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
user_id = current_user.id

file_path = save_file(file, UPLOAD_DIR)
document = Document(
    user_id=user_id,
    title=title,
    description=description,
    file_path=file_path,
    uploaded_at=datetime.utcnow(),
)

# Handle tags
for tag_name in tags:
    tag = db.query(Tag).filter(Tag.name == tag_name).first()
    if not tag:
        tag = Tag(name=tag_name)
    document.tags.append(tag)

db.add(document)
db.commit()
db.refresh(document)

# initial DocumentVersion
version = DocumentVersion(
    document_id=document.id,
    version_number=1,
    file_path=file_path,
    uploaded_at=document.uploaded_at,
)
db.add(version)
db.commit()
db.refresh(version)

summary = await generate_summary(file_path)
embeddings = await generate_embeddings(file_path)

# Update Document with summary
document.summary = summary
db.commit()
db.refresh(document)

# Create SearchIndex entry
search_index = SearchIndex(
    document_id=document.id,
    embedding_vector=embeddings,
)
db.add(search_index)
db.commit()
db.refresh(search_index)

return document

@router.get("/", response_model=List[DocumentResponse])
def get_documents(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
documents = db.query(Document).offset(skip).limit(limit).all()
return documents

@router.get("/{document_id}", response_model=DocumentResponse)
def get_document(document_id: int, db: Session = Depends(get_db)):
document = db.query(Document).filter(Document.id == document_id).first()
if not document:
raise HTTPException(status_code=404, detail="Document not found")
return document

@router.put("/{document_id}", response_model=DocumentResponse)
def update_document(
document_id: int, document_update: DocumentUpdate, db: Session = Depends(get_db)
):
document = db.query(Document).filter(Document.id == document_id).first()
if not document:
raise HTTPException(status_code=404, detail="Document not found")

if document_update.title:
    document.title = document_update.title
if document_update.description:
    document.description = document_update.description

if document_update.tags:
    # Clear existing tags
    document.tags = []
    for tag_name in document_update.tags:
        tag = db.query(Tag).filter_by(name=tag_name).first()
        if not tag:
            tag = Tag(name=tag_name)
        document.tags.append(tag)

db.commit()
db.refresh(document)
return document

@router.delete("/{document_id}", response_model=dict)
def delete_document(document_id: int, db: Session = Depends(get_db)):
document = db.query(Document).filter(Document.id == document_id).first()
if not document:
raise HTTPException(status_code=404, detail="Document not found")

# Delete associated files
try:
    os.remove(document.file_path)
    for version in document.versions:
        os.remove(version.file_path)
except Exception as e:
    raise HTTPException(status_code=500, detail=f"Error deleting files: {e}")

db.delete(document)
db.commit()
return {"detail": "Document deleted successfully"}

backend/app/routers/summaries.py

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.database import get_db
from app.models import Document
from app.schemas import SummaryResponse

router = APIRouter(
prefix="/summaries",
tags=["summaries"],
)

@router.get("/{document_id}", response_model=SummaryResponse) # Add this GET method
async def get_summary(document_id: int, db: Session = Depends(get_db)):
document = db.query(Document).filter(Document.id == document_id).first()
if not document:
raise HTTPException(status_code=404, detail="Document not found")

return {"document_id": document.id, "summary": document.summary}

When executing curl -X GET "http://localhost:8000/summaries/14" I get the summary. However when I run http://localhost:5000/summary/14 I only get an empty page. with these errors: Layout-Darstellung wurde erzwungen, bevor die Seite vollständig geladen war. Falls Stylesheet noch nicht geladen sind, kann dies zu einem kurzzeitigen Darstellung des Inhalts ohne Formatierung führen. markup.js:250:53
<App> was created with unknown prop 'name' bundle.js:6249:96
<Summary> was created with unknown prop 'id' bundle.js:6000:98
Uncaught TypeError: params is undefined. It also appears that