Spaces:
Sleeping
Sleeping
import requests | |
import os | |
import streamlit as st | |
import math | |
import re | |
from io import BytesIO | |
from reportlab.lib.pagesizes import letter | |
from reportlab.platypus import SimpleDocTemplate, Paragraph | |
from reportlab.lib.styles import getSampleStyleSheet | |
from azure.cosmos import CosmosClient | |
from dotenv import load_dotenv | |
load_dotenv() | |
def get_question_topics(): | |
url = os.environ["BASE_URL"]+"/question-topics" | |
headers = { | |
"x-api-key": os.environ["API_KEY"] | |
} | |
try: | |
response = requests.get(url,headers=headers) | |
response.raise_for_status() | |
return response.json()["output"] | |
except Exception as e: | |
print(f"Fehler beim Fetchen der Topics: {e}") | |
st.error("Someting went wrong. Please try again later.", icon="🚨") | |
def get_coding_task_topics(): | |
url = os.environ["BASE_URL"]+"/coding-task-topics" | |
headers = { | |
"x-api-key": os.environ["API_KEY"] | |
} | |
try: | |
response = requests.get(url,headers=headers) | |
response.raise_for_status() | |
return response.json()["output"] | |
except Exception as e: | |
print(f"Fehler beim Fetchen der Topics: {e}") | |
st.error("Someting went wrong. Please try again later.", icon="🚨") | |
def get_questions(topic): | |
topic = topic.replace(" ", "%20") | |
topic = topic.replace("&", "%26") | |
url = os.environ["BASE_URL"]+"/questions"+f"?dimension={topic}" | |
headers = { | |
"x-api-key": os.environ["API_KEY"] | |
} | |
try: | |
response = requests.get(url, data=topic, headers=headers) | |
response.raise_for_status() | |
# print(response.json()) | |
return response.json()["output"] | |
except Exception as e: | |
print(f"Fehler beim Fetchen der Topics: {e}") | |
st.error("Someting went wrong. Please try again later.", icon="🚨") | |
def get_coding_tasks(topic): | |
url = os.environ["BASE_URL"]+"/coding-tasks"+f"?topic={topic}" | |
headers = { | |
"x-api-key": os.environ["API_KEY"] | |
} | |
try: | |
response = requests.get(url, data=topic, headers=headers) | |
response.raise_for_status() | |
print(response.json()) | |
return response.json()["output"] | |
except Exception as e: | |
print(f"Fehler beim Fetchen der Topics: {e}") | |
st.error("Someting went wrong. Please try again later.", icon="🚨") | |
def load_topics_into_question_list(): | |
st.session_state["current_page"] = 1 | |
with st.spinner("Loading questions..."): | |
for topic in st.session_state["loaded_questions"]: | |
if topic["topic"] not in st.session_state["selected_topics"]: | |
st.session_state["loaded_questions"].remove(topic) | |
for topic in st.session_state["selected_topics"]: | |
if topic not in [topic["topic"] for topic in st.session_state["loaded_questions"]]: | |
question_element = {"topic": topic, "questions": get_questions(topic)} | |
st.session_state["loaded_questions"].append(question_element) | |
def load_topics_into_task_list(): | |
st.session_state["current_page"] = 1 | |
with st.spinner("Loading coding tasks..."): | |
for topic in st.session_state["loaded_tasks"]: | |
if topic["topic"] not in st.session_state["selected_task_topics"]: | |
st.session_state["loaded_tasks"].remove(topic) | |
for topic in st.session_state["selected_task_topics"]: | |
if topic not in [topic["topic"] for topic in st.session_state["loaded_tasks"]]: | |
question_element = {"topic": topic, "tasks": get_coding_tasks(topic)} | |
st.session_state["loaded_tasks"].append(question_element) | |
def add_question_to_interview(question): | |
if question not in st.session_state["questions_for_interview"]: | |
st.session_state["questions_for_interview"].append(question) | |
else: | |
print("Question already in list") | |
def increment_page(): | |
if st.session_state["current_page"] < math.ceil(len(st.session_state["questions_to_display"])/10): | |
st.session_state["current_page"] += 1 | |
def decrement_page(): | |
if st.session_state["current_page"] > 1: | |
st.session_state["current_page"] -= 1 | |
def change_question_type(): | |
st.session_state["current_page"] = 1 | |
if st.session_state["question_type"] == "question": | |
st.session_state["question_type"] = "coding_tasks" | |
else: | |
st.session_state["question_type"] = "question" | |
def update_questions_and_tasks(): | |
try: | |
with st.spinner("Updating questions and tasks..."): | |
client: CosmosClient = st.session_state["db"] | |
database = client.get_database_client("assessment-database") | |
container = database.get_container_client("assessments") | |
assessment = st.session_state["assessment_db_object"] | |
questions_for_db = [] | |
for question in st.session_state["questions_for_interview"]: | |
questions_for_db.append({"question": question["question"], "perfect_answer": question["perfect_answer"], "score": "", "evaluation": ""}) | |
assessment["questions"] = questions_for_db | |
tasks_for_db = [] | |
for task in st.session_state["tasks_for_interview"]: | |
tasks_for_db.append({"coding_task": task["task"], "perfect_solution": task["perfect_solution"], "score": "", "evaluation": ""}) | |
assessment["coding_tasks"] = tasks_for_db | |
assessment["process_status"] = "assessment_prepared" | |
container.upsert_item(assessment) | |
except Exception as e: | |
print(f"Fehler beim Speichern der Fragen und Aufgaben: {e}") | |
st.error("Someting went wrong. Please try again later.", icon="🚨") | |
def fix_br_tags(input_string: str): | |
return input_string.replace("<br>", "<br/>") | |
def remove_html_tags(input_string: str): | |
clean = re.compile('<.*?>') | |
return re.sub(clean, '', input_string) | |
if "topics" not in st.session_state: | |
topics = list(set([topic["dimension"] for topic in get_question_topics() if topic["dimension"] != None])) | |
st.session_state["topics"] = topics | |
if "task_topics" not in st.session_state: | |
topics = list(set([topic for topic in get_coding_task_topics() if topic != None])) | |
st.session_state["task_topics"] = topics | |
if "loaded_questions" not in st.session_state: | |
st.session_state["loaded_questions"] = [] | |
if "loaded_tasks" not in st.session_state: | |
st.session_state["loaded_tasks"] = [] | |
if "selected_topics" not in st.session_state: | |
st.session_state["selected_topics"] = [] | |
if "questions_to_display" not in st.session_state: | |
st.session_state["questions_to_display"] = [] | |
if "tasks_to_display" not in st.session_state: | |
st.session_state["tasks_to_display"] = [] | |
if "questions_for_interview" not in st.session_state: | |
st.session_state["questions_for_interview"] = [] | |
if "current_page" not in st.session_state: | |
st.session_state["current_page"] = 1 | |
if "question_type" not in st.session_state: | |
st.session_state["question_type"] = "question" | |
if "tasks_for_interview" not in st.session_state: | |
st.session_state["tasks_for_interview"] = [] | |
if "db" not in st.session_state: | |
client = CosmosClient(os.environ["COSMOS_DB_ENDPOINT"], os.environ["COSMOS_DB_KEY"]) | |
st.session_state["db"] = client | |
if "assessment_db_object" not in st.session_state: | |
if "assessment-id" in st.query_params: | |
client: CosmosClient = st.session_state["db"] | |
database = client.get_database_client("assessment-database") | |
container = database.get_container_client("assessments") | |
assessment = container.query_items(query="SELECT * FROM c WHERE c.id = @assessment_id", parameters=[dict(name="@assessment_id", value=st.query_params["assessment-id"]) ,], enable_cross_partition_query=True, max_item_count=1) | |
st.session_state["assessment_db_object"] = list(assessment)[0] | |
else: | |
st.error("No assessment found. Please contact the side admin.", icon="🚨") | |
st.stop() | |
col1, col2 = st.columns([2, 1]) | |
col1.title("Interview Preparation") | |
col2.image("https://www.workgenius.com/wp-content/uploads/2023/03/WorkGenius_navy-1.svg") | |
st.write("Assessment: "+st.session_state["assessment_db_object"]["assessment_title"]) | |
type_col1, type_col2 = st.columns([1, 1]) | |
with type_col1: | |
st.button("Questions", key="question_button", on_click=change_question_type, disabled=True if st.session_state["question_type"] == "question" else False, use_container_width=True) | |
with type_col2: | |
st.button("Coding tasks", key="coding_tasks", on_click=change_question_type, disabled=True if st.session_state["question_type"] == "coding_tasks" else False, use_container_width=True) | |
if st.session_state["question_type"] == "question": | |
st.multiselect("Select the topics for the questions", st.session_state["topics"], key="selected_topics", default=None, on_change=load_topics_into_question_list) | |
st.divider() | |
if len(st.session_state["selected_topics"]) > 0: | |
st.subheader("Questions to choose from:") | |
st.write("Filter according to the difficulty of the questions:") | |
st.checkbox("Easy", key="checkbox_filter_easy", value=True) | |
st.checkbox("Medium", key="checkbox_filter_medium", value=True) | |
st.checkbox("Hard", key="checkbox_filter_hard", value=True) | |
st.write("Filter by the topic of the questions:") | |
for topic in st.session_state["loaded_questions"]: | |
st.checkbox(topic["topic"], key="checkbox_filter_"+topic["topic"], value=True) | |
result_questions = [] | |
for i, topic in enumerate(st.session_state["loaded_questions"]): | |
if st.session_state["checkbox_filter_"+topic["topic"]]: | |
for j, question in enumerate(topic["questions"]): | |
if st.session_state["checkbox_filter_easy"] and question["difficulty"] == "Easy": | |
result_questions.append(question) | |
if st.session_state["checkbox_filter_medium"] and question["difficulty"] == "Medium": | |
result_questions.append(question) | |
if st.session_state["checkbox_filter_hard"] and question["difficulty"] == "Hard": | |
result_questions.append(question) | |
st.session_state["questions_to_display"] = result_questions | |
if len(st.session_state["questions_to_display"]) > 0: | |
nav_col1, nav_col2, nav_col3 = st.columns([1, 4, 1]) | |
nav_col1.button("◀️", key="nav1", use_container_width=True, on_click=decrement_page, disabled=True if st.session_state["current_page"] == 1 else False) | |
nav_col2.markdown(f"<div style='text-align: center;'>Page {str(st.session_state['current_page'])} / {str(math.ceil(len(st.session_state['questions_to_display'])/10))}</div>", unsafe_allow_html=True) | |
nav_col3.button("▶️", key="nav2", use_container_width=True, on_click=increment_page, disabled=True if st.session_state["current_page"] == math.ceil(len(st.session_state["questions_to_display"])/10) else False) | |
for i in range((st.session_state["current_page"]-1)*10, st.session_state["current_page"]*10 if st.session_state["current_page"]*10 < len(st.session_state["questions_to_display"]) else len(st.session_state["questions_to_display"])): | |
col_1, col_2 = st.columns([7, 1]) | |
with col_1: | |
st.write(remove_html_tags(st.session_state["questions_to_display"][i]["question"])) | |
with col_2: | |
st.button("Select", disabled=True if st.session_state["questions_to_display"][i] in st.session_state["questions_for_interview"] else False ,key="select_button_"+str(i), on_click=add_question_to_interview, args=(st.session_state["questions_to_display"][i],)) | |
else: | |
st.multiselect("Select the topics for the coding tasks", options=st.session_state["task_topics"], key="selected_task_topics", default=None, on_change=load_topics_into_task_list) | |
st.divider() | |
if len(st.session_state["selected_task_topics"]) > 0: | |
st.subheader("Coding tasks to choose from:") | |
st.write("Filter by the topic of the coding task:") | |
for topic in st.session_state["loaded_tasks"]: | |
st.checkbox(topic["topic"], key="checkbox_filter_tasks_"+topic["topic"], value=True) | |
result_tasks = [] | |
for i, topic in enumerate(st.session_state["loaded_tasks"]): | |
if st.session_state["checkbox_filter_tasks_"+topic["topic"]]: | |
for j, task in enumerate(topic["tasks"]): | |
result_tasks.append(task) | |
st.session_state["tasks_to_display"] = result_tasks | |
if len(st.session_state["tasks_to_display"]) > 0: | |
nav_col1, nav_col2, nav_col3 = st.columns([1, 4, 1]) | |
nav_col1.button("◀️", key="nav1", use_container_width=True, on_click=decrement_page, disabled=True if st.session_state["current_page"] == 1 else False) | |
nav_col2.markdown(f"<div style='text-align: center;'>Page {str(st.session_state['current_page'])} / {str(math.ceil(len(st.session_state['tasks_to_display'])/10))}</div>", unsafe_allow_html=True) | |
nav_col3.button("▶️", key="nav2", use_container_width=True, on_click=increment_page, disabled=True if st.session_state["current_page"] == math.ceil(len(st.session_state["tasks_to_display"])/10) else False) | |
for i in range((st.session_state["current_page"]-1)*10, st.session_state["current_page"]*10 if st.session_state["current_page"]*10 < len(st.session_state["tasks_to_display"]) else len(st.session_state["tasks_to_display"])): | |
col_1, col_2 = st.columns([7, 1]) | |
with col_1: | |
st.write(st.session_state["tasks_to_display"][i]["task"]) | |
with col_2: | |
st.button("Select", disabled=True if st.session_state["tasks_to_display"][i] in st.session_state["tasks_for_interview"] else False ,key="select_button_tasks_"+str(i), on_click=st.session_state["tasks_for_interview"].append, args=(st.session_state["tasks_to_display"][i],)) | |
st.divider() | |
st.subheader("Questions for the interview:") | |
if len(st.session_state["questions_for_interview"]) == 0: | |
st.write("No questions selected yet.") | |
for i, question in enumerate(st.session_state["questions_for_interview"]): | |
interview_col_1, interview_col_2 = st.columns([7, 1]) | |
with interview_col_1: | |
st.write(remove_html_tags(question["question"])) | |
with interview_col_2: | |
st.button("Remove", key="remove_button_"+str(i), on_click=st.session_state["questions_for_interview"].remove, args=(question,)) | |
st.subheader("Coding tasks for the interview:") | |
if len(st.session_state["tasks_for_interview"]) == 0: | |
st.write("No coding tasks selected yet.") | |
for i, task in enumerate(st.session_state["tasks_for_interview"]): | |
interview_col_1, interview_col_2 = st.columns([6, 2]) | |
with interview_col_1: | |
st.write(task["task"]) | |
with interview_col_2: | |
st.button("Remove", key="remove_button_tasks_"+str(i), on_click=st.session_state["tasks_for_interview"].remove, args=(task,)) | |
st.divider() | |
if len(st.session_state["questions_for_interview"]) > 0 and len(st.session_state["tasks_for_interview"]) > 0: | |
st.write("You can now save the questions and coding tasks for your interview.") | |
# Erstelle eine BytesIO, um die PDF im Speicher zu halten | |
pdf_buffer = BytesIO() | |
doc = SimpleDocTemplate(pdf_buffer, pagesize=letter, title="Interview Questions") | |
styles = getSampleStyleSheet() | |
paragraphs = [] | |
for i, question in enumerate(st.session_state["questions_for_interview"]): | |
paragraph_text = f"<font size='14'><b>Question {i+1}. :</b></font><br/><br/>{question['question']}<br/><b>Perfect answer:</b> {question['perfect_answer']}<br/><b>Difficulty:</b> {question['difficulty']}\n" | |
try: | |
paragraphs.append(Paragraph(paragraph_text, styles["Normal"])) | |
except: | |
try: | |
paragraphs.append(Paragraph(fix_br_tags(paragraph_text), styles["Normal"])) | |
except: | |
paragraphs.append(Paragraph(remove_html_tags(paragraph_text), styles["Normal"])) | |
paragraphs.append(Paragraph("<br/><br/>", styles["Normal"])) # Zusätzlicher Zeilenumbruch mit 12pt Abstand | |
for i, task in enumerate(st.session_state["tasks_for_interview"]): | |
paragraph_text = f"<font size='14'><b>Coding task {i+1}. :</b></font><br/><br/>{task['task']}<br/><b>Perfect answer:</b> {task['perfect_solution']}\n" | |
try: | |
paragraphs.append(Paragraph(paragraph_text, styles["Normal"])) | |
except: | |
try: | |
paragraphs.append(Paragraph(fix_br_tags(paragraph_text), styles["Normal"])) | |
except: | |
paragraphs.append(Paragraph(remove_html_tags(paragraph_text), styles["Normal"])) | |
paragraphs.append(Paragraph("<br/><br/>", styles["Normal"])) # Zusätzlicher Zeilenumbruch mit 12pt Abstand | |
# Füge die Paragraphen in das PDF-Dokument ein | |
doc.build(paragraphs) | |
# Speichere die PDF und schließe den Stream | |
pdf_buffer.seek(0) | |
# Zeige den Download-Button für die PDF an | |
st.download_button(label="Download", data=pdf_buffer, file_name=f'interview_questions_{st.session_state["assessment_db_object"]["assessment_title"]}.pdf', mime="application/pdf", on_click=update_questions_and_tasks) |