Skip to content

Commit

Permalink
[MRG] Merged the backend and ai code for generate answer
Browse files Browse the repository at this point in the history
  • Loading branch information
pathfindermilan committed Nov 4, 2024
1 parent 05b0956 commit 4a84a9f
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 20 deletions.
20 changes: 11 additions & 9 deletions ai/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@

app = FastAPI()

class UserData(BaseModel):
name: str
age: int
image_summary: str
document_summary: str
user_transcript: str
content_type: str
feeling_level: str

class TextAnalysisRequest(BaseModel):
text: str

Expand Down Expand Up @@ -59,16 +68,9 @@ async def analyze_pdf_summary(document: UploadFile = File(...)):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))


@app.post("/generate-answer")
async def analyze_user_data(
name: str,
age: int,
image_summary: str,
document_summary: str,
user_transcript: str,
content_type: str,
feeling_level: str,
):
async def analyze_user_data(data: UserData):
"""
Analyzes user data to generate a motivational AI response based on the user's inputs.
Expand Down
18 changes: 9 additions & 9 deletions backend/cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,20 @@ func main() {
jwtService := auth.NewJWTService(cfg.JWTSecret)
authService := services.NewAuthService(userRepo, jwtService)
syncDescriptionService := services.NewSyncDescriptionService(syncDescriptionRepo)
syncService := services.NewSyncService(syncRepo, syncDescriptionService, &cfg)
syncService := services.NewSyncService(userRepo, syncRepo, syncDescriptionService, &cfg)

router := gin.Default()

corsConfig := cors.Config{
AllowOrigins: []string{"https://restio.xyz"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}
AllowOrigins: []string{"https://restio.xyz"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}

router.Use(cors.New(corsConfig))
router.Use(cors.New(corsConfig))

// router.Static("/uploads/images", "./uploads/images")
// router.Static("/uploads/documents", "./uploads/documents")
Expand Down
6 changes: 6 additions & 0 deletions backend/internal/controllers/sync_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ func (ctrl *SyncController) SyncData(c *gin.Context) {
return
}

err = ctrl.syncService.ResetAIResponse(userID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to reset AI response"})
return
}

ctrl.syncService.ProcessDescriptions(userID, newImageUploaded, newDocumentUploaded)

c.JSON(http.StatusOK, gin.H{"message": "Data synced successfully"})
Expand Down
2 changes: 2 additions & 0 deletions backend/internal/models/sync_description.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ type SyncDescription struct {
DocumentURL string
DocumentSummary string
DocumentStatus SyncStatus
AiStatus SyncStatus
AiSummary string
}
129 changes: 127 additions & 2 deletions backend/internal/services/sync_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import (
"backend/internal/repositories"
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"strconv"
"sync"

"fmt"

"github.com/jinzhu/gorm"
)

Expand All @@ -25,21 +26,26 @@ type SyncService interface {
GetSyncData(userID uint) (*models.SyncData, error)
ProcessDescriptions(userID uint, processImage bool, processDocument bool)
DeleteSyncDescription(userID uint) error
ResetAIResponse(userID uint) error
GenerateAnswer(userID string) (string, models.SyncStatus)
}

type syncService struct {
userRepo repositories.UserRepository
syncRepo repositories.SyncRepository
syncDescriptionService SyncDescriptionService
config *config.Config
mu sync.Mutex
}

func NewSyncService(
userRepo repositories.UserRepository,
syncRepo repositories.SyncRepository,
syncDescriptionService SyncDescriptionService,
config *config.Config,
) SyncService {
return &syncService{
userRepo: userRepo,
syncRepo: syncRepo,
syncDescriptionService: syncDescriptionService,
config: config,
Expand All @@ -66,6 +72,39 @@ func (s *syncService) DeleteSyncDescription(userID uint) error {
return s.syncDescriptionService.DeleteSyncDescription(userID)
}

func (s *syncService) ResetAIResponse(userID uint) error {
s.mu.Lock()
defer s.mu.Unlock()

syncDesc, err := s.syncDescriptionService.GetSyncDescriptionByUserID(userID)
if err != nil && !gorm.IsRecordNotFoundError(err) {
return err
}

if syncDesc == nil {
syncDesc = &models.SyncDescription{
UserID: userID,
AiSummary: "",
AiStatus: models.StatusInProgress,
SyncDataID: 0, // Assuming 0 or appropriate value
}
return s.syncDescriptionService.CreateOrUpdateSyncDescription(syncDesc)
}

updated := false
if syncDesc.AiSummary != "" || syncDesc.AiStatus != models.StatusInProgress {
syncDesc.AiSummary = ""
syncDesc.AiStatus = models.StatusInProgress
updated = true
}

if updated {
return s.syncDescriptionService.CreateOrUpdateSyncDescription(syncDesc)
}

return nil
}

func (s *syncService) ProcessDescriptions(userID uint, newImageUploaded bool, newDocumentUploaded bool) {
s.mu.Lock()
defer s.mu.Unlock()
Expand Down Expand Up @@ -147,6 +186,15 @@ func (s *syncService) ProcessDescriptions(userID uint, newImageUploaded bool, ne
if newDocumentUploaded && syncDescription.DocumentStatus == models.StatusInProgress {
go s.processDocumentAndUpdateDescription(userID, syncData.DocumentURL)
}

go func(uid uint) {
answer, status := s.GenerateAnswer(strconv.Itoa(int(uid)))
if status != models.StatusDone {
fmt.Printf("Failed to generate answer for user %d\n", uid)
return
}
fmt.Printf("Generated answer for user %d: %s\n", uid, answer)
}(userID)
}

func (s *syncService) processImageAndUpdateDescription(userID uint, imageURL string) {
Expand Down Expand Up @@ -272,3 +320,80 @@ func (s *syncService) processDocument(documentPath string) (string, models.SyncS

return respData.DocumentSummary, models.StatusDone
}

func (s *syncService) GenerateAnswer(user_id string) (string, models.SyncStatus) {
uid, err := strconv.Atoi(user_id)
if err != nil {
return "", models.StatusErrored
}
userID := uint(uid)

syncData, err := s.GetSyncData(userID)
if err != nil {
return "", models.StatusErrored
}

syncDesc, err := s.syncDescriptionService.GetSyncDescriptionByUserID(userID)
if err != nil {
return "", models.StatusErrored
}

user, err := s.userRepo.GetUserByID(userID)
name := user.Name

payload := map[string]interface{}{
"name": name,
"age": syncData.Age,
"image_summary": syncDesc.ImageSummary,
"document_summary": syncDesc.DocumentSummary,
"user_transcript": syncData.QueryText,
"content_type": syncData.ContentType,
"feeling_level": syncData.FeelingLevel,
}

payloadBytes, err := json.Marshal(payload)
if err != nil {
return "", models.StatusErrored
}

req, err := http.NewRequest("POST", "https://restio.xyz/generate-answer", bytes.NewBuffer(payloadBytes))
if err != nil {
return "", models.StatusErrored
}
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", models.StatusErrored
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", models.StatusErrored
}

if resp.StatusCode != http.StatusOK {
fmt.Printf("FastAPI responded with status: %d, body: %s\n", resp.StatusCode, string(body))
return "", models.StatusErrored
}

var responseData struct {
AI_Summary string `json:"ai_summary"`
}
err = json.Unmarshal(body, &responseData)
if err != nil {
return "", models.StatusErrored
}

syncDesc.AiSummary = responseData.AI_Summary
syncDesc.AiStatus = models.StatusDone

err = s.syncDescriptionService.CreateOrUpdateSyncDescription(syncDesc)
if err != nil {
return "", models.StatusErrored
}

return syncDesc.AiSummary, models.StatusDone
}

0 comments on commit 4a84a9f

Please sign in to comment.