Merge branch 'feat/database_support' into mini_layout_remove

This commit is contained in:
sauravniraula 2025-07-12 18:47:40 +05:45
commit e4cfc70f3d
No known key found for this signature in database
GPG key ID: 60FCC1B5A5E83326
10 changed files with 84 additions and 14 deletions

View file

@ -6,7 +6,10 @@ RUN apt-get update && apt-get install -y \
npm \
nginx \
curl \
redis-server
redis-server \
default-libmysqlclient-dev \
build-essential \
pkg-config
# Create a working directory
WORKDIR /app

View file

@ -6,7 +6,10 @@ RUN apt-get update && apt-get install -y \
npm \
nginx \
curl \
redis-server
redis-server \
default-libmysqlclient-dev \
build-essential \
pkg-config
# Change working directory
WORKDIR /app

View file

@ -20,6 +20,7 @@ services:
- CUSTOM_LLM_API_KEY=${CUSTOM_LLM_API_KEY}
- CUSTOM_MODEL=${CUSTOM_MODEL}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- DATABASE_URL=${DATABASE_URL}
production-gpu:
# image: ghcr.io/presenton/presenton:latest
@ -49,6 +50,7 @@ services:
- CUSTOM_LLM_API_KEY=${CUSTOM_LLM_API_KEY}
- CUSTOM_MODEL=${CUSTOM_MODEL}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- DATABASE_URL=${DATABASE_URL}
development:
build:
@ -72,6 +74,7 @@ services:
- CUSTOM_LLM_API_KEY=${CUSTOM_LLM_API_KEY}
- CUSTOM_MODEL=${CUSTOM_MODEL}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- DATABASE_URL=${DATABASE_URL}
development-gpu:
build:
@ -101,4 +104,5 @@ services:
- CUSTOM_LLM_URL=${CUSTOM_LLM_URL}
- CUSTOM_LLM_API_KEY=${CUSTOM_LLM_API_KEY}
- CUSTOM_MODEL=${CUSTOM_MODEL}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- PEXELS_API_KEY=${PEXELS_API_KEY}
- DATABASE_URL=${DATABASE_URL}

View file

@ -153,6 +153,7 @@ class GeneratePresentationHandler(FetchAssetsOnPresentationGenerationMixin):
print("-" * 40)
print("Exporting Presentation")
export_request_body["presentation_id"] = self.presentation_id
print(export_request_body)
export_request = ExportAsRequest(**export_request_body)
presentation_and_path = await ExportAsPptxHandler(export_request).post(

View file

@ -1,5 +1,6 @@
from sqlmodel import select, exists
from api.models import LogMetadata
from api.routers.presentation.models import PresentationWithOneSlide
from api.services.logging import LoggingService
from api.sql_models import PresentationSqlModel, SlideSqlModel
from api.services.database import get_sql_session
@ -18,8 +19,19 @@ class GetPresentationsHandler:
)
)
).all()
presentations.sort(key=lambda x: x.created_at, reverse=True)
presentations_with_slide = []
for presentation in presentations:
slide = sql_session.exec(
select(SlideSqlModel)
.where(SlideSqlModel.presentation == presentation.id)
.where(SlideSqlModel.index == 0)
).first()
presentations_with_slide.append(
PresentationWithOneSlide.from_presentation_and_slide(
presentation, slide
)
)
logging_service.logger.info(
logging_service.message(
@ -27,4 +39,4 @@ class GetPresentationsHandler:
),
extra=log_metadata.model_dump(),
)
return presentations
return presentations_with_slide

View file

@ -0,0 +1,14 @@
from typing import Optional
from api.services.logging import LoggingService
from api.models import LogMetadata
from api.utils.model_utils import list_available_custom_models
class ListAvailableCustomModelsHandler:
def __init__(self, url: Optional[str] = None, api_key: Optional[str] = None):
self.url = url
self.api_key = api_key
async def get(self, logging_service: LoggingService, log_metadata: LogMetadata):
return await list_available_custom_models(self.url, self.api_key)

