Skip to content

Commit

Permalink
Switch to python
Browse files Browse the repository at this point in the history
  • Loading branch information
yitong241 committed Nov 9, 2024
1 parent 88eeaf8 commit 4e7729d
Show file tree
Hide file tree
Showing 26 changed files with 329 additions and 2,072 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file modified backend/.DS_Store
Binary file not shown.
2 changes: 0 additions & 2 deletions backend/ai-hint-service/.env.sample

This file was deleted.

4 changes: 1 addition & 3 deletions backend/ai-hint-service/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
dist/
.env
node_modules/
.env
33 changes: 17 additions & 16 deletions backend/ai-hint-service/Dockerfile
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"]
11 changes: 11 additions & 0 deletions backend/ai-hint-service/app/dependencies.py
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.")
36 changes: 36 additions & 0 deletions backend/ai-hint-service/app/main.py
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."}
16 changes: 16 additions & 0 deletions backend/ai-hint-service/app/routes/code_analysis.py
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))
42 changes: 42 additions & 0 deletions backend/ai-hint-service/app/routes/hint.py
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
36 changes: 36 additions & 0 deletions backend/ai-hint-service/app/routes/model_answer.py
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
9 changes: 9 additions & 0 deletions backend/ai-hint-service/app/schemas/code_analysis.py
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
4 changes: 4 additions & 0 deletions backend/ai-hint-service/app/schemas/hint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from pydantic import BaseModel

class HintResponse(BaseModel):
hint: str
4 changes: 4 additions & 0 deletions backend/ai-hint-service/app/schemas/model_answer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from pydantic import BaseModel

class ModelAnswerResponse(BaseModel):
model_answer: str
56 changes: 56 additions & 0 deletions backend/ai-hint-service/app/services/openai_service.py
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
Loading

0 comments on commit 4e7729d

Please sign in to comment.