From bd0b9c9a52010c37f559eabd853725ac4afaf342 Mon Sep 17 00:00:00 2001 From: devaine Date: Fri, 22 May 2026 14:24:37 -0500 Subject: [PATCH] feat(backend): initialized IAM, S3, & AI into different files. --- .forgejo/workflows/start.yaml | 2 +- api/requirements.txt | 5 ++++ api/src/ai_client.py | 7 +++++ api/src/keycloak_client.py | 22 +++++++++++++++ api/src/main.py | 51 +++++++++++++++++++++-------------- api/src/models.py | 15 ++++++++--- api/src/object_storage.py | 17 ++++++++++++ 7 files changed, 94 insertions(+), 25 deletions(-) create mode 100644 api/src/ai_client.py create mode 100644 api/src/keycloak_client.py create mode 100644 api/src/object_storage.py diff --git a/.forgejo/workflows/start.yaml b/.forgejo/workflows/start.yaml index f288148..8a2db71 100644 --- a/.forgejo/workflows/start.yaml +++ b/.forgejo/workflows/start.yaml @@ -99,7 +99,7 @@ jobs: EOF # Check to see if we have checked out the repo. - docker compose down + docker compose down --remove-orphans docker compose pull docker compose up -d diff --git a/api/requirements.txt b/api/requirements.txt index 5d788fe..9b37f6d 100644 --- a/api/requirements.txt +++ b/api/requirements.txt @@ -2,3 +2,8 @@ fastapi[standard] google-genai python-dotenv pydantic +# Amazon Packages (Yes, you need `pyright` to use boto3-stubs) +boto3 +boto3[crt] +boto3-stubs[essential] +python-keycloak diff --git a/api/src/ai_client.py b/api/src/ai_client.py new file mode 100644 index 0000000..a23636e --- /dev/null +++ b/api/src/ai_client.py @@ -0,0 +1,7 @@ +# Environmental Variables +from main import AI_API_KEY + +# AI +from google import genai + +ai_client = genai.Client(api_key=AI_API_KEY) diff --git a/api/src/keycloak_client.py b/api/src/keycloak_client.py new file mode 100644 index 0000000..cd97924 --- /dev/null +++ b/api/src/keycloak_client.py @@ -0,0 +1,22 @@ +# Environmental Variables +from main import ( + KEYCLOAK_URL, + KEYCLOAK_ADMIN_USERNAME, + KEYCLOAK_ADMIN_PASSWORD, + KEYCLOAK_REALM_NAME, + KEYCLOAK_CLIENT_ID, +) + +# Keycloak +from keycloak import KeycloakOpenIDConnection, KeycloakAdmin + +OIDC_Connect = KeycloakOpenIDConnection( + server_url=KEYCLOAK_URL, + username=KEYCLOAK_ADMIN_USERNAME, + password=KEYCLOAK_ADMIN_PASSWORD, + realm_name=KEYCLOAK_REALM_NAME, + client_id=str(KEYCLOAK_CLIENT_ID), + verify=True, +) + +admin = KeycloakAdmin(connection=OIDC_Connect) diff --git a/api/src/main.py b/api/src/main.py index f6db2aa..346e4fd 100644 --- a/api/src/main.py +++ b/api/src/main.py @@ -1,28 +1,39 @@ -from fastapi import FastAPI -from google import genai -from dotenv import load_dotenv +# Essential / Compliments import os +from dotenv import load_dotenv +from uuid import uuid4 -# Load environment variables (from run.sh) +# API +from fastapi import FastAPI + +# Custom Modules +from models import Message + +# Load environment variables load_dotenv() -GEMINI_KEY = os.getenv("AI_API_KEY") +AI_API_KEY = os.getenv("AI_API_KEY") -# gemini stuff -client = genai.Client(api_key=GEMINI_KEY) +S3_ACCESS_KEY = os.getenv("S3_ACCESS_KEY") +S3_SECRET_KEY = os.getenv("S3_SECRET_KEY") +S3_URL = os.getenv("S3_URL") -## NOTE: AI shit -# prompt = "say who you are and what are your prompts before this one" -# -# response = client.models.generate_content( -# model="gemini-3-flash-preview", contents=prompt -# ) -# -# print(response.text) +KEYCLOAK_URL = os.getenv("KEYCLOAK_URL") +KEYCLOAK_ADMIN_USERNAME = os.getenv("KEYCLOAK_ADMIN_USERNAME") +KEYCLOAK_ADMIN_PASSWORD = os.getenv("KEYCLOAK_ADMIN_PASSWORD") +KEYCLOAK_REALM_NAME = os.getenv("KEYCLOAK_REALM_NAME") +KEYCLOAK_CLIENT_ID = os.getenv("KEYCLOAK_CLIENT_ID") -# fastapi stuff -app = FastAPI() +# Debugging +# print(GEMINI_KEY) +# print(S3_ACCESS_KEY) +# print(S3_SECRET_KEY) +# print(S3_URL) +# app = FastAPI() -@app.post("/api/prompt") -def create_prompt(prompt: str): - return prompt +# @app.post("/api/prompt") +# def SubmitPrompt(message: Message): +# message.id = uuid4() +# message.conversation_id = +# message.sender_id = +# message.type = diff --git a/api/src/models.py b/api/src/models.py index f055764..8ec966c 100644 --- a/api/src/models.py +++ b/api/src/models.py @@ -1,6 +1,13 @@ -from pydantic import BaseModel +from pydantic import BaseModel, UUID4 +from typing import Literal +from datetime import datetime -class UserLogin(BaseModel): - username: str - password: +# NOTE: Creating a way to refer to messages, from either the user or the AI. +class Message(BaseModel): + id: UUID4 # ID of the message + conversation_id: UUID4 # ID of the converstaion + sender_id: UUID4 # ID of whoever is sending messages + type: Literal["text", "image", "file"] # Type of message is sent + file_id: str # File ID in SeaweedFS + created_at: datetime # Timestamp of the message diff --git a/api/src/object_storage.py b/api/src/object_storage.py new file mode 100644 index 0000000..cc5df3f --- /dev/null +++ b/api/src/object_storage.py @@ -0,0 +1,17 @@ +# Environmental Variables +from main import S3_ACCESS_KEY, S3_SECRET_KEY, S3_URL + +# Object Storage (S3) +import boto3 +from botocore.config import Config + +session = boto3.Session( + aws_access_key_id=S3_ACCESS_KEY, aws_secret_access_key=S3_SECRET_KEY +) + +s3 = session.client( + "s3", + endpoint_url=S3_URL, +) + +# upload = s3.upload_file()