Essentially our app has two columns. The first contains a text box for the user to enter their query, a set of radio buttons that allows us to switch between models and a text box that displays the output of the validation check.
The second column contains the map, generated with leafmap.folium
and a text box that displays the full text itinerary output from the LLM call. The “generate map” button is at the bottom, off screen in the screenshot above.
The code for all this is remarkably concise, thanks to all the work being done in the background by gradio.
import gradio as gr
from travel_mapper.TravelMapper import TravelMapperForUI, load_secrets, assert_secrets
from travel_mapper.user_interface.utils import generate_generic_leafmap
from travel_mapper.user_interface.constants import EXAMPLE_QUERYdef main():
# load the AP keys
secrets = load_secrets()
assert_secrets(secrets)
# set up travel mapper (see part 2)
travel_mapper = TravelMapperForUI(
openai_api_key=secrets["OPENAI_API_KEY"],
google_maps_key=secrets["GOOGLE_MAPS_API_KEY"],
google_palm_api_key=secrets["GOOGLE_PALM_API_KEY"],
)
# build the UI in gradio
app = gr.Blocks()
# make a generic map to display when the app first loads
generic_map = generate_generic_leafmap()
with app:
gr.Markdown("## Generate travel suggestions")
# make multple tabs
with gr.Tabs():
# make the first tab
with gr.TabItem("Generate with map"):
# make rows 1 within tab 1
with gr.Row():
# make column 1 within row 1
with gr.Column():
text_input_map = gr.Textbox(
EXAMPLE_QUERY, label="Travel query", lines=4
)
radio_map = gr.Radio(
value="gpt-3.5-turbo",
choices=["gpt-3.5-turbo", "gpt-4", "models/text-bison-001"],
label="models",
)
query_validation_text = gr.Textbox(
label="Query validation information", lines=2
)
# make column 2 within row 1
with gr.Column():
# place where the map will appear
map_output = gr.HTML(generic_map, label="Travel map")
# place where the suggested trip will appear
itinerary_output = gr.Textbox(
value="Your itinerary will appear here",
label="Itinerary suggestion",
lines=3,
)
# generate button
map_button = gr.Button("Generate")
# make the second tab
with gr.TabItem("Generate without map"):
# make the first row within the second tab
with gr.Row():
# make the first column within the first row
with gr.Column():
text_input_no_map = gr.Textbox(
value=EXAMPLE_QUERY, label="Travel query", lines=3
)
radio_no_map = gr.Radio(
value="gpt-3.5-turbo",
choices=["gpt-3.5-turbo", "gpt-4", "models/text-bison-001"],
label="Model choices",
)
query_validation_no_map = gr.Textbox(
label="Query validation information", lines=2
)
# make the second column within the first row
with gr.Column():
text_output_no_map = gr.Textbox(
value="Your itinerary will appear here",
label="Itinerary suggestion",
lines=3,
)
# generate button
text_button = gr.Button("Generate")
# instructions for what happens whrn the buttons are clicked
# note use of the "generate_with_leafmap" method here.
map_button.click(
travel_mapper.generate_with_leafmap,
inputs=[text_input_map, radio_map],
outputs=[map_output, itinerary_output, query_validation_text],
)
text_button.click(
travel_mapper.generate_without_leafmap,
inputs=[text_input_no_map, radio_no_map],
outputs=[text_output_no_map, query_validation_no_map],
)
# run the app
app.launch()
As can be seen from looking at the repository on github, the travel mapper code is structured with the help of a standard template from cookiecutter, but some important parts of the template are not yet filled in. Ideally we would include unit and integration tests, and complete the repository set up so that continuous integration/continuous delivery (CI/CD) concepts are used. If the project develops further beyond this POC stage, these aspects will be added in future.
There are a few ways that the code can be run locally. If we put the main
function in the block above into a script called driver.py
, we should be able to run it from the top level of the travel_mapper
project from the terminal. If the package successfully runs, a message like this should appear in the terminal
Running on local URL: http://127.0.0.1:7860
Copy-pasting this url into a web browser should display the gradio app, running locally on your machine. Of course, more steps would be needed if we actually wanted to deploy this on the web (which I do not recommend because of the costs incurred from the API calls), but this is beyond the scope of these articles.
The driver can also be run from a bash script called run.sh
, which can be found in the user_interface
module of the codebase.
# Run the UI
# run this from the top level directory of the travel mapper project
export PYTHONPATH=$PYTHONPATH:$(pwd)
echo "Starting travel mapper UI"
$(pwd)/travel_mapper/user_interface/driver.py
When run from the top level of the project, this also sets the PYTHONPATH
correctly so that the project-specific import statements are always recognized.
Thats it for the series and thanks for making it to the end! Please feel free to explore the full codebase here https://github.com/rmartinshort/travel_mapper. Any suggestions for improvement or extensions to the functionality would be much appreciated!