View file

@ -177,3 +177,23 @@ class OllamaModelStatusResponse(BaseModel):
class OllamaSupportedModelsResponse(BaseModel):
models: List[OllamaModelMetadata]
class PresentationWithOneSlide(BaseModel):
id: str
created_at: datetime
theme: Optional[dict] = None
title: Optional[str] = None
slide: SlideSqlModel
@classmethod
def from_presentation_and_slide(
cls, presentation: PresentationSqlModel, slide: SlideSqlModel
):
return cls(
id=presentation.id,
created_at=presentation.created_at,
theme=presentation.theme,
title=presentation.title,
slide=slide,
)

View file

@ -1,7 +1,6 @@
from typing import Annotated, List, Optional
import uuid
from fastapi import APIRouter, BackgroundTasks, Body, File, Form, UploadFile
import openai
from api.models import SessionModel
from api.request_utils import RequestUtils
@ -35,6 +34,9 @@ from api.routers.presentation.handlers.generate_outlines import (
)
from api.routers.presentation.handlers.get_presentation import GetPresentationHandler
from api.routers.presentation.handlers.get_presentations import GetPresentationsHandler
from api.routers.presentation.handlers.list_available_custom_models import (
ListAvailableCustomModelsHandler,
)
from api.routers.presentation.handlers.list_ollama_pulled_models import (
ListPulledOllamaModelsHandler,
)
@ -80,13 +82,10 @@ from api.routers.presentation.models import (
SearchImageRequest,
UpdatePresentationThemeRequest,
PresentationUpdateRequest,
PresentationWithOneSlide,
)
from api.sql_models import PresentationSqlModel
from api.utils.model_utils import get_llm_client, list_available_custom_models
from api.utils.utils import handle_errors
from image_processor.images_finder import (
generate_image_google,
)
from ppt_generator.models.slide_model import SlideModel
route_prefix = "/api/v1/ppt"
@ -94,7 +93,7 @@ presentation_router = APIRouter(prefix=route_prefix)
@presentation_router.get(
"/user_presentations", response_model=List[PresentationSqlModel]
"/user_presentations", response_model=List[PresentationWithOneSlide]
)
async def get_user_presentations():
request_utils = RequestUtils(f"{route_prefix}/user_presentations")
@ -398,4 +397,10 @@ async def list_custom_models(
url: Annotated[Optional[str], Body()] = None,
api_key: Annotated[Optional[str], Body()] = None,
):
return await list_available_custom_models(url, api_key)
request_utils = RequestUtils(f"{route_prefix}/models/list/custom")
logging_service, log_metadata = await request_utils.initialize_logger()
return await handle_errors(
ListAvailableCustomModelsHandler(url, api_key).get,
logging_service,
log_metadata,
)

View file

@ -4,8 +4,14 @@ from sqlalchemy import create_engine
from sqlmodel import Session
sql_url = "sqlite:///" + os.path.join(os.getenv("APP_DATA_DIRECTORY"), "fastapi.db")
sql_engine = create_engine(sql_url, connect_args={"check_same_thread": False})
database_url = os.getenv("DATABASE_URL") or "sqlite:///" + os.path.join(
os.getenv("APP_DATA_DIRECTORY"), "fastapi.db"
)
connect_args = {}
if "sqlite" in database_url:
connect_args["check_same_thread"] = False
sql_engine = create_engine(database_url, connect_args=connect_args)
@contextmanager

View file

@ -55,6 +55,7 @@ mmh3==5.1.0
mpmath==1.3.0
multidict==6.4.3
mypy_extensions==1.1.0
mysqlclient==2.2.7
numpy==2.2.5
ollama==0.5.1
onnxruntime==1.22.0
@ -67,6 +68,7 @@ pillow==11.3.0
propcache==0.3.1
proto-plus==1.26.1
protobuf==6.31.1
psycopg2-binary==2.9.10
py_rust_stemmers==0.1.5
pyasn1==0.6.1
pyasn1_modules==0.4.2