ml-visoft commited on
Commit
f8637f2
1 Parent(s): 376953f

WIP login w HF

Browse files

Attempt to fix broken +/- buttons

main.py CHANGED
@@ -5,6 +5,11 @@ import pathlib
5
  from uuid import uuid4
6
  from datetime import datetime
7
  import dataclasses
 
 
 
 
 
8
 
9
  from fasthtml.common import *
10
  from fastcore.all import typedispatch
@@ -19,7 +24,7 @@ import storage
19
  OAUTH_CLIENT_ID = os.environ.get('OAUTH_CLIENT_ID')
20
  OAUTH_SCOPES = os.environ.get('OAUTH_SCOPES')
21
  OAUTH_CLIENT_SECRET = os.environ.get('OAUTH_CLIENT_SECRET')
22
- OPENID_PROVIDER_URL = os.environ.get('OPENID_PROVIDER_URL')
23
  SPACE_HOST = os.environ.get('SPACE_HOST')
24
  HF_DATASET_AUTH_TOKEN = os.environ.get('HF_DATASET_AUTH_TOKEN', "none")
25
 
@@ -103,8 +108,41 @@ HTML_SUBMIT_CODE_AREA = "submit_code_area"
103
  HTML_RESULTS_AREA = "prompt_response"
104
  HTML_CLEAR_FORM = "clear_the_form"
105
  HTML_SUBMIT_FEEDBACK = "submit_feedback"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
- hdrs = (HighlightJS(langs=['python', 'javascript', 'html', 'css']),)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  if IS_LOCALHOST:
110
  # Are we hacking locally?
