from __future__ import annotations from pathlib import Path import gradio as gr from typing import Any, Callable import contextvars from uw_programmatic.uw_machine import UWMachine from dotenv import load_dotenv import os def run_with_context(func: Callable) -> Callable: ctx = contextvars.copy_context() def wrapper(*args, **kwargs) -> Any: return ctx.run(func, *args, **kwargs) return wrapper def generate_questions( page_lower, page_higher, question_number, taxonomy ) -> tuple[str, dict[str, Any]]: if machine.value and machine.value.current_state_value == "start": machine.value.start_machine() # Start the machine! if not question_number or question_number <= 0: msg = "Choose a valid question number." raise gr.Error(msg) if not page_lower or not page_higher or page_higher < page_lower: msg = "Choose a valid page range." raise gr.Error(msg) if page_higher - page_lower <= 6: msg = "Page range must be >6." raise gr.Error(msg) if not taxonomy or len(taxonomy) == 0: msg = "Choose at least one taxonomy." raise gr.Error(msg) try: machine.value.send( "process_event", event_={ "type": "user_input", "value": { "page_range": (page_lower, page_higher), "question_number": question_number, "taxonomy": taxonomy, }, }, ) except AttributeError: create_statemachine() machine.value.start_machine() machine.value.send( "process_event", event_={ "type": "user_input", "value": { "page_range": (page_lower, page_higher), "question_number": question_number, "taxonomy": taxonomy, }, }, ) button = gr.update( visible=True, value=f"{Path.cwd().joinpath('outputs/professor_guide.csv')}", ) markdown = "## Questions Ready for Download Below" if machine.value.errored: button = gr.update() markdown = "## Questions Not Ready for Download" exception = "Bad Page Range Selected" raise gr.Error(exception) return (markdown, button) def create_statemachine() -> None: # Creates GoapMachine from the config.yaml in current directory cwd_path = Path.cwd() / "uw_programmatic" config_path = cwd_path.joinpath(Path("config.yaml")) try: machine.value = UWMachine.from_config_file(config_path) except Exception as e: raise gr.Error(str(e)) from e def questions_downloaded() -> dict[str, Any]: return gr.update(interactive=True, visible=True) with gr.Blocks() as demo: gr.Markdown("# UW Quiz Generator") machine = gr.State(value=None) with gr.Row(): with gr.Column(scale=2): taxonomy = gr.CheckboxGroup( choices=["Knowledge", "Comprehension", "Application"], label="Taxonomy", value="Knowledge", ) question_number = gr.Number( minimum=1, maximum=25, label="Number of Questions", value=3 ) gr.Markdown("For Textbook - Pages 1-348") with gr.Row(): page_lower = gr.Number( label="First Page", minimum=1, value=1, maximum=348 ) page_higher = gr.Number( label="Last Page", minimum=1, value=348, maximum=348 ) start_button = gr.Button(value="Generate Questions", scale=1) with gr.Column(scale=1): output = gr.Markdown("## Questions Not Ready for Download", visible=True) download_professor = gr.DownloadButton( label="Download Questions", visible=False, scale=1 ) create_statemachine() start_button.click( fn=run_with_context(generate_questions), inputs=[page_lower, page_higher, question_number, taxonomy], outputs=[output, download_professor], ) download_professor.click( fn=run_with_context(questions_downloaded), outputs=[start_button] ) load_dotenv() demo.launch( share=True, ssr_mode=False, auth=(os.environ.get("HF_USERNAME", ""), os.environ.get("HF_PASSWORD", "")), ) # demo.launch()