import os import gradio as gr from weasyprint import HTML # Use WeasyPrint for HTML to PDF from huggingface_hub import InferenceClient from huggingface_hub.utils import HfHubHTTPError import requests # --- Configuration --- HF_TOKEN = os.getenv("HF_TOKEN") if not HF_TOKEN: raise ValueError("The HF_TOKEN environment variable must be set.") MODEL_NAME = "meta-llama/Llama-3.1-8B-Instruct" MAX_INPUT_LENGTH = 4096 # Maximum characters for lesson content # --- Hugging Face Inference Client --- client = InferenceClient(model=MODEL_NAME, token=HF_TOKEN) # Corrected: Use model and token def call_hf_api(lesson_text: str) -> str: """ Calls the Hugging Face Inference API, generating exercises in SPANISH. """ if not lesson_text.strip(): return "Please provide lesson content." if len(lesson_text) > MAX_INPUT_LENGTH: return f"Error: Lesson content is too long (>{MAX_INPUT_LENGTH} characters). Please shorten it." prompt = f""" You are a helpful assistant that generates structured HSK exercises in HTML format. Use ONLY the following lesson content to create the exercises. Do NOT hallucinate any content. The generated exercises, including all instructions within each exercise, section titles, and questions, MUST be in SPANISH. USER INPUT Lesson Content YOU MUST USE FOR CUSTOMIZING THE EXERCICES OF THE HTML TEMPLATE: {lesson_text} Generate exactly 12 exercise sections in HTML, as shown in the example below. The exercises MUST use the vocabulary and grammar points from the lesson content provided above. Do not include an answer key. Example HTML Output Structure (use this EXACT structure, adapt exercise TYPES and content, and generate content in SPANISH, ACCORDING TO THE INPUT):
Total de 12 Secciones - La última es escritura.
Completa las siguientes oraciones con la palabra correcta del recuadro.
[Palabras del recuadro: (Palabras relevantes de la lección)]
Ordena las siguientes palabras para formar oraciones coherentes.
Elige la opción correcta para completar cada oración.
Traduce las siguientes frases al chino.
Empareja las palabras de la columna A con sus significados en la columna B.
Escribe los siguientes caracteres en los recuadros.
Completa el siguiente diálogo con las frases apropiadas.
A: ______
B: Me llamo Li Hua.
Responde las siguientes preguntas en español.
Indica si las siguientes afirmaciones son verdaderas (V) o falsas (F).
Describe la siguiente imagen en una oración.
[Espacio para la imagen, o una descripción si no se puede incluir la imagen]
[ ]
Corrige los errores en las siguientes oraciones.
Escribe un párrafo corto (aproximadamente 50-80 palabras) en chino sobre un tema relacionado con la lección. Usa el vocabulario y las estructuras gramaticales que has aprendido.
[Espacio para escribir]
— Fin de la Hoja de Ejercicios —
Do NOT include any other text outside of the HTML. Output ONLY the HTML. The HTML MUST be different and adapted to the content provided in the `lesson_text` variable. The example serves as a template of the STRUCTURE and TYPES OF EXERCISES. The content MUST be in SPANISH, and related to lesson_text """ messages = [ { "role": "user", "content": prompt, } ] try: # Corrected: Use the text-generation task and pass messages directly generated_text = client.text_generation( prompt=prompt, max_new_tokens=2000, temperature=0.7, top_p=0.9, stop_sequences=["```"], ) # HTML Cleanup: if "```html" in generated_text: generated_text = generated_text.split("```html")[1] if "```" in generated_text: generated_text = generated_text.split("```")[0] return generated_text except HfHubHTTPError as e: return f"Error from Hugging Face Hub: {e}" except requests.exceptions.RequestException as e: return f"Network or API error: {e}" except Exception as e: return f"An unexpected error occurred: {e}" def generate_exercises(lesson_text: str) -> str: """Generates exercises in HTML format.""" return call_hf_api(lesson_text) def create_pdf(exercises_text: str) -> str: """Creates a PDF from the generated HTML exercises.""" if not exercises_text.strip(): return None try: output_filename = "hsk_exercises.pdf" HTML(string=exercises_text).write_pdf(output_filename) return output_filename except Exception as e: return f"Error during PDF generation: {e}" def copy_text(exercises_text: str) -> str: """Copies the generated HTML to the clipboard (for display purposes).""" if not exercises_text.strip(): return "No text to copy!" return exercises_text # --- Gradio Interface --- with gr.Blocks(title="HSK Exercise Generator", theme=gr.themes.Soft()) as demo: gr.Markdown("# HSK Exercise Generator") gr.Markdown("Paste your lesson content and generate structured HSK exercises.") with gr.Row(): lesson_input = gr.Textbox( lines=10, label="Lesson Content", placeholder=f"Paste lesson content here (max {MAX_INPUT_LENGTH} characters)...", ) generate_btn = gr.Button("Generate Exercises") output_html = gr.HTML(label="Generated Exercises") # Use gr.HTML for HTML output with gr.Row(): download_btn = gr.Button("Download as PDF") copy_btn = gr.Button("Copy Text") copy_notice = gr.Textbox( label="Copy/Status", placeholder="Shows copied text or status here.", interactive=False, ) generate_btn.click(generate_exercises, inputs=lesson_input, outputs=output_html) download_btn.click(create_pdf, inputs=output_html, outputs=gr.File()) copy_btn.click(copy_text, inputs=output_html, outputs=copy_notice) gr.Markdown( """ Usage: 1. Set your Hugging Face token: `export HF_TOKEN=hf_yourRealToken` 2. Install required packages: `pip install gradio huggingface_hub requests weasyprint` 3. Run the script: `python exercise_generator.py` 4. Open the provided local URL in your browser. 5. Paste your lesson content (make sure it's not too long). 6. Click "Generate Exercises". 7. The generated exercises (in Spanish) will appear in the output area. 8. You can then download them as a PDF or copy the text. """ ) if __name__ == "__main__": demo.launch()