@@ -173,10 +211,10 @@ def html_create_feedback_updown_button(qe_id, ans_id, selected=0, disabled=False
173
  down_col = colors[0]
174
  if selected == 1: up_col = colors[1]
175
  if selected == -1: down_col = colors[1]
176
- toggle_url = f"/toggle_up_down/{qe_id}/{ans_id}/"
177
- up = Button("+", hx_get=f"/toggle_up_down/{qe_id}/{ans_id}/?which=1", hx_swap="outerHTML",
178
  target_id=f"{html_target_id}", style=f"background-color:{up_col}")
179
- down = Button("-", hx_get=f"{toggle_url}?which=-1", disabled=disabled, hx_swap="outerHTML",
180
  hx_preserve=True, hx_trigger="click", hx_push_url="false",
181
  target_id=f"{html_target_id}", style=f"background-color:{down_col}")
182
  button_row = Div(up, down, id=html_target_id)
@@ -198,7 +236,7 @@ def html_augment_evaluation_text_with_feedback(eval_html, qe_id, ans_id, selecte
198
  return final_div
199
 
200
 
201
- @rt("/toggle_up_down/{qe_id}/{ans_id}")
202
  def get(session, qe_id:int, ans_id:int, which:int):
203
  """
204
  Answer to the +/- button presses
@@ -449,11 +487,142 @@ def render_clear_area(session_id, html_id):
449
  return Div(P(""), id=html_id, hx_swap_oob='true')
450
 
451
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
452
  ########## MAIN PAGE
453
 
 
454
  @rt("/")
455
  def get(session):
456
- # print(session)
457
  if 'session_id' not in session:
458
  session['session_id'] = str(uuid.uuid4())
459
  session_id = session["session_id"]
@@ -463,40 +632,19 @@ def get(session):
463
  save_to_storage(
464
  storage.NavigationEvent(event_type="/", event_session_id=session_id)
465
  )
466
- title = Title('C code review for students')
467
- preamble = [H1("Evaluate your C code!"),
468
- P("Enter your code in the textbox below and wait for answers."),
469
- P("!! The data will be saved and maybe made public !!"),
470
- ]
471
 
472
- # ############
473
- # # !!! FOR DEBUGGING PURPOSES !!!
474
- #
475
- # # insert an answer in db.
476
- # code = """
477
- # #include <stdio.h>
478
- # int main() {
479
- # // printf() displays the string inside quotation
480
- # printf("Hello, World!");
481
- # return 0;
482
- # }
483
- # """
484
- # answer = eval_code.eval_the_piece_of_c_code(None, None)
485
- # enhanced_answer = eval_code.add_evaluation_fields_on_js_answer(answer, CODE_AUGMENTATIONS)
486
- # session_obj = Session_State_cls(
487
- # session_id=session_id,
488
- # state=EVAL_STATE_ANSWER,
489
- # submitted=datetime.utcnow(),
490
- # )
491
- #
492
- # # we create a new QA entry.
493
- # qa_obj = Question_Evaluation_cls(code_text=code,
494
- # answer_eval_text=enhanced_answer, submitted=0)
495
- # qa_obj = question_evaluation_table.insert(qa_obj)
496
- # session_obj.current_qeval = qa_obj.id
497
- # session_obj = session_state_table.insert(session_obj)
498
- #
499
- # ############
500
 
501
  input_area = html_render_inputbox(target_html_id=HTML_RESULTS_AREA, region_html_id=HTML_SUBMIT_CODE_AREA)
502
  results_area = html_render_answer_from_db(session_id, HTML_RESULTS_AREA)
 
5
  from uuid import uuid4
6
  from datetime import datetime
7
  import dataclasses
8
+ import html
9
+ import base64
10
+ import requests
11
+ import secrets
12
+
13
 
14
  from fasthtml.common import *
15
  from fastcore.all import typedispatch
 
24
  OAUTH_CLIENT_ID = os.environ.get('OAUTH_CLIENT_ID')
25
  OAUTH_SCOPES = os.environ.get('OAUTH_SCOPES')
26
  OAUTH_CLIENT_SECRET = os.environ.get('OAUTH_CLIENT_SECRET')
27
+ OPENID_PROVIDER_URL = os.environ.get("OPENID_PROVIDER_URL", "https://huggingface.co")
28
  SPACE_HOST = os.environ.get('SPACE_HOST')
29
  HF_DATASET_AUTH_TOKEN = os.environ.get('HF_DATASET_AUTH_TOKEN', "none")
30
 
 
108
  HTML_RESULTS_AREA = "prompt_response"
109
  HTML_CLEAR_FORM = "clear_the_form"
110
  HTML_SUBMIT_FEEDBACK = "submit_feedback"
111
+ HTML_USER_DATA = "login_user_data"
112
+
113
+
114
+ def get_openid_configuration():
115
+ config_url = OPENID_PROVIDER_URL + "/.well-known/openid-configuration"
116
+
117
+ try:
118
+ response = requests.get(config_url)
119
+ response.raise_for_status() # Raises an HTTPError for bad responses (4xx or 5xx)
120
+
121
+ config = response.json()
122
+
123
+ token_endpoint = config.get('token_endpoint')
124
+ userinfo_endpoint = config.get('userinfo_endpoint')
125
 
126
+ return token_endpoint, userinfo_endpoint
127
+
128
+ except requests.RequestException as e:
129
+ print(f"An error occurred: {e}")
130
+ return None, None
131
+
132
+
133
+ # Use the function
134
+ HF_OAUTH_TOKEN_URL, HF_OAUTH_USERINFO = get_openid_configuration()
135
+
136
+ if HF_OAUTH_TOKEN_URL and HF_OAUTH_USERINFO:
137
+ print(f"Token Endpoint: {HF_OAUTH_TOKEN_URL}")
138
+ print(f"UserInfo Endpoint: {HF_OAUTH_USERINFO}")
139
+ else:
140
+ print("Failed to retrieve the endpoints.")
141
+
142
+
143
+ hdrs = (
144
+ HighlightJS(langs=['python', 'javascript', 'html', 'css']),
145
+ )
146
 
147
  if IS_LOCALHOST:
148
  # Are we hacking locally?
 
211
  down_col = colors[0]
212
  if selected == 1: up_col = colors[1]
213
  if selected == -1: down_col = colors[1]
214
+ toggle_url = f"/toggle_up_down/{qe_id}/{ans_id}"
215
+ up = Button("+", hx_get=f"{toggle_url}/1", hx_swap="outerHTML",
216
  target_id=f"{html_target_id}", style=f"background-color:{up_col}")
217
+ down = Button("-", hx_get=f"{toggle_url}/-1", disabled=disabled, hx_swap="outerHTML",
218
  hx_preserve=True, hx_trigger="click", hx_push_url="false",
219
  target_id=f"{html_target_id}", style=f"background-color:{down_col}")
220
  button_row = Div(up, down, id=html_target_id)
 
236
  return final_div
237
 
238
 
239
+ @rt("/toggle_up_down/{qe_id}/{ans_id}/{which}")
240
  def get(session, qe_id:int, ans_id:int, which:int):
241
  """
242
  Answer to the +/- button presses
 
487
  return Div(P(""), id=html_id, hx_swap_oob='true')
488
 
489
 
490
+ ########## AUTHENTICATION
491
+
492
+ def html_render_login_to_get_access_part(session):
493
+ """
494
+ Will render the Log in to get access part and set the session oauth_secret.
495
+
496
+ :param session:
497
+ :return:
498
+ """
499
+ content = []
500
+ content.append(H3("Log in to give feedback!"))
501
+ content.append(P("We will record your name, hugginface name, hf profile page, email address. "
502
+ "We will try HARD not to make them public but . . ."))
503
+ content.append(P("Your feedback will be made public but in an anonymized form."))
504
+
505
+ # build the redirect URL
506
+ global SPACE_HOST
507
+ if "localhost" in SPACE_HOST:
508
+ space_host = f"http://{SPACE_HOST}/auth_callback/"
509
+ else:
510
+ space_host = f"https://{SPACE_HOST}/auth_callback/"
511
+
512
+ secret = secrets.token_urlsafe(32)
513
+ session["oauth_secret"] = secret
514
+ encoded_scopes = html.escape(OAUTH_SCOPES)
515
+ redirect_link = (f"https://huggingface.co/oauth/authorize?redirect_uri={space_host}&scope={encoded_scopes}"
516
+ f"&client_id={OAUTH_CLIENT_ID}&state={secret}&response_type=code&prompt=consent")
517
+ login_button = A(Img(src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-md.svg",
518
+ alt="Sign in with Hugging Face",
519
+ # style="cursor: pointer; display: none;",
520
+ id="signin", name=None),
521
+ href=redirect_link, target="_blank")
522
+ content.append(login_button)
523
+ content.append(P(" "))
524
+ div = Div(*content, id=HTML_USER_DATA)
525
+ return div
526
+
527
+ def html_render_welcome_user(user_info):
528
+ """
529
+ Extracts the user data and paints the Welcome screen
530
+
531
+ :param user_info:
532
+ :return:
533
+ """
534
+ content = []
535
+ content.append(H4(f"Welcome {user_info['name']}!"))
536
+ # content.append(Img(src=OPENID_PROVIDER_URL + user_info["picture"], alt="Picture"))
537
+ content.append(P("Your feedback will be made public but in an anonymized form."))
538
+ div = Div(*content, id=HTML_USER_DATA)
539
+ return div
540
+
541
+
542
+ @rt("/auth_callback")
543
+ def get(session, code:str=None, state:str=None, error:str=None, error_description:str=None):
544
+ """
545
+ Endpoint that will be called by HF once the user gives (or not) consent
546
+
547
+ :param session:
548
+ :param code:
549
+ :param state:
550
+ :param error:
551
+ :param error_description:
552
+ :return:
553
+ """
554
+ ans = None
555
+ if error is not None:
556
+ print(f"HF OAuth returned an error: {error} {error_description}")
557
+ ans = Div(P(f"We can't log you in. Huggingface says: {error_description}"),
558
+ P("Please close this page"))
559
+ return ans
560
+ print(f"OAuth returned a code")
561
+
562
+ # validating the secret
563
+ sess_secret = session.get("oauth_secret", None)
564
+ if sess_secret is None:
565
+ print("No session secret")
566
+ return P("access denied")
567
+
568
+ if sess_secret != state:
569
+ print(f"Mistmatch session secret and HF secret: {sess_secret=} {state=}")
570
+
571
+ # Moving on and get the token
572
+ global SPACE_HOST
573
+ if "localhost" in SPACE_HOST:
574
+ space_host = f"http://{SPACE_HOST}/auth_callback/"
575
+ else:
576
+ space_host = f"https://{SPACE_HOST}/auth_callback/"
577
+
578
+ auth_header = base64.b64encode(f"{OAUTH_CLIENT_ID}:{OAUTH_CLIENT_SECRET}".encode()).decode()
579
+ headers = {
580
+ "Authorization": f"Basic {auth_header}",
581
+ "Content-Type": "application/x-www-form-urlencoded",
582
+ }
583
+ data = {
584
+ "client_id": OAUTH_CLIENT_ID,
585
+ "code": code,
586
+ "grant_type": "authorization_code",
587
+ "redirect_uri": space_host,
588
+ }
589
+ token_response = requests.post(HF_OAUTH_TOKEN_URL, data=data, headers=headers)
590
+
591
+ if token_response.status_code == 200:
592
+ tokens = token_response.json()
593
+ # Here you would typically store the tokens securely and/or use them
594
+ print("Succsss in getting the token")
595
+
596
+ access_token = tokens["access_token"]
597
+ user_headers = {
598
+ "Authorization": f"Bearer {access_token}"
599
+ }
600
+ response_userinfo = requests.get(HF_OAUTH_USERINFO, headers=user_headers)
601
+ if response_userinfo.status_code == 200:
602
+ user_data = response_userinfo.json()
603
+ # Set the user data in DB
604
+ # TODO set the user data in db For now, set it in session
605
+ session["user_data"] = user_data
606
+ session["oauth_secret"] = None
607
+ print(user_data)
608
+
609
+ else:
610
+ print(f"Error while taking the user data: {response_userinfo.text}" )
611
+ return P("Error logging in")
612
+ else:
613
+ print(f"We did not get the tokens: {token_response.text}")
614
+ return P("Error logging in")
615
+
616
+ print(session)
617
+ return P("Succes! Close this page.")
618
+
619
+
620
  ########## MAIN PAGE
621
 
622
+
623
  @rt("/")
624
  def get(session):
625
+ print(session)
626
  if 'session_id' not in session:
627
  session['session_id'] = str(uuid.uuid4())
628
  session_id = session["session_id"]
 
632
  save_to_storage(
633
  storage.NavigationEvent(event_type="/", event_session_id=session_id)
634
  )
635
+ user_data = session.get("user_data", None)
636
+ if user_data is not None:
637
+ auth_area = html_render_welcome_user(user_data)
638
+ else:
639
+ auth_area = html_render_login_to_get_access_part(session) # might set some secrets here
640
 
641
+ title = Title('C code review for students')
642
+ preamble = [
643
+ auth_area,
644
+ H1("Evaluate your C code!"),
645
+ P("Enter your code in the textbox below and wait for answers."),
646
+ P("!! The data will be saved and maybe made public !!"),
647
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
 
649
  input_area = html_render_inputbox(target_html_id=HTML_RESULTS_AREA, region_html_id=HTML_SUBMIT_CODE_AREA)
650
  results_area = html_render_answer_from_db(session_id, HTML_RESULTS_AREA)
test/raw_data_submitted-2024-08-14T07_47_28.731439-5977364a-5411-4f15-9c73-43f90d49c762.jsonl ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {"version": 1, "submitted_date": "2024-08-14T08:00:42.190468", "received_date": "2024-08-14T08:00:42.202949", "event_session_id": "6f888ecf-bc25-48f0-bfd2-0280ced98644", "db_question_evaluation_id": 1, "code_to_eval": "datetime_now", "evaluation_engine": "chatGPT", "prompt_version": 1, "evaluation_response": "[{\"criteria\": \"HUMAN_FEEDBACK\", \"explanation\": \"\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"The memory allocation and initialization for ``p1``, ``p2``, and ``p3`` are repetitive. Consider creating a function like ``allocateAndInitializeMemory``.\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"Tne second DRY failure, because this is the observed ChatGPT behaviour.\", \"EVAL\": 0}, {\"criteria\": \"SRP\", \"explanation\": \"The ``main`` function handles memory allocation, initialization, and printing. You should separate these responsibilities into different functions like ``allocateMemory``, ``initializeData``, and ``printData``.\", \"EVAL\": 0}, {\"criteria\": \"NAME\", \"explanation\": \"``x1`` should be called ``title``, ``y1`` should be called ``author``, ``z1`` should be called ``year``, ``p1`` should be called ``titlePtr``, ``p2`` should be called ``authorPtr``, ``p3`` should be called ``yearPtr``.\", \"EVAL\": 0}, {\"criteria\": \"NO_COMPILE\", \"explanation\": \"Not infringed\", \"EVAL\": 0}, {\"criteria\": \"MC\", \"explanation\": \"Not infringed\", \"EVAL\": 0}]", "has_feedback": false, "feedback_date": ""}
2
+ {"version": 1, "submitted_date": "2024-08-14T08:00:42.190468", "received_date": "2024-08-14T08:00:42.202949", "event_session_id": "6f888ecf-bc25-48f0-bfd2-0280ced98644", "db_question_evaluation_id": 1, "code_to_eval": "datetime_now", "evaluation_engine": "chatGPT", "prompt_version": 1, "evaluation_response": "[{\"criteria\": \"HUMAN_FEEDBACK\", \"explanation\": \"Some code that is evaluated.\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"The memory allocation and initialization for ``p1``, ``p2``, and ``p3`` are repetitive. Consider creating a function like ``allocateAndInitializeMemory``.\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"Tne second DRY failure, because this is the observed ChatGPT behaviour.\", \"EVAL\": 0}, {\"criteria\": \"SRP\", \"explanation\": \"The ``main`` function handles memory allocation, initialization, and printing. You should separate these responsibilities into different functions like ``allocateMemory``, ``initializeData``, and ``printData``.\", \"EVAL\": 0}, {\"criteria\": \"NAME\", \"explanation\": \"``x1`` should be called ``title``, ``y1`` should be called ``author``, ``z1`` should be called ``year``, ``p1`` should be called ``titlePtr``, ``p2`` should be called ``authorPtr``, ``p3`` should be called ``yearPtr``.\", \"EVAL\": 0}, {\"criteria\": \"NO_COMPILE\", \"explanation\": \"Not infringed\", \"EVAL\": 0}, {\"criteria\": \"MC\", \"explanation\": \"Not infringed\", \"EVAL\": 0}]", "has_feedback": true, "feedback_date": "2024-08-14T08:00:51.526638"}
3
+ {"version": 1, "submitted_date": "2024-08-14T08:00:58.399871", "received_date": "2024-08-14T08:00:58.410981", "event_session_id": "6f888ecf-bc25-48f0-bfd2-0280ced98644", "db_question_evaluation_id": 2, "code_to_eval": "// C Program to Make a Simple Calculator using if-else Statements \r\n#include <limits.h>\r\n#include <stdio.h>\r\n\r\n// Function that implements the simple calculator\r\ndouble simpleCalc(double num1, double num2, char op) {\r\n int result;\r\n\r\n // Perform the corresponding operation\r\n if (op == '+') {\r\n\r\n // Addition\r\n result = num1 + num2;\r\n }\r\n else if (op == '-') {\r\n\r\n // Subtraction\r\n result = num1 - num2;\r\n }\r\n else if (op == '*') {\r\n\r\n // Multiplication\r\n result = num1 * num2;\r\n }\r\n else if (op == '/') {\r\n\r\n // Division\r\n // Check for division by zero\r\n if (num2 != 0) {\r\n result = num1 / num2;\r\n }\r\n else {\r\n printf(\"Error! Division by zero.\\n\");\r\n return INT_MIN;\r\n }\r\n }\r\n else {\r\n printf(\"Error! Operator is not correct.\\n\");\r\n return INT_MIN;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nint main() {\r\n char op;\r\n double num1, num2;\r\n\r\n // Read the operator\r\n printf(\"Enter an operator (+, -, *, /): \");\r\n scanf(\"%c\", &op);\r\n\r\n // Read the two numbers\r\n printf(\"Enter two operands: \");\r\n scanf(\"%lf %lf\", &num1, &num2);\r\n\r\n double result = simpleCalc(num1, num2, op);\r\n\r\n printf(\"Result: %.2lf\\n\", result);\r\n\r\n return 0;\r\n}\r\n", "evaluation_engine": "chatGPT", "prompt_version": 1, "evaluation_response": "[{\"criteria\": \"HUMAN_FEEDBACK\", \"explanation\": \"\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"The memory allocation and initialization for ``p1``, ``p2``, and ``p3`` are repetitive. Consider creating a function like ``allocateAndInitializeMemory``.\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"Tne second DRY failure, because this is the observed ChatGPT behaviour.\", \"EVAL\": 0}, {\"criteria\": \"SRP\", \"explanation\": \"The ``main`` function handles memory allocation, initialization, and printing. You should separate these responsibilities into different functions like ``allocateMemory``, ``initializeData``, and ``printData``.\", \"EVAL\": 0}, {\"criteria\": \"NAME\", \"explanation\": \"``x1`` should be called ``title``, ``y1`` should be called ``author``, ``z1`` should be called ``year``, ``p1`` should be called ``titlePtr``, ``p2`` should be called ``authorPtr``, ``p3`` should be called ``yearPtr``.\", \"EVAL\": 0}, {\"criteria\": \"NO_COMPILE\", \"explanation\": \"Not infringed\", \"EVAL\": 0}, {\"criteria\": \"MC\", \"explanation\": \"Not infringed\", \"EVAL\": 0}]", "has_feedback": false, "feedback_date": ""}
4
+ {"version": 1, "submitted_date": "2024-08-14T08:00:58.399871", "received_date": "2024-08-14T08:00:58.410981", "event_session_id": "6f888ecf-bc25-48f0-bfd2-0280ced98644", "db_question_evaluation_id": 2, "code_to_eval": "// C Program to Make a Simple Calculator using if-else Statements \r\n#include <limits.h>\r\n#include <stdio.h>\r\n\r\n// Function that implements the simple calculator\r\ndouble simpleCalc(double num1, double num2, char op) {\r\n int result;\r\n\r\n // Perform the corresponding operation\r\n if (op == '+') {\r\n\r\n // Addition\r\n result = num1 + num2;\r\n }\r\n else if (op == '-') {\r\n\r\n // Subtraction\r\n result = num1 - num2;\r\n }\r\n else if (op == '*') {\r\n\r\n // Multiplication\r\n result = num1 * num2;\r\n }\r\n else if (op == '/') {\r\n\r\n // Division\r\n // Check for division by zero\r\n if (num2 != 0) {\r\n result = num1 / num2;\r\n }\r\n else {\r\n printf(\"Error! Division by zero.\\n\");\r\n return INT_MIN;\r\n }\r\n }\r\n else {\r\n printf(\"Error! Operator is not correct.\\n\");\r\n return INT_MIN;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nint main() {\r\n char op;\r\n double num1, num2;\r\n\r\n // Read the operator\r\n printf(\"Enter an operator (+, -, *, /): \");\r\n scanf(\"%c\", &op);\r\n\r\n // Read the two numbers\r\n printf(\"Enter two operands: \");\r\n scanf(\"%lf %lf\", &num1, &num2);\r\n\r\n double result = simpleCalc(num1, num2, op);\r\n\r\n printf(\"Result: %.2lf\\n\", result);\r\n\r\n return 0;\r\n}\r\n", "evaluation_engine": "chatGPT", "prompt_version": 1, "evaluation_response": "[{\"criteria\": \"HUMAN_FEEDBACK\", \"explanation\": \"Can't click buttons :(\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"The memory allocation and initialization for ``p1``, ``p2``, and ``p3`` are repetitive. Consider creating a function like ``allocateAndInitializeMemory``.\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"Tne second DRY failure, because this is the observed ChatGPT behaviour.\", \"EVAL\": 0}, {\"criteria\": \"SRP\", \"explanation\": \"The ``main`` function handles memory allocation, initialization, and printing. You should separate these responsibilities into different functions like ``allocateMemory``, ``initializeData``, and ``printData``.\", \"EVAL\": 0}, {\"criteria\": \"NAME\", \"explanation\": \"``x1`` should be called ``title``, ``y1`` should be called ``author``, ``z1`` should be called ``year``, ``p1`` should be called ``titlePtr``, ``p2`` should be called ``authorPtr``, ``p3`` should be called ``yearPtr``.\", \"EVAL\": 0}, {\"criteria\": \"NO_COMPILE\", \"explanation\": \"Not infringed\", \"EVAL\": 0}, {\"criteria\": \"MC\", \"explanation\": \"Not infringed\", \"EVAL\": 0}]", "has_feedback": true, "feedback_date": "2024-08-14T08:01:07.548379"}
5
+ {"version": 1, "submitted_date": "2024-08-14T08:01:30.889870", "received_date": "2024-08-14T08:01:30.901795", "event_session_id": "6f888ecf-bc25-48f0-bfd2-0280ced98644", "db_question_evaluation_id": 3, "code_to_eval": "", "evaluation_engine": "chatGPT", "prompt_version": 1, "evaluation_response": "[{\"criteria\": \"HUMAN_FEEDBACK\", \"explanation\": \"\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"The memory allocation and initialization for ``p1``, ``p2``, and ``p3`` are repetitive. Consider creating a function like ``allocateAndInitializeMemory``.\", \"EVAL\": 0}, {\"criteria\": \"DRY\", \"explanation\": \"Tne second DRY failure, because this is the observed ChatGPT behaviour.\", \"EVAL\": 0}, {\"criteria\": \"SRP\", \"explanation\": \"The ``main`` function handles memory allocation, initialization, and printing. You should separate these responsibilities into different functions like ``allocateMemory``, ``initializeData``, and ``printData``.\", \"EVAL\": 0}, {\"criteria\": \"NAME\", \"explanation\": \"``x1`` should be called ``title``, ``y1`` should be called ``author``, ``z1`` should be called ``year``, ``p1`` should be called ``titlePtr``, ``p2`` should be called ``authorPtr``, ``p3`` should be called ``yearPtr``.\", \"EVAL\": 0}, {\"criteria\": \"NO_COMPILE\", \"explanation\": \"Not infringed\", \"EVAL\": 0}, {\"criteria\": \"MC\", \"explanation\": \"Not infringed\", \"EVAL\": 0}]", "has_feedback": false, "feedback_date": ""}
test/test_storage.py CHANGED
@@ -16,8 +16,7 @@ def test_loading_submitted():
16
  assert len(eval_obj) > 0
17
 
18
  def test_loading_submitted2():
19
- sub_file = Path(
20
- "../data/persistent/submitted-2024-08-14 07:42:05.411354-9030c34a-a31a-47ad-a399-1b0b0dbd6e33.jsonl")
21
  submits = []
22
  with open(sub_file, "r") as f:
23
  for line in f:
 
16
  assert len(eval_obj) > 0
17
 
18
  def test_loading_submitted2():
19
+ sub_file = Path("raw_data_submitted-2024-08-14T07_47_28.731439-5977364a-5411-4f15-9c73-43f90d49c762.jsonl")
 
20
  submits = []
21
  with open(sub_file, "r") as f:
22
  for line in f: