Spaces:
Running
Running
User level for accessing different areas
Browse files
main.py
CHANGED
@@ -27,7 +27,7 @@ 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 |
-
|
31 |
|
32 |
LOCAL_STORAGE_PATH = ""
|
33 |
|
@@ -238,7 +238,7 @@ def html_create_feedback_updown_button(qe_id, ans_id, selected=0, disabled=False
|
|
238 |
return button_row
|
239 |
|
240 |
|
241 |
-
def html_augment_signle_evaluation_text_with_feedback(eval_html, qe_obj, ans_id):
|
242 |
"""
|
243 |
Will plot the + / - buttons for feedback.
|
244 |
|
@@ -248,8 +248,12 @@ def html_augment_signle_evaluation_text_with_feedback(eval_html, qe_obj, ans_id)
|
|
248 |
:return:
|
249 |
"""
|
250 |
answer_eval_js = json.loads(qe_obj.answer_eval_text)
|
251 |
-
|
|
|
252 |
disabled=(qe_obj.submitted == 1))
|
|
|
|
|
|
|
253 |
final_div = Div(eval_html, buttons,
|
254 |
style=" background-color: #f0f0f0; display: flex; "
|
255 |
"width: 98%; margin: 16px; padding: 3px; align-items: center;", cls="row")
|
@@ -317,6 +321,10 @@ def post(session, qe_id:int, freeform_feedback:str):
|
|
317 |
print("submit_feedback made session/object error")
|
318 |
return "Error"
|
319 |
|
|
|
|
|
|
|
|
|
320 |
# Update the object
|
321 |
session_id = session.get("session_id", "Not set")
|
322 |
save_to_storage(
|
@@ -339,12 +347,12 @@ def post(session, qe_id:int, freeform_feedback:str):
|
|
339 |
feedback_userdata=user_data)
|
340 |
)
|
341 |
|
342 |
-
return tl_html_results_and_feedback_area(
|
343 |
|
344 |
|
345 |
####### EVALUATE CODE
|
346 |
|
347 |
-
def html_format_code_review_form(qe_obj):
|
348 |
"""
|
349 |
Formats the code review, adding fields for feedback if it is required.
|
350 |
|
@@ -365,11 +373,14 @@ def html_format_code_review_form(qe_obj):
|
|
365 |
for k, eval_line in enumerate(enhanced_answer):
|
366 |
if caug_code == eval_line["criteria"]:
|
367 |
eval_txt = Div(P(eval_line["explanation"]), style="flex: 1; margin-right: 10px;", cls="box col-xs-11")
|
368 |
-
eval_txt_fb = html_augment_signle_evaluation_text_with_feedback(eval_txt, qe_obj, k)
|
369 |
eval_txt_fb_list.append(eval_txt_fb)
|
370 |
criteria_div = Div(*crit_tag, *eval_txt_fb_list, style="border: 1px solid black; margin: 10px; padding: 10px")
|
371 |
list_of_citerias.append(criteria_div)
|
372 |
-
|
|
|
|
|
|
|
373 |
return html_render_code_output(c_code), *list_of_citerias, textual_feedback
|
374 |
|
375 |
|
@@ -412,7 +423,7 @@ def get(session):
|
|
412 |
"""
|
413 |
if 'session_id' not in session: return "render_answer No session ID"
|
414 |
session_id = session["session_id"]
|
415 |
-
answer_area = tl_html_results_and_feedback_area(
|
416 |
return answer_area
|
417 |
|
418 |
|
@@ -436,8 +447,14 @@ def html_render_code_output(code):
|
|
436 |
return txtarea
|
437 |
|
438 |
|
439 |
-
def html_render_answer_from_db(
|
|
|
440 |
eval_request_status, state_obj = get_latest_eval_request_status(session_id)
|
|
|
|
|
|
|
|
|
|
|
441 |
# state_rows = session_state_table(limit=1, where=f"session_id == '{session_id}'", order_by="id DESC")
|
442 |
# print(eval_request_status, state_obj)
|
443 |
if eval_request_status == EVAL_STATE_NEW:
|
@@ -448,9 +465,9 @@ def html_render_answer_from_db(session_id, show_submit_form=True):
|
|
448 |
print(f"Object id {state_obj.current_qeval} can't be found in question_evaluation_table")
|
449 |
return (None,)
|
450 |
qe_obj = qe_obj_lst[0]
|
451 |
-
return (html_format_code_review_form(qe_obj),
|
452 |
-
|
453 |
-
|
454 |
if eval_request_status == EVAL_STATE_TIMEDOUT:
|
455 |
return html_eval_request_timed_out(),
|
456 |
if eval_request_status == EVAL_STATE_QUERY:
|
@@ -518,28 +535,59 @@ def call_gpt_and_store_result(session_obj_id, code_to_check):
|
|
518 |
traceback.print_exc()
|
519 |
|
520 |
|
521 |
-
def tl_html_results_and_feedback_area(
|
522 |
"""
|
523 |
Top level component that will render the code evaluation overlapped with feedback submission form.
|
524 |
|
525 |
:param session_id:
|
526 |
:return:
|
527 |
"""
|
528 |
-
results_feedback_area = html_render_answer_from_db(
|
529 |
return Div(*results_feedback_area, id=HTML_RESULTS_AREA)
|
530 |
|
531 |
|
|
|
532 |
######## CODE INPUT FORM
|
533 |
|
534 |
|
535 |
-
def
|
536 |
txtarea = Textarea(id="ccodetoeval", name="ccodetoeval", placeholder="Enter a piece of C code", rows=3)
|
537 |
form = Form(Group(txtarea, Button("Evaluate")),
|
538 |
hx_post="/submit_to_eval",
|
539 |
hx_swap="outerHTML",
|
540 |
target_id=f"{target_html_id}"
|
541 |
)
|
542 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
543 |
|
544 |
|
545 |
|
@@ -565,6 +613,29 @@ def render_clear_area(session_id, html_id):
|
|
565 |
return Div(P(""), id=html_id, hx_swap_oob='true')
|
566 |
|
567 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
568 |
########## AUTHENTICATION
|
569 |
|
570 |
def html_render_login_to_get_access_part(session):
|
@@ -756,6 +827,24 @@ def get(session):
|
|
756 |
session["user_data"] = None
|
757 |
return RedirectResponse(url="/")
|
758 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
759 |
########## MAIN PAGE
|
760 |
|
761 |
|
@@ -784,55 +873,13 @@ def get(session):
|
|
784 |
P("!! The data will be saved and maybe made public !!"),
|
785 |
]
|
786 |
|
787 |
-
input_area =
|
788 |
-
results_feedback_area = tl_html_results_and_feedback_area(
|
789 |
clear_area = render_clear_area(session_id, HTML_CLEAR_FORM)
|
790 |
# print(session)
|
791 |
return title, Main( *preamble, input_area, results_feedback_area, clear_area)
|
792 |
|
793 |
|
794 |
-
@rt("/submit_to_eval", methods="post")
|
795 |
-
def post(session, ccodetoeval:str):
|
796 |
-
# print(session)
|
797 |
-
if 'session_id' not in session:
|
798 |
-
return P("submit_to_eval. Bad call. No session ID")
|
799 |
-
session_id = session["session_id"]
|
800 |
-
session_obj = Session_State_cls(
|
801 |
-
session_id=session_id,
|
802 |
-
state=EVAL_STATE_QUERY,
|
803 |
-
submitted_date=datetime.isoformat(datetime.utcnow()),
|
804 |
-
)
|
805 |
-
save_to_storage(
|
806 |
-
storage.NavigationEvent(event_type="/submit_to_eval", event_session_id=session_id, event_params={"ccodetoeval":ccodetoeval})
|
807 |
-
)
|
808 |
-
|
809 |
-
# we insert and we get the new primary key
|
810 |
-
session_obj = session_state_table.insert(session_obj)
|
811 |
-
# will be executed in another thread with magic @threaded
|
812 |
-
call_gpt_and_store_result(session_obj.id, ccodetoeval)
|
813 |
-
return tl_html_results_and_feedback_area(session_id), render_clear_area(session_id, HTML_CLEAR_FORM)
|
814 |
-
|
815 |
|
816 |
-
@rt("/clear_area", methods="get")
|
817 |
-
def get(session):
|
818 |
-
if 'session_id' not in session: return P("clear_area. Bad call. No session ID")
|
819 |
-
session_id = session["session_id"]
|
820 |
-
|
821 |
-
save_to_storage(
|
822 |
-
storage.NavigationEvent(event_type="/clear_area", event_session_id=session_id)
|
823 |
-
)
|
824 |
-
|
825 |
-
# insert a row to "cancel"/reset the current request
|
826 |
-
session_obj = Session_State_cls(
|
827 |
-
session_id=session_id,
|
828 |
-
state=EVAL_STATE_NEW,
|
829 |
-
submitted_date=datetime.isoformat(datetime.utcnow()),
|
830 |
-
)
|
831 |
-
session_state_table.insert(session_obj)
|
832 |
-
# re-issue the page, basically.
|
833 |
-
input_area = html_render_inputbox(target_html_id=HTML_RESULTS_AREA, region_html_id=HTML_SUBMIT_CODE_AREA)
|
834 |
-
results_area = tl_html_results_and_feedback_area(session_id)
|
835 |
-
clear_area = render_clear_area(session_id, HTML_CLEAR_FORM)
|
836 |
-
return results_area, input_area, clear_area
|
837 |
|
838 |
serve()
|
|
|
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 |
+
DEFAULT_ANONYMOUS_USER_LEVEL = os.environ.get('DEFAULT_ANONYMOUS_USER_LEVEL', 0)
|
31 |
|
32 |
LOCAL_STORAGE_PATH = ""
|
33 |
|
|
|
238 |
return button_row
|
239 |
|
240 |
|
241 |
+
def html_augment_signle_evaluation_text_with_feedback(eval_html, qe_obj, ans_id, show_feedback_buttons=False):
|
242 |
"""
|
243 |
Will plot the + / - buttons for feedback.
|
244 |
|
|
|
248 |
:return:
|
249 |
"""
|
250 |
answer_eval_js = json.loads(qe_obj.answer_eval_text)
|
251 |
+
if show_feedback_buttons:
|
252 |
+
buttons = html_create_feedback_updown_button(qe_obj.id, ans_id, answer_eval_js[ans_id]["EVAL"],
|
253 |
disabled=(qe_obj.submitted == 1))
|
254 |
+
else:
|
255 |
+
buttons = Div("")
|
256 |
+
|
257 |
final_div = Div(eval_html, buttons,
|
258 |
style=" background-color: #f0f0f0; display: flex; "
|
259 |
"width: 98%; margin: 16px; padding: 3px; align-items: center;", cls="row")
|
|
|
321 |
print("submit_feedback made session/object error")
|
322 |
return "Error"
|
323 |
|
324 |
+
ulevel = get_user_level(session)
|
325 |
+
if ulevel < 2:
|
326 |
+
return P("Unauthorized. Log in to submit feedback.")
|
327 |
+
|
328 |
# Update the object
|
329 |
session_id = session.get("session_id", "Not set")
|
330 |
save_to_storage(
|
|
|
347 |
feedback_userdata=user_data)
|
348 |
)
|
349 |
|
350 |
+
return tl_html_results_and_feedback_area(session)
|
351 |
|
352 |
|
353 |
####### EVALUATE CODE
|
354 |
|
355 |
+
def html_format_code_review_form(qe_obj, show_feedback_buttons):
|
356 |
"""
|
357 |
Formats the code review, adding fields for feedback if it is required.
|
358 |
|
|
|
373 |
for k, eval_line in enumerate(enhanced_answer):
|
374 |
if caug_code == eval_line["criteria"]:
|
375 |
eval_txt = Div(P(eval_line["explanation"]), style="flex: 1; margin-right: 10px;", cls="box col-xs-11")
|
376 |
+
eval_txt_fb = html_augment_signle_evaluation_text_with_feedback(eval_txt, qe_obj, k, show_feedback_buttons)
|
377 |
eval_txt_fb_list.append(eval_txt_fb)
|
378 |
criteria_div = Div(*crit_tag, *eval_txt_fb_list, style="border: 1px solid black; margin: 10px; padding: 10px")
|
379 |
list_of_citerias.append(criteria_div)
|
380 |
+
if show_feedback_buttons:
|
381 |
+
textual_feedback = html_get_textual_feedback_form(qe_obj)
|
382 |
+
else:
|
383 |
+
textual_feedback = P("Log in to leave some feedback about this evaluation")
|
384 |
return html_render_code_output(c_code), *list_of_citerias, textual_feedback
|
385 |
|
386 |
|
|
|
423 |
"""
|
424 |
if 'session_id' not in session: return "render_answer No session ID"
|
425 |
session_id = session["session_id"]
|
426 |
+
answer_area = tl_html_results_and_feedback_area(session)
|
427 |
return answer_area
|
428 |
|
429 |
|
|
|
447 |
return txtarea
|
448 |
|
449 |
|
450 |
+
def html_render_answer_from_db(session, show_submit_form=True):
|
451 |
+
session_id = session["session_id"]
|
452 |
eval_request_status, state_obj = get_latest_eval_request_status(session_id)
|
453 |
+
ulevel = get_user_level(session)
|
454 |
+
if ulevel >= 2:
|
455 |
+
show_feedback_buttons = True
|
456 |
+
else:
|
457 |
+
show_feedback_buttons = False
|
458 |
# state_rows = session_state_table(limit=1, where=f"session_id == '{session_id}'", order_by="id DESC")
|
459 |
# print(eval_request_status, state_obj)
|
460 |
if eval_request_status == EVAL_STATE_NEW:
|
|
|
465 |
print(f"Object id {state_obj.current_qeval} can't be found in question_evaluation_table")
|
466 |
return (None,)
|
467 |
qe_obj = qe_obj_lst[0]
|
468 |
+
return (html_format_code_review_form(qe_obj, show_feedback_buttons),
|
469 |
+
tl_html_render_inputbox(session, target_html_id=HTML_RESULTS_AREA,
|
470 |
+
region_html_id=HTML_SUBMIT_CODE_AREA) if show_submit_form else None)
|
471 |
if eval_request_status == EVAL_STATE_TIMEDOUT:
|
472 |
return html_eval_request_timed_out(),
|
473 |
if eval_request_status == EVAL_STATE_QUERY:
|
|
|
535 |
traceback.print_exc()
|
536 |
|
537 |
|
538 |
+
def tl_html_results_and_feedback_area(session, show_submit_form=True):
|
539 |
"""
|
540 |
Top level component that will render the code evaluation overlapped with feedback submission form.
|
541 |
|
542 |
:param session_id:
|
543 |
:return:
|
544 |
"""
|
545 |
+
results_feedback_area = html_render_answer_from_db(session, show_submit_form)
|
546 |
return Div(*results_feedback_area, id=HTML_RESULTS_AREA)
|
547 |
|
548 |
|
549 |
+
|
550 |
######## CODE INPUT FORM
|
551 |
|
552 |
|
553 |
+
def tl_html_render_inputbox(session, target_html_id, region_html_id):
|
554 |
txtarea = Textarea(id="ccodetoeval", name="ccodetoeval", placeholder="Enter a piece of C code", rows=3)
|
555 |
form = Form(Group(txtarea, Button("Evaluate")),
|
556 |
hx_post="/submit_to_eval",
|
557 |
hx_swap="outerHTML",
|
558 |
target_id=f"{target_html_id}"
|
559 |
)
|
560 |
+
|
561 |
+
ulevel = get_user_level(session)
|
562 |
+
if ulevel < 1:
|
563 |
+
form = P("Log in to submit code to review.", style="background-color: #fff0f0;")
|
564 |
+
out_div = Div(form, id=region_html_id, hx_swap_oob='true')
|
565 |
+
return out_div
|
566 |
+
|
567 |
+
|
568 |
+
@rt("/submit_to_eval", methods="post")
|
569 |
+
def post(session, ccodetoeval:str):
|
570 |
+
# print(session)
|
571 |
+
ulevel = get_user_level(session)
|
572 |
+
if ulevel < 1:
|
573 |
+
return P("Unauthorized. Log in to submit code to review.", style="background-color: #fff0f0;")
|
574 |
+
if 'session_id' not in session:
|
575 |
+
return P("submit_to_eval. Bad call. No session ID")
|
576 |
+
session_id = session["session_id"]
|
577 |
+
session_obj = Session_State_cls(
|
578 |
+
session_id=session_id,
|
579 |
+
state=EVAL_STATE_QUERY,
|
580 |
+
submitted_date=datetime.isoformat(datetime.utcnow()),
|
581 |
+
)
|
582 |
+
save_to_storage(
|
583 |
+
storage.NavigationEvent(event_type="/submit_to_eval", event_session_id=session_id, event_params={"ccodetoeval":ccodetoeval})
|
584 |
+
)
|
585 |
+
|
586 |
+
# we insert and we get the new primary key
|
587 |
+
session_obj = session_state_table.insert(session_obj)
|
588 |
+
# will be executed in another thread with magic @threaded
|
589 |
+
call_gpt_and_store_result(session_obj.id, ccodetoeval)
|
590 |
+
return tl_html_results_and_feedback_area(session), render_clear_area(session_id, HTML_CLEAR_FORM)
|
591 |
|
592 |
|
593 |
|
|
|
613 |
return Div(P(""), id=html_id, hx_swap_oob='true')
|
614 |
|
615 |
|
616 |
+
@rt("/clear_area", methods="get")
|
617 |
+
def get(session):
|
618 |
+
if 'session_id' not in session: return P("clear_area. Bad call. No session ID")
|
619 |
+
session_id = session["session_id"]
|
620 |
+
|
621 |
+
save_to_storage(
|
622 |
+
storage.NavigationEvent(event_type="/clear_area", event_session_id=session_id)
|
623 |
+
)
|
624 |
+
|
625 |
+
# insert a row to "cancel"/reset the current request
|
626 |
+
session_obj = Session_State_cls(
|
627 |
+
session_id=session_id,
|
628 |
+
state=EVAL_STATE_NEW,
|
629 |
+
submitted_date=datetime.isoformat(datetime.utcnow()),
|
630 |
+
)
|
631 |
+
session_state_table.insert(session_obj)
|
632 |
+
# re-issue the page, basically.
|
633 |
+
input_area = tl_html_render_inputbox(session, target_html_id=HTML_RESULTS_AREA, region_html_id=HTML_SUBMIT_CODE_AREA)
|
634 |
+
results_area = tl_html_results_and_feedback_area(session)
|
635 |
+
clear_area = render_clear_area(session_id, HTML_CLEAR_FORM)
|
636 |
+
return results_area, input_area, clear_area
|
637 |
+
|
638 |
+
|
639 |
########## AUTHENTICATION
|
640 |
|
641 |
def html_render_login_to_get_access_part(session):
|
|
|
827 |
session["user_data"] = None
|
828 |
return RedirectResponse(url="/")
|
829 |
|
830 |
+
|
831 |
+
def get_user_level(session):
|
832 |
+
"""
|
833 |
+
Gets the user rights level. Basically 0 for not logged in, 2 for logged in.
|
834 |
+
The DEFAULT_ANONYMOUS_USER_LEVEL can raise this level (max operation)
|
835 |
+
|
836 |
+
:param session:
|
837 |
+
:return:
|
838 |
+
"""
|
839 |
+
ulevel = 0
|
840 |
+
if session[USER_DATA_SESSION_NAME] is not None:
|
841 |
+
ulevel = 2
|
842 |
+
ulevel = max(ulevel, DEFAULT_ANONYMOUS_USER_LEVEL)
|
843 |
+
|
844 |
+
return ulevel
|
845 |
+
|
846 |
+
|
847 |
+
|
848 |
########## MAIN PAGE
|
849 |
|
850 |
|
|
|
873 |
P("!! The data will be saved and maybe made public !!"),
|
874 |
]
|
875 |
|
876 |
+
input_area = tl_html_render_inputbox(session, target_html_id=HTML_RESULTS_AREA, region_html_id=HTML_SUBMIT_CODE_AREA)
|
877 |
+
results_feedback_area = tl_html_results_and_feedback_area(session, show_submit_form=False)
|
878 |
clear_area = render_clear_area(session_id, HTML_CLEAR_FORM)
|
879 |
# print(session)
|
880 |
return title, Main( *preamble, input_area, results_feedback_area, clear_area)
|
881 |
|
882 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
883 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
884 |
|
885 |
serve()
|