kevinkal commited on
Commit
7cf90e0
·
verified ·
1 Parent(s): 59699e2

Update router with mistral endpoint

Browse files
Files changed (1) hide show
  1. routers/powerpoint.py +80 -2
routers/powerpoint.py CHANGED
@@ -4,6 +4,7 @@ from pydantic import BaseModel
4
  from typing import Annotated, List, Literal, Optional, Union, Dict
5
  from google import genai
6
  from google.genai import types
 
7
  from auth import verify_token
8
  import os
9
  import tempfile
@@ -20,6 +21,7 @@ from collections import deque
20
  from threading import Lock
21
  import json
22
  from abc import ABC, abstractmethod
 
23
 
24
  router = APIRouter(prefix="/powerpoint", tags=["powerpoint"])
25
 
@@ -27,6 +29,10 @@ router = APIRouter(prefix="/powerpoint", tags=["powerpoint"])
27
  gemini_key = os.environ.get('GEMINI_KEY', '')
28
  client = genai.Client(api_key=gemini_key)
29
 
 
 
 
 
30
  class APIResponse(BaseModel):
31
  success: bool
32
  data: Optional[Union[Dict, List[Dict], str]] = None
@@ -42,8 +48,10 @@ class MultimodalModel(str, Enum):
42
  gemini_20_flash = "gemini-2.0-flash"
43
  gemini_20_flash_lite = "gemini-2.0-flash-lite"
44
  gemini_25_pro = "gemini-2.5-pro"
45
- gemma_3_4b = "gemma-3-4b-it"
46
- gemma_3_12b = "gemma-3-12b-it"
 
 
47
 
48
  class TemplateType(str, Enum):
49
  single_graph = "single_graph"
@@ -554,6 +562,76 @@ async def image_to_pptx(
554
  except Exception as e:
555
  return APIResponse(success=False, error=f"Failed to generate presentation: {str(e)}")
556
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
  @router.get("/templates")
558
  async def get_available_templates(token: Annotated[str, Depends(verify_token)]):
559
  """Get list of available presentation templates"""
 
4
  from typing import Annotated, List, Literal, Optional, Union, Dict
5
  from google import genai
6
  from google.genai import types
7
+ from mistralai import Mistral
8
  from auth import verify_token
9
  import os
10
  import tempfile
 
21
  from threading import Lock
22
  import json
23
  from abc import ABC, abstractmethod
24
+ import base64
25
 
26
  router = APIRouter(prefix="/powerpoint", tags=["powerpoint"])
27
 
 
29
  gemini_key = os.environ.get('GEMINI_KEY', '')
30
  client = genai.Client(api_key=gemini_key)
31
 
32
+ # Get Mistral client
33
+ mistral_key = os.environ.get('MISTRAL_KEY', '')
34
+ mistral_client = Mistral(api_key=mistral_key)
35
+
36
  class APIResponse(BaseModel):
37
  success: bool
38
  data: Optional[Union[Dict, List[Dict], str]] = None
 
48
  gemini_20_flash = "gemini-2.0-flash"
49
  gemini_20_flash_lite = "gemini-2.0-flash-lite"
50
  gemini_25_pro = "gemini-2.5-pro"
51
+
52
+ class MistralModel(str, Enum):
53
+ mistral_small_latest = "mistral-small-latest"
54
+ mistral_medium_latest = "mistral-medium-latest"
55
 
56
  class TemplateType(str, Enum):
57
  single_graph = "single_graph"
 
562
  except Exception as e:
563
  return APIResponse(success=False, error=f"Failed to generate presentation: {str(e)}")
564
 
565
+ @router.post("/mistral-image-to-pptx")
566
+ async def mistral_image_to_pptx(
567
+ token: Annotated[str, Depends(verify_token)],
568
+ file: UploadFile = File(..., description="Image file to convert to PowerPoint"),
569
+ template: TemplateType = Form(..., description="Template type to use for the presentation"),
570
+ model: MistralModel = Form(..., description="Mistral model (mistral-small-latest or mistral-medium-latest)"),
571
+ ):
572
+ """
573
+ Analyze an image with Mistral AI and generate a PowerPoint presentation based on the analysis using the selected template
574
+ """
575
+ try:
576
+ # Get template generator
577
+ template_generator = TEMPLATE_GENERATORS.get(template)
578
+ if not template_generator:
579
+ raise HTTPException(status_code=400, detail=f"Unsupported template: {template}")
580
+
581
+ # Read uploaded file
582
+ file_content = await file.read()
583
+
584
+ # Convert image to base64 for Mistral
585
+ image_base64 = base64.b64encode(file_content).decode('utf-8')
586
+ image_url = f"data:{file.content_type};base64,{image_base64}"
587
+
588
+ # Prepare messages for Mistral
589
+ messages = [
590
+ {
591
+ "role": "user",
592
+ "content": [
593
+ {
594
+ "type": "text",
595
+ "text": template_generator.get_prompt()
596
+ },
597
+ {
598
+ "type": "image_url",
599
+ "image_url": image_url
600
+ }
601
+ ]
602
+ }
603
+ ]
604
+
605
+ # Send to Mistral
606
+ response = mistral_client.chat.complete(
607
+ model=model.value,
608
+ messages=messages,
609
+ response_format=template_generator.get_response_schema()
610
+ )
611
+
612
+ # Display usage information
613
+ if hasattr(response, 'usage'):
614
+ print(f"Mistral usage: {response.usage}")
615
+
616
+ # Parse the response
617
+ response_text = response.choices[0].message.content
618
+ presentation_data = template_generator.get_response_schema().model_validate(json.loads(response_text))
619
+
620
+ # Generate PPTX file
621
+ pptx_path = template_generator.generate_pptx(presentation_data)
622
+
623
+ # Return file as download
624
+ return FileResponse(
625
+ path=pptx_path,
626
+ filename=f"mistral_presentation_{template.value}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pptx",
627
+ media_type="application/vnd.openxmlformats-officedocument.presentationml.presentation"
628
+ )
629
+
630
+ except HTTPException:
631
+ raise
632
+ except Exception as e:
633
+ return APIResponse(success=False, error=f"Failed to generate presentation with Mistral: {str(e)}")
634
+
635
  @router.get("/templates")
636
  async def get_available_templates(token: Annotated[str, Depends(verify_token)]):
637
  """Get list of available presentation templates"""