scriptsledge commited on
Commit
9725757
·
verified ·
1 Parent(s): 55ff7a7

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +26 -0
  2. main.py +22 -0
  3. model_service.py +62 -0
  4. requirements.txt +4 -0
Dockerfile ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use the official Python 3.10 slim image
2
+ FROM python:3.10-slim
3
+
4
+ # Set the working directory to /app
5
+ WORKDIR /app
6
+
7
+ # Copy the requirements file into the container at /app
8
+ COPY requirements.txt .
9
+
10
+ # Install any needed packages specified in requirements.txt
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ # Copy the current directory contents into the container at /app
14
+ COPY . .
15
+
16
+ # Create a non-root user and switch to it (required by Hugging Face Spaces)
17
+ RUN useradd -m -u 1000 user
18
+ USER user
19
+ ENV HOME=/home/user \
20
+ PATH=/home/user/.local/bin:$PATH
21
+
22
+ # Expose port 7860 (Hugging Face Spaces default)
23
+ EXPOSE 7860
24
+
25
+ # Run uvicorn when the container launches
26
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
main.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+
5
+ from model_service import correct_code_with_ai
6
+ app = FastAPI()
7
+ app.add_middleware(
8
+ CORSMiddleware,
9
+ allow_origins=["*"], # Allows all origins for simplicity.
10
+ allow_credentials=True,
11
+ allow_methods=["*"],
12
+ allow_headers=["*"],
13
+ )
14
+
15
+ class CodeSnippet(BaseModel):
16
+ code: str
17
+
18
+ @app.post("/api/correct")
19
+ def correct_code_endpoint(snippet: CodeSnippet):
20
+ corrected_code = correct_code_with_ai(snippet.code)
21
+ return {"corrected_code": corrected_code}
22
+
model_service.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
2
+
3
+ # Initialize the model pipeline.
4
+ # We use 'Qwen/Qwen2.5-0.5B-Instruct' which is small, fast, and works natively.
5
+ model_id = "Qwen/Qwen2.5-0.5B-Instruct"
6
+ print(f"Loading AI model ({model_id})...")
7
+
8
+ code_fixer = None
9
+ try:
10
+ # 1. Try loading from local cache first (offline mode)
11
+ print("Attempting to load from local cache...")
12
+ model = AutoModelForCausalLM.from_pretrained(model_id, trust_remote_code=True, local_files_only=True)
13
+ tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True, local_files_only=True)
14
+ code_fixer = pipeline("text-generation", model=model, tokenizer=tokenizer)
15
+ print("Success: Loaded model from local cache.")
16
+ except Exception as local_err:
17
+ print(f"Local cache not found or incomplete: {local_err}")
18
+ print("Attempting to download model from Hugging Face (requires internet)...")
19
+ try:
20
+ # 2. Fallback to downloading (online mode)
21
+ code_fixer = pipeline("text-generation", model=model_id, trust_remote_code=True)
22
+ print("Success: Model downloaded and loaded.")
23
+ except Exception as remote_err:
24
+ print(f"CRITICAL: Failed to load model. Error: {remote_err}")
25
+ print("To run locally, ensure you have internet access for the first run to download the model.")
26
+ code_fixer = None
27
+
28
+ def correct_code_with_ai(code: str) -> str:
29
+ """
30
+ Takes a buggy code snippet and returns a corrected version using the Qwen model.
31
+ """
32
+ if not code_fixer:
33
+ return "# Model failed to load. Check server logs."
34
+
35
+ # Frame the input as a chat conversation
36
+ messages = [
37
+ {"role": "system", "content": "You are a helpful Python coding assistant. Your task is to fix bugs, suggest better variable naming in form of comments in the provided code. Return ONLY the corrected code, without explanation."},
38
+ {"role": "user", "content": f"{code}"},
39
+ ]
40
+
41
+ try:
42
+ # Generate the response
43
+ # max_new_tokens controls how much new text is generated.
44
+ outputs = code_fixer(messages, max_new_tokens=512)
45
+
46
+ # The pipeline for chat-like input typically returns a list of dictionaries.
47
+ # We need to parse the output to get just the assistant's response.
48
+ # The structure is usually: [{'generated_text': [...conversation including response...]}]
49
+ # or sometimes just the generated text depending on pipeline version.
50
+
51
+ result = outputs[0]['generated_text']
52
+
53
+ # If the result is the full conversation list (common in newer transformers for chat)
54
+ if isinstance(result, list):
55
+ # The last message should be the assistant's response
56
+ return result[-1]['content']
57
+ else:
58
+ # Fallback if it returns a string
59
+ return result
60
+ except Exception as e:
61
+ print(f"An error occurred during AI correction: {e}")
62
+ return f"# Unable to correct the code. Error: {str(e)}"
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ transformers
4
+ torch