#4544 Folder-Based Prompt and Response Workflow

#4544 Folder-Based Prompt and Response Workflow

#4544 Provide a python application method that reads a text file from a specified folder, applies an AI prompt to that text content, submits the prompt to a Google Gemini LLM, and writes the response to a text file in another specified folder.

Below, you'll find a clean, modular Python script using the official Google GenAI SDK (google-genai) to read a file, process it with Gemini, and save the output.

Prerequisites

First, make sure you have the correct, current SDK installed:

pip install google-genai

You also need to set your Gemini API key as an environment variable.

  • Linux/macOS: export GEMINI_API_KEY="your-api-key-here"

  • Windows (CMD): set GEMINI_API_KEY="your-api-key-here"

  • Windows (PowerShell): $env:GEMINI_API_KEY="your-api-key-here"

Python Script

import os
from pathlib import Path
from google import genai
from google.genai import types

def process_text_with_gemini(
    input_folder: str,
    output_folder: str,
    filename: str,
    ai_prompt: str,
    model_name: str = "gemini-2.5-flash"
):
    """
    Reads a text file, appends an AI prompt, sends it to Gemini, 
    and writes the response to a new file.
    """
    # 1. Setup paths
    input_path = Path(input_folder) / filename
    output_path = Path(output_folder) / f"processed_{filename}"
    
    # Ensure output directory exists
    Path(output_folder).mkdir(parents=True, exist_ok=True)
    
    # 2. Read the input file
    try:
        with open(input_path, 'file_reading', encoding='utf-8') as f:
            file_content = f.read()
    except FileNotFoundError:
        print(f"Error: The file {input_path} was not found.")
        return
    except Exception as e:
        print(f"Error reading file: {e}")
        return

    # 3. Combine the prompt and the file content
    # Using system instructions is often best for guiding the AI's behavior
    full_content = f"{ai_prompt}\n\n--- TEXT CONTENT ---\n{file_content}"
    
    print(f"Sending content to {model_name}...")

    # 4. Initialize the Gemini client and generate content
    # The client automatically picks up the GEMINI_API_KEY environment variable
    try:
        client = genai.Client()
        response = client.models.generate_content(
            model=model_name,
            contents=full_content,
        )
        
        # 5. Write the response to the output folder
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(response.text)
            
        print(f"Success! Response written to: {output_path}")
        
    except Exception as e:
        print(f"An error occurred during API call or writing: {e}")

# --- Example Usage ---
if __name__ == "__main__":
    # Define your folders and files
    IN_DIR = "./input_documents"
    OUT_DIR = "./output_results"
    FILE_TO_READ = "sample.txt"
    
    PROMPT = "Summarize the following text in three bullet points, then list the top 3 action items."
    
    # (Optional) Create a dummy file for testing if you don't have one
    Path(IN_DIR).mkdir(parents=True, exist_ok=True)
    with open(Path(IN_DIR) / FILE_TO_READ, 'w', encoding='utf-8') as f:
        f.write("Project Titan is running behind schedule. The design team needs to approve the blueprints by Friday. "
                "Marketing requires the asset list by next Tuesday so they can prep the campaign. "
                "Budget approvals are still pending from Sarah.")

    # Run the application method
    process_text_with_gemini(
        input_folder=IN_DIR,
        output_folder=OUT_DIR,
        filename=FILE_TO_READ,
        ai_prompt=PROMPT
    )

Key Highlights of this Implementation

  • Modern SDK: It utilizes the updated google-genai library and the genai.Client() syntax.

  • Robust Pathing: Uses Python's built-in pathlib to handle directory creation and file paths safely across different operating systems (Windows vs. Mac/Linux).

  • Model Choice: It defaults to gemini-2.5-flash, which is ideal, fast, and cost-effective for general text processing and summarization tasks.

  • Encoding Safety: Explicitly opens files using encoding='utf-8' to prevent erratic crashes when reading special characters or emojis.


Provide a driving routine to get the list of text files in a specified directory and calls the process_text_with_gemini() method

Here is the driving routine to scale up your script. This addition will scan a specified directory, filter for text files, and loop through them to call your process_text_with_gemini function.

I have also fixed a tiny typo from the previous script (changing 'file_reading' to 'r' in the file open mode) so everything runs flawlessly.

Updated Python Script with Batch Processing

import os
from pathlib import Path
from google import genai

