diff --git a/backend/ai-service/.gitignore b/backend/ai-service/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/backend/ai-service/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/backend/ai-service/__init__.py b/backend/ai-service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/ai-service/main.py b/backend/ai-service/main.py new file mode 100644 index 0000000..08e56d0 --- /dev/null +++ b/backend/ai-service/main.py @@ -0,0 +1,32 @@ +from fastapi import FastAPI + +from .models.models import SearchData +from .processing.processing import process + +app = FastAPI() + + +@app.get("/") +async def root(): + return {"message": "Hello from Trustify AI service!"} + + +@app.get("/health") +async def check_health(): + return {"message": "healthy"} + + +@app.post("/search") +async def search(payload: SearchData): + logging.info(payload) + result = process(payload) + + if result == None: + return {"message": "ai-service-error"} + + return { + "message": "Success", + "result": result.result, + "score": result.score, + "sources": result.sources, + } diff --git a/backend/ai-service/models/__init__.py b/backend/ai-service/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/ai-service/models/models.py b/backend/ai-service/models/models.py new file mode 100644 index 0000000..f326c4e --- /dev/null +++ b/backend/ai-service/models/models.py @@ -0,0 +1,19 @@ +from typing import List + +from pydantic import BaseModel + + +class Source(BaseModel): + url: str + + +class SearchData(BaseModel): + headline: str + content: str | None + url: str | None + + +class SearchResponse(BaseModel): + result: str + score: int + sources: List[Source] diff --git a/backend/ai-service/processing/__init__.py b/backend/ai-service/processing/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/ai-service/processing/processing.py b/backend/ai-service/processing/processing.py new file mode 100644 index 0000000..2b5911e --- /dev/null +++ b/backend/ai-service/processing/processing.py @@ -0,0 +1,12 @@ +from ..models.models import SearchData, SearchResponse, Source + + +def process(data: SearchData | None) -> SearchResponse | None: + if data == None: + return None + + response = SearchResponse( + result="Fake", score=78, sources=[Source(url="http://example_source.com")] + ) + + return response diff --git a/backend/api-service/api/handlers/handlers.go b/backend/api-service/api/handlers/handlers.go index 6723d62..90bf6d8 100644 --- a/backend/api-service/api/handlers/handlers.go +++ b/backend/api-service/api/handlers/handlers.go @@ -24,9 +24,7 @@ func HandleSearch(ctx *gin.Context) { }) } - ctx.JSON(http.StatusOK, gin.H{ - "result": result, - }) + ctx.JSON(http.StatusOK, *result) } func HealthCheck(ctx *gin.Context) { diff --git a/backend/api-service/cmd/trustify/main.go b/backend/api-service/cmd/trustify/main.go index 4a17ac7..bcbf7e9 100644 --- a/backend/api-service/cmd/trustify/main.go +++ b/backend/api-service/cmd/trustify/main.go @@ -14,7 +14,6 @@ import ( ) func main() { - apiServer := server.GetConfig() routes.ServerRoutes(apiServer.Router) @@ -39,5 +38,4 @@ func main() { <-ctx.Done() log.Println("Server down") - } diff --git a/backend/api-service/config/client/client.go b/backend/api-service/config/client/client.go new file mode 100644 index 0000000..ddae683 --- /dev/null +++ b/backend/api-service/config/client/client.go @@ -0,0 +1,27 @@ +package client + +import ( + "time" + + fastshot "github.com/opus-domini/fast-shot" +) + +type ClientConfig struct { + Client fastshot.ClientHttpMethods +} + +var clientConfig *ClientConfig + +func GetClientConfig() *ClientConfig { + if clientConfig != nil { + return clientConfig + } + + clientConfig = &ClientConfig{ + Client: fastshot.NewClient("http://localhost:5000"). + Header().Add("Content-Type", "application/json"). + Config().SetTimeout(15 * time.Second).Build(), + } + + return clientConfig +} diff --git a/backend/api-service/go.mod b/backend/api-service/go.mod index 4d32670..c99e03b 100644 --- a/backend/api-service/go.mod +++ b/backend/api-service/go.mod @@ -20,6 +20,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/opus-domini/fast-shot v1.1.4 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect diff --git a/backend/api-service/go.sum b/backend/api-service/go.sum index b7eda8b..e456f0c 100644 --- a/backend/api-service/go.sum +++ b/backend/api-service/go.sum @@ -43,6 +43,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/opus-domini/fast-shot v1.1.4 h1:xWTO/4JEILjZM/rP6mwiWe/jZyE9+L1G9sC4BsoynAk= +github.com/opus-domini/fast-shot v1.1.4/go.mod h1:BOr2JXHQJhOnYsxyCvFbgBP3BuYCjgh2YfzWKweEL0A= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/backend/api-service/internal/services/analysis.go b/backend/api-service/internal/services/analysis.go index 0796691..be8b133 100644 --- a/backend/api-service/internal/services/analysis.go +++ b/backend/api-service/internal/services/analysis.go @@ -1,17 +1,31 @@ package services import ( + "fmt" + "github.com/MarcinZ20/Trustify/backend/api-service/api/models" + "github.com/MarcinZ20/Trustify/backend/api-service/config/client" ) -func PerformTextAnalysis(header string, content string, url string) (models.ResponseData, error) { - responseData := models.ResponseData{ - Score: 78, - Resutl: "True", - Sources: []models.Source{ - {Url: "http://example.com"}, {Url: "https://something.com"}, - }, +func PerformTextAnalysis(header string, content string, url string) (*models.ResponseData, error) { + apiClient := client.GetClientConfig() + + var respData models.ResponseData + + payload := map[string]string{ + "headline": header, + "content": content, + "url": url, + } + + response, err := apiClient.Client.POST("/search").Body().AsJSON(payload).Send() + if err != nil { + return &respData, fmt.Errorf("bad request: %s", err) + } + + if err := response.Body().AsJSON(&respData); err != nil { + return &respData, fmt.Errorf("parsing error: %s", err) } - return responseData, nil + return &respData, nil }