-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
329 additions
and
2,072 deletions.
There are no files selected for viewing
Binary file not shown.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1 @@ | ||
dist/ | ||
.env | ||
node_modules/ | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,24 @@ | ||
# Use an official Node.js runtime as the base image | ||
FROM node:18-alpine | ||
# backend/ai-hint-service/Dockerfile | ||
|
||
# Set the working directory | ||
WORKDIR /app | ||
FROM python:3.9-slim | ||
|
||
# Copy package files | ||
COPY package*.json ./ | ||
# Set environment variables | ||
ENV PYTHONDONTWRITEBYTECODE=1 | ||
ENV PYTHONUNBUFFERED=1 | ||
|
||
# Install dependencies | ||
RUN npm install | ||
# Set work directory | ||
WORKDIR /app | ||
|
||
# Copy the rest of the application code | ||
COPY . . | ||
# Install dependencies | ||
COPY requirements.txt . | ||
RUN pip install --upgrade pip | ||
RUN pip install -r requirements.txt | ||
|
||
# Build TypeScript (if using TypeScript) | ||
RUN npm run build | ||
# Copy application code | ||
COPY ./app /app/app | ||
|
||
# Expose the port | ||
EXPOSE 3006 | ||
# Expose port | ||
EXPOSE 8000 | ||
|
||
# Start the application | ||
CMD ["npm", "start"] | ||
# Command to run the application | ||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# backend/ai-hint-service/app/dependencies.py | ||
|
||
from dotenv import load_dotenv | ||
import os | ||
|
||
# Load environment variables from .env file | ||
load_dotenv() | ||
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") | ||
|
||
if not OPENAI_API_KEY: | ||
raise ValueError("OPENAI_API_KEY is not set in the environment variables.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# backend/ai-hint-service/app/main.py | ||
|
||
from fastapi import FastAPI | ||
from .routes import hint, code_analysis, model_answer | ||
from fastapi.middleware.cors import CORSMiddleware | ||
|
||
app = FastAPI( | ||
title="AI Hint Service", | ||
description="Provides AI-generated hints, code complexity analysis, and model answers.", | ||
version="1.0.0", | ||
) | ||
|
||
# CORS settings - adjust origins as needed | ||
origins = [ | ||
"http://localhost", | ||
"http://localhost:80", | ||
# Add other frontend URLs here | ||
] | ||
|
||
app.add_middleware( | ||
CORSMiddleware, | ||
allow_origins=origins, # Or ["*"] to allow all | ||
allow_credentials=True, | ||
allow_methods=["*"], | ||
allow_headers=["*"], | ||
) | ||
|
||
# Include routers | ||
app.include_router(hint.router, prefix="/api/hint", tags=["Hint"]) | ||
app.include_router(code_analysis.router, prefix="/api/code-analysis", tags=["Code Analysis"]) | ||
app.include_router(model_answer.router, prefix="/api/model-answer", tags=["Model Answer"]) | ||
|
||
# Root endpoint | ||
@app.get("/") | ||
def read_root(): | ||
return {"message": "AI Hint Service is up and running."} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from fastapi import APIRouter, HTTPException | ||
from ..services.openai_service import analyze_code_complexity | ||
from ..schemas.code_analysis import CodeAnalysisRequest, CodeAnalysisResponse | ||
|
||
router = APIRouter() | ||
|
||
@router.post("/", response_model=CodeAnalysisResponse) | ||
async def get_code_analysis(request: CodeAnalysisRequest): | ||
""" | ||
Analyze the complexity of the provided code. | ||
""" | ||
try: | ||
result = analyze_code_complexity(request.code, request.language) | ||
return CodeAnalysisResponse(**result) | ||
except Exception as e: | ||
raise HTTPException(status_code=500, detail=str(e)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from fastapi import APIRouter, HTTPException | ||
from ..services.openai_service import generate_hint | ||
from ..schemas.hint import HintResponse | ||
from typing import Optional | ||
|
||
router = APIRouter() | ||
|
||
@router.get("/{question_id}", response_model=HintResponse) | ||
async def get_hint(question_id: int): | ||
""" | ||
Generate a hint for the given question ID. | ||
""" | ||
# Placeholder: Fetch question description from the question service | ||
# You need to integrate with your question service's API to get the description | ||
question_description = fetch_question_description(question_id) | ||
if not question_description: | ||
raise HTTPException(status_code=404, detail="Question not found.") | ||
|
||
try: | ||
hint = generate_hint(question_description) | ||
return HintResponse(hint=hint) | ||
except Exception as e: | ||
raise HTTPException(status_code=500, detail=str(e)) | ||
|
||
def fetch_question_description(question_id: int) -> Optional[str]: | ||
# Implement the logic to fetch question description from the question service | ||
# For example, make an HTTP request to the question service's API | ||
import requests | ||
QUESTION_SERVICE_URL = "http://localhost/api/questions" | ||
QUESTION_SERVICE_URL = "http://question:3002" | ||
try: | ||
link = f"{QUESTION_SERVICE_URL}/{question_id}" | ||
print(link) | ||
response = requests.get(link) | ||
print(response) | ||
if response.status_code == 200: | ||
data = response.json() | ||
return data.get("description") | ||
else: | ||
return None | ||
except Exception as e: | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from fastapi import APIRouter, HTTPException | ||
from ..services.openai_service import generate_model_answer | ||
from ..schemas.model_answer import ModelAnswerResponse | ||
from typing import Optional | ||
|
||
router = APIRouter() | ||
|
||
@router.get("/{question_id}", response_model=ModelAnswerResponse) | ||
async def get_model_answer(question_id: int): | ||
""" | ||
Generate a model answer for the given question ID. | ||
""" | ||
# Placeholder: Fetch question description from the question service | ||
question_description = fetch_question_description(question_id) | ||
if not question_description: | ||
raise HTTPException(status_code=404, detail="Question not found.") | ||
|
||
try: | ||
model_answer = generate_model_answer(question_description, language="python") # Adjust language as needed | ||
return ModelAnswerResponse(model_answer=model_answer) | ||
except Exception as e: | ||
raise HTTPException(status_code=500, detail=str(e)) | ||
|
||
def fetch_question_description(question_id: int) -> Optional[str]: | ||
# Implement the logic to fetch question description from the question service | ||
import requests | ||
QUESTION_SERVICE_URL = "http://question:3002" | ||
try: | ||
response = requests.get(f"{QUESTION_SERVICE_URL}/{question_id}") | ||
if response.status_code == 200: | ||
data = response.json() | ||
return data.get("description") | ||
else: | ||
return None | ||
except Exception as e: | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from pydantic import BaseModel | ||
|
||
class CodeAnalysisRequest(BaseModel): | ||
code: str | ||
language: str # e.g., "python", "cpp", "java" | ||
|
||
class CodeAnalysisResponse(BaseModel): | ||
complexity: str | ||
analysis: str |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from pydantic import BaseModel | ||
|
||
class HintResponse(BaseModel): | ||
hint: str |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from pydantic import BaseModel | ||
|
||
class ModelAnswerResponse(BaseModel): | ||
model_answer: str |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from openai import OpenAI | ||
# from ..dependencies import OPENAI_API_KEY | ||
from dotenv import load_dotenv | ||
import os | ||
|
||
load_dotenv() | ||
|
||
client = OpenAI( | ||
api_key = os.getenv("OPENAI_API_KEY") | ||
) | ||
|
||
model = 'gpt-3.5-turbo-0125' | ||
|
||
def generate_hint(question_description: str) -> str: | ||
prompt = f"Provide a concise hint for the following programming problem:\n\n{question_description}\n\nHint:" | ||
completion = client.chat.completions.create( | ||
model=model, | ||
messages=[ | ||
{"role": "system", "content": "You are a helpful assistant."}, | ||
{"role": "user", "content": prompt} | ||
] | ||
) | ||
hint = completion.choices[0].message.content | ||
print(hint) | ||
return hint | ||
|
||
def analyze_code_complexity(code: str, language: str) -> dict: | ||
prompt = f"Analyze the following {language} code for its time and space complexity. Provide a detailed explanation.\n\nCode:\n{code}\n\nAnalysis:" | ||
completion = client.completions.create( | ||
model=model, | ||
messages=[ | ||
{"role": "system", "content": "You are a helpful assistant."}, | ||
{"role": "user", "content": prompt} | ||
] | ||
) | ||
analysis = completion.choices[0].message['content'] | ||
# Simple heuristic to determine complexity | ||
if "O(" in analysis: | ||
start = analysis.find("O(") | ||
end = analysis.find(")", start) + 1 | ||
complexity = analysis[start:end] | ||
else: | ||
complexity = "Complexity could not be determined." | ||
return {"complexity": complexity, "analysis": analysis} | ||
|
||
def generate_model_answer(question_description: str, language: str) -> str: | ||
prompt = f"Provide a complete and optimized {language} solution for the following programming problem:\n\n{question_description}\n\nSolution:" | ||
completion = client.completions.create( | ||
model=model, | ||
messages=[ | ||
{"role": "system", "content": "You are a helpful assistant."}, | ||
{"role": "user", "content": prompt} | ||
] | ||
) | ||
model_answer = completion.choices[0].message['content'] | ||
return model_answer |
Oops, something went wrong.