def process_text_with_gemini(
    input_folder: str,
    output_folder: str,
    filename: str,
    ai_prompt: str,
    model_name: str = "gemini-2.5-flash"
):
    """
    Reads a single text file, appends an AI prompt, sends it to Gemini, 
    and writes the response to a new file.
    """
    input_path = Path(input_folder) / filename
    output_path = Path(output_folder) / f"processed_{filename}"
    
    Path(output_folder).mkdir(parents=True, exist_ok=True)
    
    try:
        # Fixed 'file_reading' typo to standard 'r' mode
        with open(input_path, 'r', encoding='utf-8') as f:
            file_content = f.read()
    except Exception as e:
        print(f"  [Error] Skipping {filename} - Could not read file: {e}")
        return

    full_content = f"{ai_prompt}\n\n--- TEXT CONTENT ---\n{file_content}"
    
    try:
        client = genai.Client()
        response = client.models.generate_content(
            model=model_name,
            contents=full_content,
        )
        
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(response.text)
            
        print(f"  [Success] Saved response to: {output_path.name}")
        
    except Exception as e:
        print(f"  [Error] Failed to process {filename} via API: {e}")


def batch_process_folder(input_folder: str, output_folder: str, ai_prompt: str):
    """
    Drives the application: Finds all .txt files in the input folder
    and processes them one by one.
    """
    input_path = Path(input_folder)
    
    # 1. Ensure the input directory actually exists
    if not input_path.exists() or not input_path.is_dir():
        print(f"Error: Input directory '{input_folder}' does not exist.")
        return

    # 2. Find all text files (.txt). Use *.txt for just text files, or * for everything.
    # .glob() is case-insensitive on Windows, but case-sensitive on Linux/Mac. 
    # To catch .TXT as well, you can use rglob or list comprehensions.
    text_files = list(input_path.glob("*.txt"))
    
    if not text_files:
        print(f"No .txt files found in '{input_folder}'.")
        return
        
    print(f"Found {len(text_files)} file(s) to process.\n" + "="*40)

    # 3. Iterate through the files and call the Gemini processor
    for file_path in text_files:
        print(f"Processing: {file_path.name}...")
        
        process_text_with_gemini(
            input_folder=input_folder,
            output_folder=output_folder,
            filename=file_path.name,
            ai_prompt=ai_prompt
        )
        print("-" * 40)
        
    print("Batch processing complete!")


# --- Example Usage ---
if __name__ == "__main__":
    IN_DIR = "./input_documents"
    OUT_DIR = "./output_results"
    PROMPT = "Summarize the key points of this document and list any actionable tasks."
    
    # Optional: Setup mock files for a quick test run
    Path(IN_DIR).mkdir(parents=True, exist_ok=True)
    with open(Path(IN_DIR) / "notes1.txt", 'w', encoding='utf-8') as f:
        f.write("Meet with design team on Wednesday to review wireframes.")
    with open(Path(IN_DIR) / "notes2.txt", 'w', encoding='utf-8') as f:
        f.write("Send invoice to client by Friday afternoon.")

    # Run the driver routine
    batch_process_folder(
        input_folder=IN_DIR,
        output_folder=OUT_DIR,
        ai_prompt=PROMPT
    )

Efficiency Tips for Large Folders

  • Rate Limits: If you are processing dozens of files simultaneously on a free-tier API key, you might hit rate limits. If you experience 429 (Too Many Requests) errors, import Python's time module and add a brief pause (time.sleep(2)) at the end of the loop.

  • File Extensions: If your text files have extensions other than .txt (like .md or .log), you can adjust input_path.glob("*.txt") accordingly.


Note that the driver should also read a single prompt file (.prompt) from the specified input folder and pass that prompt to the process_text_with_gemini() method

Here is the updated driving routine. It now looks for a single .prompt file within the input folder first, reads its content, and uses that dynamically for all the text files it processes.

If it can't find a .prompt file, it will gracefully fall back to a default prompt so your script doesn't crash.

Updated Python Script

import os
from pathlib import Path
from google import genai

