RoutePlannerApp / app.py
ArielKes's picture
removed redundant text box
812bee8
Raw History Blame Contribute Delete
3.9 kB
import os
import gradio as gr
import pandas as pd
from geolocation_apis import addresses_to_coordinates, coordinates_to_route
from pdf_parser import process_pdf_hebrew_rtl
from llm_api import llm_parser
from map_visualize import generate_route_map
def summarize_items(items):
"""
Returns a preview list for the dataset component.
"""
return [
[
f"{i + 1}. [{item['source']}] " + (
os.path.basename(item['file'].name) if item['source'] == 'PDF' else item['content'][:40]
) + "..."
]
for i, item in enumerate(items)
]
def add_files(files, items):
"""
Adds uploaded PDF file objects to the state.
"""
new_items = [{"source": "PDF", "file": f} for f in files]
items += new_items
return items, gr.update(samples=summarize_items(items))
def add_text(text, items):
"""
Adds pasted text content to the state.
"""
if text.strip():
items.append({"source": "Paste", "content": text.strip()})
return items, gr.update(samples=summarize_items(items))
def delete_item(evt: gr.SelectData, items):
"""
Deletes an item when selected in the dataset component.
"""
del items[evt.index]
return items, gr.update(samples=summarize_items(items))
def run_pipeline(items):
"""
Processes PDFs and pasted text through the LLM pipeline,
geocodes addresses, computes an optimized route,
and writes two HTML outputs (data table and map).
"""
# Separate file-based and pasted inputs
pdf_paths = [item['file'].name for item in items if item['source'] == 'PDF']
# Parse PDFs to text
text_docs = [process_pdf_hebrew_rtl(path) for path in pdf_paths]
# Include any pasted text directly
pasted_texts = [item['content'] for item in items if item['source'] == 'Paste']
# Combine for LLM parsing
docs = text_docs + pasted_texts
results, llm_parsed = llm_parser(docs=docs)
# Geolocation and routing
locations = addresses_to_coordinates([r.business_address for r in results])
points = [loc.coords for loc in locations]
route = coordinates_to_route(points)
# Build data table
df = pd.DataFrame([loc.to_dict() for loc in locations])
llm_parsed = llm_parsed.rename(columns={'business_address': 'Address'})
df = df.join(llm_parsed.set_index('Address'), on='Address')
# Write HTML outputs
data_output_path = './data_output.html'
with open(data_output_path, mode='w', encoding='utf-8') as html:
html.write(df.to_html(index=False, escape=False))
map_output_path = './map_output.html'
generate_route_map(route, map_output_path)
return data_output_path, map_output_path
# Build Gradio interface
with gr.Blocks() as demo:
state = gr.State([])
with gr.Row():
file_input = gr.Files(file_types=['.pdf'], label="Upload PDFs")
file_btn = gr.Button("Add PDFs")
with gr.Row():
paste_box = gr.Textbox(lines=3, placeholder="Paste text content...", label="Paste Text")
paste_btn = gr.Button("Add Text")
gr.Markdown("### ๐Ÿ“ Inputs:")
item_list = gr.Dataset(
components=[gr.Textbox(visible=False)], # hide the textbox
samples=[],
headers=["Items"]
)
# Register callbacks for managing inputs
file_btn.click(add_files, inputs=[file_input, state], outputs=[state, item_list])
paste_btn.click(add_text, inputs=[paste_box, state], outputs=[state, item_list])
item_list.select(delete_item, inputs=state, outputs=[state, item_list])
# Processing and output
process_btn = gr.Button("Process & Download HTML")
data_out = gr.File(label="๐Ÿ“Š Business Data HTML")
map_out = gr.File(label="๐Ÿ—บ๏ธ Route Map HTML")
process_btn.click(run_pipeline, inputs=state, outputs=[data_out, map_out])
# Launch the app
if __name__ == '__main__':
demo.launch()