arun-j0 commited on
Commit
8506218
·
1 Parent(s): 0117ea3

initial commit

Browse files
Files changed (2) hide show
  1. app.py +78 -0
  2. groq_client.py +115 -0
app.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from groq_client import (
3
+ extract_file_id,
4
+ download_public_notebook,
5
+ review_notebook_content,
6
+ )
7
+
8
+ st.set_page_config(page_title="Notebook Reviewer", layout="wide")
9
+
10
+ # Page title and description
11
+ st.title("📓 Jupyter Notebook Reviewer with Groq AI")
12
+ st.markdown(
13
+ """
14
+ Upload a Jupyter Notebook (`.ipynb`) file or provide a Google Drive link to receive **detailed feedback** on each code cell.
15
+ Each cell's context, code, and output are analyzed for accuracy, readability, and efficiency.
16
+ """
17
+ )
18
+
19
+ # Layout: Sidebar for input options
20
+ with st.sidebar:
21
+ st.header("📥 Upload or Provide Link")
22
+ uploaded_file = st.file_uploader("Upload Notebook File", type=["ipynb"])
23
+ google_drive_link = st.text_input("OR Enter Google Drive Link")
24
+
25
+ # Main review section
26
+ st.subheader("📑 Notebook Review")
27
+
28
+ if st.button("Review Notebook"):
29
+ notebook_content = None
30
+
31
+ # Process notebook input
32
+ if uploaded_file:
33
+ notebook_content = uploaded_file.getvalue().decode("utf-8")
34
+ st.success("Notebook uploaded successfully!")
35
+ elif google_drive_link:
36
+ try:
37
+ file_id = extract_file_id(google_drive_link)
38
+ notebook_content = download_public_notebook(file_id)
39
+ st.success("Notebook downloaded successfully from Google Drive!")
40
+ except Exception as e:
41
+ st.error(f"Error: {e}")
42
+ st.stop()
43
+ else:
44
+ st.error("Please upload a file or provide a Google Drive link.")
45
+ st.stop()
46
+
47
+ # Analyze the notebook content
48
+ try:
49
+ feedback = review_notebook_content(notebook_content)
50
+ st.success(
51
+ "Notebook successfully reviewed! Scroll down to see detailed feedback."
52
+ )
53
+
54
+ # Display feedback for each cell
55
+ for cell_index, cell_feedback in enumerate(feedback, start=1):
56
+ with st.expander(f"Feedback for Cell {cell_index}", expanded=False):
57
+ # Splitting feedback into sections
58
+ cell_lines = cell_feedback.split("\n")
59
+ markdown_lines = []
60
+ code_block = []
61
+
62
+ for line in cell_lines:
63
+ if line.strip().startswith("```"): # Identify code block markers
64
+ code_block.append(line.strip("`"))
65
+ elif code_block:
66
+ code_block.append(line)
67
+ else:
68
+ markdown_lines.append(line)
69
+
70
+ # Render text feedback
71
+ st.markdown("\n".join(markdown_lines))
72
+
73
+ # Render code if present
74
+ if code_block:
75
+ st.code("\n".join(code_block), language="python")
76
+
77
+ except Exception as e:
78
+ st.error(f"An error occurred: {e}")
groq_client.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from groq import Groq
2
+ import requests
3
+ import nbformat
4
+
5
+ # Initialize the Groq client
6
+ GROQ_API_KEY = "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"
7
+ client = Groq(api_key=GROQ_API_KEY)
8
+
9
+
10
+ def extract_file_id(google_drive_link):
11
+ if "id=" in google_drive_link:
12
+ return google_drive_link.split("id=")[-1]
13
+ elif "drive.google.com/file/d/" in google_drive_link:
14
+ return google_drive_link.split("file/d/")[-1].split("/")[0]
15
+ else:
16
+ raise ValueError("Invalid Google Drive link.")
17
+
18
+
19
+ def download_public_notebook(file_id):
20
+ download_url = f"https://drive.google.com/uc?export=download&id={file_id}"
21
+ response = requests.get(download_url)
22
+ response.raise_for_status()
23
+ return response.text
24
+
25
+
26
+ def parse_notebook_with_markdown(notebook_content):
27
+ """
28
+ Parse the notebook to extract markdown, code, and corresponding outputs.
29
+ Markdown cells preceding a code cell are associated with it.
30
+ """
31
+ notebook = nbformat.reads(notebook_content, as_version=4)
32
+ cells = notebook.cells
33
+
34
+ parsed_cells = []
35
+ current_markdown = ""
36
+
37
+ for cell in cells:
38
+ if cell.cell_type == "markdown":
39
+ current_markdown += cell.source + "\n\n" # Append markdown content
40
+ elif cell.cell_type == "code":
41
+ code = cell.source
42
+ output = (
43
+ "".join(
44
+ output.text for output in cell.outputs if hasattr(output, "text")
45
+ )
46
+ or "No output"
47
+ )
48
+ parsed_cells.append((current_markdown.strip(), code, output))
49
+ current_markdown = (
50
+ "" # Reset markdown context after associating it with a code cell
51
+ )
52
+
53
+ return parsed_cells
54
+
55
+
56
+ def send_to_groq_api_with_context(markdown, code, output, cell_index):
57
+ """
58
+ Sends markdown, code, and output to the Groq API for grading.
59
+ """
60
+ prompt = f"""
61
+ You are a Python notebook grader. Below is a question or context from a Jupyter notebook, followed by the corresponding Python code and its output.
62
+
63
+ Please provide:
64
+ 1. A grade out of 10 for this cell.
65
+ 2. Detailed remarks on the quality of the code, including its readability, efficiency, and accuracy.
66
+ 3. Suggestions for improving the code if necessary.
67
+ 4. Comments on how well the code addresses the context or question provided.
68
+ 5. Actionable suggestions for improvement, including alternative solutions and learning resources.
69
+ 6. Code Quality: Assess readability, modularity, and adherence to Pythonic practices.
70
+ 7. Efficiency: Evaluate computational efficiency and suggest optimizations if necessary.
71
+ 8. Outputs: Verify the correctness and clarity of the outputs.
72
+ 9. Areas for improvement: Mention specific areas where the code or logic can be improved.
73
+ 10. Logical Errors: Specifically check if the code has logical errors or flaws that would prevent it from achieving the intended result, even if it runs without errors.
74
+
75
+ Cell Index: {cell_index}
76
+
77
+ Context or Question:
78
+ {markdown if markdown else "No specific context provided."}
79
+
80
+ Code:
81
+ {code}
82
+
83
+ Output:
84
+ {output}
85
+ """
86
+
87
+ chat_completion = client.chat.completions.create(
88
+ messages=[
89
+ {
90
+ "role": "system",
91
+ "content": "You are a Python notebook grader focusing on the provided context, code, and output for each cell. Provide a detailed analysis based on the following criteria, including checking for any logical errors that might affect the correctness of the code.",
92
+ },
93
+ {"role": "user", "content": prompt},
94
+ ],
95
+ model="llama3-8b-8192",
96
+ temperature=0.5,
97
+ max_tokens=1500,
98
+ top_p=1,
99
+ )
100
+
101
+ return chat_completion.choices[0].message.content
102
+
103
+
104
+ def review_notebook_content(notebook_content):
105
+ """
106
+ Reviews a notebook's content and returns detailed feedback for each cell.
107
+ """
108
+ parsed_cells = parse_notebook_with_markdown(notebook_content)
109
+ feedback_list = []
110
+
111
+ for i, (markdown, code, output) in enumerate(parsed_cells, start=1):
112
+ feedback = send_to_groq_api_with_context(markdown, code, output, i)
113
+ feedback_list.append(f"Feedback for Cell {i}:\n{feedback}\n{'-' * 50}")
114
+
115
+ return feedback_list