def process_text_with_gemini(
    input_folder: str,
    output_folder: str,
    filename: str,
    ai_prompt: str,
    model_name: str = "gemini-2.5-flash"
):
    """
    Reads a single text file, appends an AI prompt, sends it to Gemini, 
    and writes the response to a new file.
    """
    input_path = Path(input_folder) / filename
    output_path = Path(output_folder) / f"processed_{filename}"
    
    Path(output_folder).mkdir(parents=True, exist_ok=True)
    
    try:
        with open(input_path, 'r', encoding='utf-8') as f:
            file_content = f.read()
    except Exception as e:
        print(f"  [Error] Skipping {filename} - Could not read file: {e}")
        return

    full_content = f"{ai_prompt}\n\n--- TEXT CONTENT ---\n{file_content}"
    
    try:
        client = genai.Client()
        response = client.models.generate_content(
            model=model_name,
            contents=full_content,
        )
        
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(response.text)
            
        print(f"  [Success] Saved response to: {output_path.name}")
        
    except Exception as e:
        print(f"  [Error] Failed to process {filename} via API: {e}")


def batch_process_folder(input_folder: str, output_folder: str, fallback_prompt: str):
    """
    Drives the application: Finds a .prompt file to use, then processes 
    all .txt files in the input folder using that prompt.
    """
    input_path = Path(input_folder)
    
    if not input_path.exists() or not input_path.is_dir():
        print(f"Error: Input directory '{input_folder}' does not exist.")
        return

    # 1. Look for a .prompt file in the directory
    prompt_files = list(input_path.glob("*.prompt"))
    active_prompt = fallback_prompt

    if prompt_files:
        # Use the first .prompt file found
        selected_prompt_file = prompt_files[0]
        try:
            with open(selected_prompt_file, 'r', encoding='utf-8') as f:
                active_prompt = f.read().strip()
            print(f"Using prompt from file: '{selected_prompt_file.name}'")
        except Exception as e:
            print(f"Warning: Could not read prompt file ({e}). Using fallback prompt.")
    else:
        print(f"No .prompt file found. Using default fallback prompt.")

    print(f"Active Prompt: \"{active_prompt[:50]}...\"")
    print("-" * 40)

    # 2. Find all text files (.txt)
    text_files = list(input_path.glob("*.txt"))
    
    if not text_files:
        print(f"No .txt files found in '{input_folder}'.")
        return
        
    print(f"Found {len(text_files)} file(s) to process.\n" + "="*40)

    # 3. Iterate through the files and call the Gemini processor
    for file_path in text_files:
        print(f"Processing: {file_path.name}...")
        
        process_text_with_gemini(
            input_folder=input_folder,
            output_folder=output_folder,
            filename=file_path.name,
            ai_prompt=active_prompt
        )
        print("-" * 40)
        
    print("Batch processing complete!")


# --- Example Usage ---
if __name__ == "__main__":
    IN_DIR = "./input_documents"
    OUT_DIR = "./output_results"
    
    # This acts as a backup in case instructions.prompt doesn't exist
    DEFAULT_FALLBACK_PROMPT = "Summarize the key points of this document."
    
    # Optional: Setup mock files including the .prompt file for a test run
    Path(IN_DIR).mkdir(parents=True, exist_ok=True)
    
    # Creating the prompt file
    with open(Path(IN_DIR) / "instructions.prompt", 'w', encoding='utf-8') as f:
        f.write("Analyze the following text. Provide a 2-sentence summary followed by a list of metadata entities mentioned.")
        
    # Creating a sample text file
    with open(Path(IN_DIR) / "report.txt", 'w', encoding='utf-8') as f:
        f.write("ACME Corp quarterly review. CEO Jane Doe announced a 12% revenue growth in Texas. "
                "The engineering team deployed the new cloud infrastructure on AWS.")

    # Run the driver routine
    batch_process_folder(
        input_folder=IN_DIR,
        output_folder=OUT_DIR,
        fallback_prompt=DEFAULT_FALLBACK_PROMPT
    )

What Changed?

  • Prompt Detection: prompt_files = list(input_path.glob("*.prompt")) scans the directory for files ending in .prompt.

  • Dynamic Assignment: If found, it safely opens prompt_files[0], reads the instruction set, and assigns it to active_prompt to override the default text string.

  • Bulletproof Fallback: If you delete or misplace the .prompt file, the script won't crash—it will just let you know it's reverting to your hardcoded fallback_prompt.


NOTE TO SELF: The original text file should be deleted following successful writing of the new files to the specified output folder.


From <https://gemini.google.com/app/>  Google Gemini (3.5 Flash)

Comments

Popular posts from this blog

#3679 Google Gemini 2.5 Pro: Create Python Application to View and Query Neo4j KG

#4054 AI Agents in AI Studio