#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-genailibrary and thegenai.Client()syntax.Robust Pathing: Uses Python's built-in
pathlibto 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'stimemodule 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.mdor.log), you can adjustinput_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 toactive_promptto override the default text string.Bulletproof Fallback: If you delete or misplace the
.promptfile, the script won't crash—it will just let you know it's reverting to your hardcodedfallback_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
Post a Comment