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): CHINOTOTAL - Lección [Número de Lección]

CHINOTOTAL - Lección [Número de Lección]

Ejercicios Completos

Total de 12 Secciones - La última es escritura.


Sección 1: Completa los Espacios en Blanco

Completa las siguientes oraciones con la palabra correcta del recuadro.

[Palabras del recuadro: (Palabras relevantes de la lección)]

  1. El ______ está en la mesa. (libro, silla, comida)
  2. Me gusta ______ música. (escuchar, hablar, comer)

Sección 2: Ordena las Oraciones

Ordena las siguientes palabras para formar oraciones coherentes.

  1. / libro / el / es / dónde /
  2. / gusta / me / mucho / este / restaurante /

Sección 3: Opción Múltiple

Elige la opción correcta para completar cada oración.

  1. Voy ______ la biblioteca. (a, en, de)
  2. ______ es tu nombre? (Cómo, Qué, Quién)

Sección 4: Traducción

Traduce las siguientes frases al chino.

  1. I like to read books.
  2. Where is the bathroom?

Sección 5: Emparejar

Empareja las palabras de la columna A con sus significados en la columna B.

  1. [Palabra 1] A. [Significado A]
  2. [Palabra 2] B. [Significado B]

Sección 6: Escritura de Caracteres

Escribe los siguientes caracteres en los recuadros.

  1. [Caracter 1] [Recuadro para escribir]
  2. [Caracter 2] [Recuadro para escribir]

Sección 7: Completa el Diálogo

Completa el siguiente diálogo con las frases apropiadas.

A: ______
B: Me llamo Li Hua.

  1. ¿Cómo te llamas?
  2. ¿De dónde eres?

Sección 8: Respuesta Corta

Responde las siguientes preguntas en español.

  1. ¿Qué te gusta hacer en tu tiempo libre?
  2. ¿Cuál es tu comida favorita?

Sección 9: Verdadero/Falso

Indica si las siguientes afirmaciones son verdaderas (V) o falsas (F).

  1. [Afirmación 1] (V/F)
  2. [Afirmación 2] (V/F)

Sección 10: Descripción de Imagen

Describe la siguiente imagen en una oración.

[Espacio para la imagen, o una descripción si no se puede incluir la imagen]

[ ]


Sección 11: Corrección de Errores

Corrige los errores en las siguientes oraciones.

  1. Yo gusta leer libro.
  2. El dónde es el baño.

Sección 12: Ejercicio de Escritura

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()