DylanonWic commited on
Commit
115169a
1 Parent(s): 9ce77e0

Upload 11 files

Browse files
Files changed (11) hide show
  1. app.py +19 -0
  2. chatbot.ipynb +169 -0
  3. chatbot.py +76 -0
  4. data_source.txt +0 -0
  5. gplace.ipynb +726 -0
  6. gplace.py +95 -0
  7. prompt.txt +10 -0
  8. requirements.txt +9 -0
  9. tools.ipynb +46 -0
  10. tools.py +14 -0
  11. utils.py +8 -0
app.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import gradio as gr
3
+ from chatbot import submitUserMessage
4
+
5
+ def chat(message:str, history):
6
+ return submitUserMessage(message)
7
+
8
+
9
+ def slow_echo_chat(message, history):
10
+ answer = submitUserMessage(message)
11
+ for i in range(len(answer)):
12
+ time.sleep(0.01)
13
+ yield answer[: i+1]
14
+
15
+
16
+ # gr.ChatInterface(chat).launch()
17
+ interface = gr.ChatInterface(slow_echo_chat)
18
+
19
+ interface.launch()
chatbot.ipynb ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os\n",
10
+ "import utils\n",
11
+ "\n",
12
+ "utils.load_env()\n",
13
+ "os.environ['LANGCHAIN_TRACING_V2'] = \"true\""
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "code",
18
+ "execution_count": 2,
19
+ "metadata": {},
20
+ "outputs": [],
21
+ "source": [
22
+ "from typing import Annotated, Literal, TypedDict\n",
23
+ "\n",
24
+ "from langchain_core.messages import HumanMessage\n",
25
+ "\n",
26
+ "# for llm model\n",
27
+ "from langchain_anthropic import ChatAnthropic\n",
28
+ "from langchain_openai import ChatOpenAI\n",
29
+ "\n",
30
+ "from langchain_core.tools import tool\n",
31
+ "from langgraph.checkpoint.memory import MemorySaver\n",
32
+ "from langgraph.graph import END, StateGraph, MessagesState\n",
33
+ "from langgraph.prebuilt import ToolNode\n",
34
+ "import tools\n",
35
+ "\n",
36
+ "\n",
37
+ "tool_node = tools.tool_node\n",
38
+ "\n",
39
+ "# model = ChatAnthropic(model=\"claude-3-5-sonnet-20240620\", temperature=0).bind_tools(tools)\n",
40
+ "model = ChatOpenAI(model=\"gpt-4o-mini\")\n",
41
+ "\n",
42
+ "# Define the function that determines whether to continue or not\n",
43
+ "def should_continue(state: MessagesState) -> Literal[\"tools\", END]:\n",
44
+ " messages = state['messages']\n",
45
+ " last_message = messages[-1]\n",
46
+ " # If the LLM makes a tool call, then we route to the \"tools\" node\n",
47
+ " if last_message.tool_calls:\n",
48
+ " return \"tools\"\n",
49
+ " # Otherwise, we stop (reply to the user)\n",
50
+ " return END\n",
51
+ "\n",
52
+ "\n",
53
+ "# Define the function that calls the model\n",
54
+ "def call_model(state: MessagesState):\n",
55
+ " messages = state['messages']\n",
56
+ " response = model.invoke(messages)\n",
57
+ " # We return a list, because this will get added to the existing list\n",
58
+ " return {\"messages\": [response]}\n",
59
+ "\n",
60
+ "\n",
61
+ "# Define a new graph\n",
62
+ "workflow = StateGraph(MessagesState)\n",
63
+ "\n",
64
+ "# Define the two nodes we will cycle between\n",
65
+ "workflow.add_node(\"agent\", call_model)\n",
66
+ "workflow.add_node(\"tools\", tool_node)\n",
67
+ "\n",
68
+ "# Set the entrypoint as `agent`\n",
69
+ "# This means that this node is the first one called\n",
70
+ "workflow.set_entry_point(\"agent\")\n",
71
+ "\n",
72
+ "# We now add a conditional edge\n",
73
+ "workflow.add_conditional_edges(\n",
74
+ " # First, we define the start node. We use `agent`.\n",
75
+ " # This means these are the edges taken after the `agent` node is called.\n",
76
+ " \"agent\",\n",
77
+ " # Next, we pass in the function that will determine which node is called next.\n",
78
+ " should_continue,\n",
79
+ ")\n",
80
+ "\n",
81
+ "# We now add a normal edge from `tools` to `agent`.\n",
82
+ "# This means that after `tools` is called, `agent` node is called next.\n",
83
+ "workflow.add_edge(\"tools\", 'agent')\n",
84
+ "\n",
85
+ "# Initialize memory to persist state between graph runs\n",
86
+ "checkpointer = MemorySaver()\n",
87
+ "\n",
88
+ "# Finally, we compile it!\n",
89
+ "# This compiles it into a LangChain Runnable,\n",
90
+ "# meaning you can use it as you would any other runnable.\n",
91
+ "# Note that we're (optionally) passing the memory when compiling the graph\n",
92
+ "app = workflow.compile(checkpointer=checkpointer)"
93
+ ]
94
+ },
95
+ {
96
+ "cell_type": "code",
97
+ "execution_count": 6,
98
+ "metadata": {},
99
+ "outputs": [],
100
+ "source": [
101
+ "def submitUserMessage(message:str):\n",
102
+ " final_state = app.invoke(\n",
103
+ " {\"messages\": [HumanMessage(content=message)]},\n",
104
+ " config={\"configurable\": {\"thread_id\": 42}}\n",
105
+ " )\n",
106
+ " return final_state[\"messages\"][-1].content"
107
+ ]
108
+ },
109
+ {
110
+ "cell_type": "code",
111
+ "execution_count": 7,
112
+ "metadata": {},
113
+ "outputs": [
114
+ {
115
+ "name": "stderr",
116
+ "output_type": "stream",
117
+ "text": [
118
+ "Unable to load requested LangChainTracer. To disable this warning, unset the LANGCHAIN_TRACING_V2 environment variables.\n",
119
+ "LangSmithUserError('API key must be provided when using hosted LangSmith API')\n",
120
+ "Unable to load requested LangChainTracer. To disable this warning, unset the LANGCHAIN_TRACING_V2 environment variables.\n",
121
+ "LangSmithUserError('API key must be provided when using hosted LangSmith API')\n",
122
+ "Unable to load requested LangChainTracer. To disable this warning, unset the LANGCHAIN_TRACING_V2 environment variables.\n",
123
+ "LangSmithUserError('API key must be provided when using hosted LangSmith API')\n",
124
+ "Unable to load requested LangChainTracer. To disable this warning, unset the LANGCHAIN_TRACING_V2 environment variables.\n",
125
+ "LangSmithUserError('API key must be provided when using hosted LangSmith API')\n",
126
+ "Unable to load requested LangChainTracer. To disable this warning, unset the LANGCHAIN_TRACING_V2 environment variables.\n",
127
+ "LangSmithUserError('API key must be provided when using hosted LangSmith API')\n",
128
+ "Unable to load requested LangChainTracer. To disable this warning, unset the LANGCHAIN_TRACING_V2 environment variables.\n",
129
+ "LangSmithUserError('API key must be provided when using hosted LangSmith API')\n"
130
+ ]
131
+ },
132
+ {
133
+ "data": {
134
+ "text/plain": [
135
+ "'บริเวณมาบุญครองในกรุงเทพฯ มีร้านกาแฟหลายแห่งที่น่าสนใจ คุณสามารถลองไปที่ร้านเหล่านี้ได้:\\n\\n1. **ร้านกาแฟโฟลว์ (Flow Coffee)** - ร้านกาแฟเล็กๆ ที่มีบรรยากาศสบาย เหมาะสำหรับนั่งทำงานหรือนั่งชิลล์\\n2. **ร้านกาแฟ On the Way** - ร้านกาแฟที่มีเมนูหลากหลายและบรรยากาศดี\\n3. **ร้านกาแฟชิค (Chic)** - ร้านกาแฟที่มีการตกแต่งน่ารักและเครื่องดื่มหลากหลาย\\n4. **ร้านกาแฟ Starbucks** - มีสาขาหลายแห่งในกรุงเทพฯ รวมถึงใกล้บริเวณมาบุญครอง\\n5. **ร้านกาแฟดอยช้าง** - ที่มีชื่อเสียงในเรื่องของกาแฟจากดอยช้าง\\n\\nคุณสามารถค้นหาร้านกาแฟเพิ่มเติมได้จาก Google Maps หรือแอปพลิเคชันค้นหาร้านอาหารต่างๆ เพื่อดูรีวิวและข้อมูลเพิ่มเติมเกี่ยวกับร้านกาแฟใกล้มาบุญครองได้ค่ะ'"
136
+ ]
137
+ },
138
+ "execution_count": 7,
139
+ "metadata": {},
140
+ "output_type": "execute_result"
141
+ }
142
+ ],
143
+ "source": [
144
+ "submitUserMessage(\"ค้นหาร้านกาแฟใกล้มาบุญครอง\")"
145
+ ]
146
+ }
147
+ ],
148
+ "metadata": {
149
+ "kernelspec": {
150
+ "display_name": "Python 3",
151
+ "language": "python",
152
+ "name": "python3"
153
+ },
154
+ "language_info": {
155
+ "codemirror_mode": {
156
+ "name": "ipython",
157
+ "version": 3
158
+ },
159
+ "file_extension": ".py",
160
+ "mimetype": "text/x-python",
161
+ "name": "python",
162
+ "nbconvert_exporter": "python",
163
+ "pygments_lexer": "ipython3",
164
+ "version": "3.11.9"
165
+ }
166
+ },
167
+ "nbformat": 4,
168
+ "nbformat_minor": 2
169
+ }
chatbot.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import utils
3
+
4
+ utils.load_env()
5
+ # os.environ['LANGCHAIN_TRACING_V2'] = "true"
6
+
7
+ from typing import Literal
8
+ from langchain_core.messages import HumanMessage
9
+ from langchain_openai import ChatOpenAI
10
+ from langgraph.checkpoint.memory import MemorySaver
11
+ from langgraph.graph import END, StateGraph, MessagesState
12
+ import tools
13
+
14
+ # define tools node.
15
+ tool_node = tools.tool_node
16
+
17
+ # load models.
18
+ model = ChatOpenAI(model="gpt-4o-mini")
19
+
20
+ # Define the function that determines whether to continue or not
21
+ def should_continue(state: MessagesState) -> Literal["tools", END]:
22
+ messages = state['messages']
23
+ last_message = messages[-1]
24
+ # If the LLM makes a tool call, then we route to the "tools" node
25
+ if last_message.tool_calls:
26
+ return "tools"
27
+ # Otherwise, we stop (reply to the user)
28
+ return END
29
+
30
+
31
+ # Define the function that calls the model
32
+ def call_model(state: MessagesState):
33
+ messages = state['messages']
34
+ response = model.invoke(messages)
35
+ # We return a list, because this will get added to the existing list
36
+ return {"messages": [response]}
37
+
38
+
39
+ # Define a new graph
40
+ workflow = StateGraph(MessagesState)
41
+
42
+ # Define the two nodes we will cycle between
43
+ workflow.add_node("agent", call_model)
44
+ workflow.add_node("tools", tool_node)
45
+
46
+ # Set the entrypoint as `agent`
47
+ workflow.set_entry_point("agent")
48
+
49
+ # We now add a conditional edge
50
+ workflow.add_conditional_edges(
51
+ # First, we define the start node. We use `agent`.
52
+ # This means these are the edges taken after the `agent` node is called.
53
+ "agent",
54
+ # Next, we pass in the function that will determine which node is called next.
55
+ should_continue,
56
+ )
57
+
58
+ # We now add a normal edge from `tools` to `agent`.
59
+ # This means that after `tools` is called, `agent` node is called next.
60
+ workflow.add_edge("tools", 'agent')
61
+
62
+ # Initialize memory to persist state between graph runs
63
+ checkpointer = MemorySaver()
64
+
65
+ # Finally, we compile it!
66
+ # This compiles it into a LangChain Runnable,
67
+ # meaning you can use it as you would any other runnable.
68
+ # Note that we're (optionally) passing the memory when compiling the graph
69
+ app = workflow.compile(checkpointer=checkpointer)
70
+
71
+ def submitUserMessage(message:str):
72
+ final_state = app.invoke(
73
+ {"messages": [HumanMessage(content=message)]},
74
+ config={"configurable": {"thread_id": 42}}
75
+ )
76
+ return final_state["messages"][-1].content
data_source.txt ADDED
File without changes
gplace.ipynb ADDED
@@ -0,0 +1,726 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 6,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os\n",
10
+ "import requests"
11
+ ]
12
+ },
13
+ {
14
+ "cell_type": "code",
15
+ "execution_count": 1,
16
+ "metadata": {},
17
+ "outputs": [],
18
+ "source": [
19
+ "import utils\n",
20
+ "\n",
21
+ "utils.load_env()"
22
+ ]
23
+ },
24
+ {
25
+ "cell_type": "code",
26
+ "execution_count": 3,
27
+ "metadata": {},
28
+ "outputs": [
29
+ {
30
+ "name": "stderr",
31
+ "output_type": "stream",
32
+ "text": [
33
+ "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:141: LangChainDeprecationWarning: The class `GooglePlacesTool` was deprecated in LangChain 0.0.33 and will be removed in 0.3.0. An updated version of the class exists in the langchain-google-community package and should be used instead. To use it run `pip install -U langchain-google-community` and import as `from langchain_google_community import GooglePlacesTool`.\n",
34
+ " warn_deprecated(\n",
35
+ "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:141: LangChainDeprecationWarning: The class `GooglePlacesAPIWrapper` was deprecated in LangChain 0.0.33 and will be removed in 0.3.0. An updated version of the class exists in the langchain-google-community package and should be used instead. To use it run `pip install -U langchain-google-community` and import as `from langchain_google_community import GooglePlacesAPIWrapper`.\n",
36
+ " warn_deprecated(\n"
37
+ ]
38
+ },
39
+ {
40
+ "data": {
41
+ "text/plain": [
42
+ "'1. Fashion Island\\nAddress: 587-589/7-9, Ram Inthra Rd, Khwaeng Khan Na Yao, Khet Khan Na Yao, Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJd57HEQRjHTERG_xSTcdQoYs\\nPhone: 02 947 5000\\nWebsite: http://www.fashionisland.co.th/\\n\\n\\n2. Food Island-Fashion Island\\nAddress: 5/5-6 หมู่ 5 Fashion Island, Ram Inthra Rd, Khwaeng Khan Na Yao, บางเขน Krung Thep Maha Nakhon 10220, Thailand\\nGoogle place ID: ChIJxVlvKA9jHTERAaDXThEk0sU\\nPhone: Unknown\\nWebsite: https://www.fashionisland.co.th/\\n\\n\\n3. Grand Station @ Fashion Island\\nAddress: Fashion Island Shopping Mall คันนายาว Khet Khan Na Yao, Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJgYJ0xNxjHTERqh7EMAXGflk\\nPhone: 02 947 5000\\nWebsite: https://www.fashionisland.co.th/about-us/grandstation/\\n\\n\\n4. Central Department Store Fashion Island\\nAddress: 591 Ram Inthra Rd, Khwaeng Khan Na Yao, Khet Khan Na Yao, Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJU51oO09jHTERkAkthlfrvMQ\\nPhone: 02 947 5320\\nWebsite: http://www.central.co.th/\\n\\n\\n5. Pomelo Fashion Island\\nAddress: Unit GSSH101, 1st Floor, Fashion Island Shopping Mall, 587-589, Ramindra Rd, แขวงคันนายาว เขตคันนายาว กรุงเทพมหานคร 10230, Thailand\\nGoogle place ID: ChIJaYz1YRFjHTERHcxGtqrypsk\\nPhone: 02 000 6811\\nWebsite: https://www.pomelofashion.com/\\n\\n\\n6. Fashion Island\\nAddress: 401 Newport Center Dr, Newport Beach, CA 92660, USA\\nGoogle place ID: ChIJUetYrofg3IARvxarZNginsY\\nPhone: (949) 721-2000\\nWebsite: https://www.fashionisland.com/?utm_source=soci&utm_medium=organic&utm_campaign=gmb_soci_listing\\n\\n\\n7. Haborland Fashion Island\\nAddress: ศูนย์การค้า แฟชั่นไอส์แลนด์ ชั้น3, Khwaeng Khan Na Yao, Khet Khan Na Yao, Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJ7wF25A5jHTERyBbgZ24hjGU\\nPhone: 065 848 1000\\nWebsite: https://harborlandgroup.com/\\n\\n\\n8. Panya Ramintra\\nAddress: Khan Na Yao, Bangkok 10230, Thailand\\nGoogle place ID: ChIJ9e97xwhjHTERR-MWDuKtUYY\\nPhone: Unknown\\nWebsite: Unknown\\n\\n\\n9. Manfair @Fashion Island, 2nd FL, Street 23, Grand Station, Unit MSE025\\nAddress: Manfair Store-Grand Station @Fashion Island Khwaeng Khan Na Yao, Khet Khan Na Yao, Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJod6zSApjHTERkZ8GxIKx-AY\\nPhone: 085 166 5561\\nWebsite: https://manfair.co.th/\\n\\n\\n10. ร้านชุดชั้นใน GIRLY SECRET @Fasion Island\\nAddress: GIRLY SECRET แฟชั่นไอส์แลนด์ ชั้น2 โซนแกรนด์เสตชั่น สตรีท 11 Lat Phrao Road Khwaeng Khan Na Yao, คันนายาว Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJMRAHkpKd4jARZBQhL3tzF28\\nPhone: 092 697 9698\\nWebsite: Unknown\\n\\n\\n11. OkurimonoJapan! (Fashion Island)\\nAddress: Level 2, Ram Inthra Rd, Khwaeng Khan Na Yao, Khet Khan Na Yao, Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJUTgHRlBjHTERw3I3e-uH7hI\\nPhone: 080 594 4644\\nWebsite: Unknown\\n\\n\\n12. Opposite Fashion Island\\nAddress: Khan Na Yao, Bangkok 10230, Thailand\\nGoogle place ID: ChIJV8YMrwhjHTERTd8eEupPwZY\\nPhone: Unknown\\nWebsite: Unknown\\n\\n'"
43
+ ]
44
+ },
45
+ "execution_count": 3,
46
+ "metadata": {},
47
+ "output_type": "execute_result"
48
+ }
49
+ ],
50
+ "source": [
51
+ "from langchain_community.tools import GooglePlacesTool\n",
52
+ "\n",
53
+ "places = GooglePlacesTool()\n",
54
+ "places.run(\"fasion islands\")"
55
+ ]
56
+ },
57
+ {
58
+ "cell_type": "code",
59
+ "execution_count": null,
60
+ "metadata": {},
61
+ "outputs": [],
62
+ "source": [
63
+ "#find places id\n",
64
+ "#near by search"
65
+ ]
66
+ },
67
+ {
68
+ "cell_type": "code",
69
+ "execution_count": 14,
70
+ "metadata": {},
71
+ "outputs": [
72
+ {
73
+ "name": "stdout",
74
+ "output_type": "stream",
75
+ "text": [
76
+ "{'candidates': [{'formatted_address': '444 ถ. พญาไท แขวงวังใหม่ เขตปทุมวัน กรุงเทพมหานคร 10330 ไทย', 'geometry': {'location': {'lat': 13.744677, 'lng': 100.5295593}, 'viewport': {'northeast': {'lat': 13.74598387989272, 'lng': 100.5309299798927}, 'southwest': {'lat': 13.74328422010728, 'lng': 100.5282303201073}}}, 'name': 'เอ็ม บี เค เซ็นเตอร์', 'opening_hours': {'open_now': False}, 'rating': 4.3}], 'status': 'OK'}\n"
77
+ ]
78
+ }
79
+ ],
80
+ "source": [
81
+ "def find_place_from_text(input_text, location=None, radius=10000):\n",
82
+ " # Retrieve the API key from environment variables\n",
83
+ " api_key = os.getenv('GPLACES_API_KEY')\n",
84
+ "\n",
85
+ " if not api_key:\n",
86
+ " raise ValueError(\"API key not found. Please set the GOOGLE_MAPS_API_KEY environment variable.\")\n",
87
+ "\n",
88
+ " # Define the endpoint URL\n",
89
+ " url = \"https://maps.googleapis.com/maps/api/place/findplacefromtext/json\"\n",
90
+ "\n",
91
+ " # Define the parameters for the request\n",
92
+ " params = {\n",
93
+ " 'fields': 'formatted_address,name,rating,opening_hours,geometry',\n",
94
+ " 'input': input_text,\n",
95
+ " 'inputtype': 'textquery',\n",
96
+ " 'key': api_key\n",
97
+ " }\n",
98
+ " \n",
99
+ " params['locationbias'] = f'circle:{radius}@{location}' if location is not None and radius is not None else None\n",
100
+ "\n",
101
+ " # Make the request to the Google Maps API\n",
102
+ " response = requests.get(url, params=params)\n",
103
+ "\n",
104
+ " # Check if the request was successful\n",
105
+ " if response.status_code == 200:\n",
106
+ " return response.json() # Return the JSON response\n",
107
+ " else:\n",
108
+ " response.raise_for_status() # Raise an exception for HTTP errors\n",
109
+ "\n",
110
+ "# Example usage:\n",
111
+ "location = \"15.87,100.9925\" # Latitude and Longitude\n",
112
+ "input_text = \"มาบุญครอง\"\n",
113
+ "result = find_place_from_text(input_text, location)\n",
114
+ "\n",
115
+ "print(result)"
116
+ ]
117
+ },
118
+ {
119
+ "cell_type": "code",
120
+ "execution_count": 43,
121
+ "metadata": {},
122
+ "outputs": [
123
+ {
124
+ "name": "stdout",
125
+ "output_type": "stream",
126
+ "text": [
127
+ "Coordinates: 13.744677,100.5295593\n"
128
+ ]
129
+ }
130
+ ],
131
+ "source": [
132
+ "def find_location(input_text:str, location:str=None, radius=10000):\n",
133
+ " # Call the find_place_from_text function to get the location data\n",
134
+ " data = find_place_from_text(input_text, location, radius)\n",
135
+ "\n",
136
+ " # Extract the latitude and longitude from the response\n",
137
+ " candidates = data.get('candidates', [])\n",
138
+ " if len(candidates)==0:\n",
139
+ " raise ValueError(\"No location found.\")\n",
140
+ "\n",
141
+ " # Assuming we're taking the first candidate\n",
142
+ " geometry = candidates[0].get('geometry', {})\n",
143
+ " location = geometry.get('location', {})\n",
144
+ "\n",
145
+ " latitude = location.get('lat')\n",
146
+ " longitude = location.get('lng')\n",
147
+ "\n",
148
+ " if latitude is None or longitude is None:\n",
149
+ " raise ValueError(\"Latitude or Longitude not found in the response.\")\n",
150
+ "\n",
151
+ " # Return the latitude and longitude as a formatted string\n",
152
+ " return f\"{latitude},{longitude}\"\n",
153
+ "\n",
154
+ "\n",
155
+ "location = \"15.87,100.9925\" # Latitude and Longitude\n",
156
+ "input_text = \"มาบุญครอง\"\n",
157
+ "coordinates = find_location(input_text, location)\n",
158
+ "print(f\"Coordinates: {coordinates}\")"
159
+ ]
160
+ },
161
+ {
162
+ "cell_type": "code",
163
+ "execution_count": 45,
164
+ "metadata": {},
165
+ "outputs": [
166
+ {
167
+ "data": {
168
+ "text/plain": [
169
+ "[{'business_status': 'OPERATIONAL',\n",
170
+ " 'geometry': {'location': {'lat': 13.7491743, 'lng': 100.5161575},\n",
171
+ " 'viewport': {'northeast': {'lat': 13.75056342989272,\n",
172
+ " 'lng': 100.5175915298927},\n",
173
+ " 'southwest': {'lat': 13.74786377010728, 'lng': 100.5148918701073}}},\n",
174
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
175
+ " 'icon_background_color': '#FF9E67',\n",
176
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
177
+ " 'name': 'White Flower',\n",
178
+ " 'opening_hours': {'open_now': True},\n",
179
+ " 'photos': [{'height': 3024,\n",
180
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/112771822205386110836\">Natthapong Taweesook</a>'],\n",
181
+ " 'photo_reference': 'AelY_CsoE9mkGAM4CG4Y7i3QaoX7aKQZy9HhsBI-v4gCECbwhKH5_r-0_gCdsvjSgGyjxX5MKn5_pLdTgHTESSCsFLHYWvsPCdBhNLEAipvg7fS82FL3__FnHBVkM_ufpYlHCCn57kf8b_7EazaR1rvLXoaGY6jRZ5fCEUaY9CtfBqZqbxk',\n",
182
+ " 'width': 4032}],\n",
183
+ " 'place_id': 'ChIJl9od-jqZ4jARVmMNi4wBU2o',\n",
184
+ " 'plus_code': {'compound_code': 'PGX8+MF Bangkok',\n",
185
+ " 'global_code': '7P52PGX8+MF'},\n",
186
+ " 'price_level': 3,\n",
187
+ " 'rating': 4.4,\n",
188
+ " 'reference': 'ChIJl9od-jqZ4jARVmMNi4wBU2o',\n",
189
+ " 'scope': 'GOOGLE',\n",
190
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
191
+ " 'user_ratings_total': 2323,\n",
192
+ " 'vicinity': '678/1-7 Bamrung Mueang Rd, Wat Thep Sirin, Pom Prap Sattru Phai'},\n",
193
+ " {'business_status': 'OPERATIONAL',\n",
194
+ " 'geometry': {'location': {'lat': 13.7449251, 'lng': 100.514918},\n",
195
+ " 'viewport': {'northeast': {'lat': 13.74623957989272,\n",
196
+ " 'lng': 100.5163598298927},\n",
197
+ " 'southwest': {'lat': 13.74353992010728, 'lng': 100.5136601701073}}},\n",
198
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
199
+ " 'icon_background_color': '#FF9E67',\n",
200
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
201
+ " 'name': 'Lung & Pa',\n",
202
+ " 'opening_hours': {'open_now': True},\n",
203
+ " 'photos': [{'height': 3024,\n",
204
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/110014743976867613506\">auttapong maesincee</a>'],\n",
205
+ " 'photo_reference': 'AelY_Cuw4CTnO_tRSofR-FyQfj8EB2EiuNd5M0rdo1LBY-WzlDt0COUJLVdya639XsDmqeXaEXDsuHPe8lQy2uj3REGHCK0rj9RBXEwcclMdKZLFwmy2MHkel4MoxAg5QSjimam-OuiUql3xfdVwVI_p95eTNoAWBkHCyAPyEw_ILsPz3xO5',\n",
206
+ " 'width': 4032}],\n",
207
+ " 'place_id': 'ChIJB0JM5CSZ4jARZ0sxEfceIho',\n",
208
+ " 'plus_code': {'compound_code': 'PGV8+X2 Bangkok',\n",
209
+ " 'global_code': '7P52PGV8+X2'},\n",
210
+ " 'price_level': 1,\n",
211
+ " 'rating': 4.6,\n",
212
+ " 'reference': 'ChIJB0JM5CSZ4jARZ0sxEfceIho',\n",
213
+ " 'scope': 'GOOGLE',\n",
214
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
215
+ " 'user_ratings_total': 125,\n",
216
+ " 'vicinity': '34/3 Mittraphan Rd, Pom Prap, Pom Prap Sattru Phai'},\n",
217
+ " {'business_status': 'OPERATIONAL',\n",
218
+ " 'geometry': {'location': {'lat': 13.7539337, 'lng': 100.5418347},\n",
219
+ " 'viewport': {'northeast': {'lat': 13.75527512989272,\n",
220
+ " 'lng': 100.5432228298927},\n",
221
+ " 'southwest': {'lat': 13.75257547010728, 'lng': 100.5405231701073}}},\n",
222
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
223
+ " 'icon_background_color': '#FF9E67',\n",
224
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
225
+ " 'name': 'Pratunam Thai Food~Authentic (Cook by thai chef) / ร้านอาหาร ประตูน้ำไทยฟู้ด',\n",
226
+ " 'opening_hours': {'open_now': True},\n",
227
+ " 'photos': [{'height': 809,\n",
228
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/100445062871009806114\">A Google User</a>'],\n",
229
+ " 'photo_reference': 'AelY_Cve0Z3K2wpXgtc9uyyRNmUaQEsNrxCjnkKphKCd534mIu2LnYccgRFjTfFBjBOMI7FohPZGjIS1_iNFy1atfgkos24-Oz1yMbRFsfngUWMnVfoMMYySuhMPMj5H-KZSOEgzrjS93tLDdOvjSG-ooMXCby8udoXmRDf8cjGbIudJt_Ef',\n",
230
+ " 'width': 1440}],\n",
231
+ " 'place_id': 'ChIJbclEnumf4jARYQQZzBKxU18',\n",
232
+ " 'plus_code': {'compound_code': 'QG3R+HP Bangkok',\n",
233
+ " 'global_code': '7P52QG3R+HP'},\n",
234
+ " 'rating': 4.8,\n",
235
+ " 'reference': 'ChIJbclEnumf4jARYQQZzBKxU18',\n",
236
+ " 'scope': 'GOOGLE',\n",
237
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
238
+ " 'user_ratings_total': 64,\n",
239
+ " 'vicinity': '190 3 ถนน พญาไท Khwaeng Makkasan, Ratchathewi'},\n",
240
+ " {'business_status': 'OPERATIONAL',\n",
241
+ " 'geometry': {'location': {'lat': 13.7380932, 'lng': 100.5168921},\n",
242
+ " 'viewport': {'northeast': {'lat': 13.73944302989272,\n",
243
+ " 'lng': 100.5182419298927},\n",
244
+ " 'southwest': {'lat': 13.73674337010728, 'lng': 100.5155422701073}}},\n",
245
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
246
+ " 'icon_background_color': '#FF9E67',\n",
247
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
248
+ " 'name': 'Supa Restaurant',\n",
249
+ " 'opening_hours': {'open_now': True},\n",
250
+ " 'photos': [{'height': 4640,\n",
251
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/112078133470872246639\">A Google User</a>'],\n",
252
+ " 'photo_reference': 'AelY_Cv4WhdIzv_rZWGAOHk3MDedYk69pG-sj3gRLSXIstV9JBPQdKqYQNll6o9E2_-j0tHbljoMdnVi1VGlajxPzjT1ONP10NmNpfwTbIJuntKw6fwJPTsYCak1ZooXO1gQKmzPWBcNwHkE8sshXwgrwYaNQ8AahF8ZGvLd14W5WQ8MpbtF',\n",
253
+ " 'width': 3472}],\n",
254
+ " 'place_id': 'ChIJE3_so2WZ4jARDbO3ktHv2kU',\n",
255
+ " 'plus_code': {'compound_code': 'PGQ8+6Q Bangkok',\n",
256
+ " 'global_code': '7P52PGQ8+6Q'},\n",
257
+ " 'rating': 4.9,\n",
258
+ " 'reference': 'ChIJE3_so2WZ4jARDbO3ktHv2kU',\n",
259
+ " 'scope': 'GOOGLE',\n",
260
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
261
+ " 'user_ratings_total': 39,\n",
262
+ " 'vicinity': '512 Rong Mueang Rd, Khwaeng Rong Muang, Pathum Wan'},\n",
263
+ " {'business_status': 'OPERATIONAL',\n",
264
+ " 'geometry': {'location': {'lat': 13.7295572, 'lng': 100.5232952},\n",
265
+ " 'viewport': {'northeast': {'lat': 13.73092007989272,\n",
266
+ " 'lng': 100.5246405298927},\n",
267
+ " 'southwest': {'lat': 13.72822042010728, 'lng': 100.5219408701073}}},\n",
268
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
269
+ " 'icon_background_color': '#FF9E67',\n",
270
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
271
+ " 'name': 'Dao Restaurant',\n",
272
+ " 'opening_hours': {'open_now': True},\n",
273
+ " 'photos': [{'height': 2252,\n",
274
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/106367740125040655910\">A Google User</a>'],\n",
275
+ " 'photo_reference': 'AelY_Cso_rentogXMdMZUgmkkRmY9-Wq14vmpmO758LJqvyxfsUzXMv98HID9tluoKllNnUMxRDxfSsPR7HBdXhj_bAYXLY8gKe8txNRix4Sbj7I-EG4jbgPItvJP-9BMxMdpgU6D2ZpBypvLssziSkv1l3LqigPovW0rUqqt3ZnM803GLQr',\n",
276
+ " 'width': 4000}],\n",
277
+ " 'place_id': 'ChIJV3Ra-NOY4jARZsqKoJRW5PE',\n",
278
+ " 'plus_code': {'compound_code': 'PGHF+R8 Bangkok',\n",
279
+ " 'global_code': '7P52PGHF+R8'},\n",
280
+ " 'rating': 4.8,\n",
281
+ " 'reference': 'ChIJV3Ra-NOY4jARZsqKoJRW5PE',\n",
282
+ " 'scope': 'GOOGLE',\n",
283
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
284
+ " 'user_ratings_total': 121,\n",
285
+ " 'vicinity': '68 Amon Rattana Dilok Alley, Si Phraya, Bang Rak'},\n",
286
+ " {'business_status': 'OPERATIONAL',\n",
287
+ " 'geometry': {'location': {'lat': 13.7371139, 'lng': 100.51473},\n",
288
+ " 'viewport': {'northeast': {'lat': 13.73846577989272,\n",
289
+ " 'lng': 100.5160974298927},\n",
290
+ " 'southwest': {'lat': 13.73576612010728, 'lng': 100.5133977701073}}},\n",
291
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
292
+ " 'icon_background_color': '#FF9E67',\n",
293
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
294
+ " 'name': 'Khao Moo Daeng Si Morakot',\n",
295
+ " 'opening_hours': {'open_now': True},\n",
296
+ " 'photos': [{'height': 3456,\n",
297
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/114367741789682073061\">bow nattanan</a>'],\n",
298
+ " 'photo_reference': 'AelY_CuAScQz_jbH-RnBWWRu35qLVPUsdpn6IhQMTjZbWTUNtRcipMpBEXdYCYlSVqiUytyvQPwfikhEL6xxlRUzg3ICmv-_y7avxFGZuACY24WHhebqgDRH3UHGM1pTPstHZE-6GkfOOmbhbnuVllmWxF6dJW49LUhflcnuxgWzUsisJn6I',\n",
299
+ " 'width': 4608}],\n",
300
+ " 'place_id': 'ChIJ-bLUEyeZ4jARupp8yg3g8MA',\n",
301
+ " 'plus_code': {'compound_code': 'PGP7+RV Bangkok',\n",
302
+ " 'global_code': '7P52PGP7+RV'},\n",
303
+ " 'price_level': 2,\n",
304
+ " 'rating': 4.3,\n",
305
+ " 'reference': 'ChIJ-bLUEyeZ4jARupp8yg3g8MA',\n",
306
+ " 'scope': 'GOOGLE',\n",
307
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
308
+ " 'user_ratings_total': 1845,\n",
309
+ " 'vicinity': '80 82 Sukon 1 Alley, Talat Noi, Samphanthawong'},\n",
310
+ " {'business_status': 'OPERATIONAL',\n",
311
+ " 'geometry': {'location': {'lat': 13.74873, 'lng': 100.5419459},\n",
312
+ " 'viewport': {'northeast': {'lat': 13.75011277989272,\n",
313
+ " 'lng': 100.5432604798927},\n",
314
+ " 'southwest': {'lat': 13.74741312010728, 'lng': 100.5405608201073}}},\n",
315
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
316
+ " 'icon_background_color': '#FF9E67',\n",
317
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
318
+ " 'name': 'Krua Aroi',\n",
319
+ " 'opening_hours': {'open_now': True},\n",
320
+ " 'photos': [{'height': 4032,\n",
321
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/106167940718102589718\">A Google User</a>'],\n",
322
+ " 'photo_reference': 'AelY_CsdYwIyao-ZFeTbGvRcNBGLX_DE8tjTyqyvPTYtQJnqD66SqInRcTchTNu28eK_abcYwwfeCz3UJZKKVoFDo57kPGhpEE2XwrHel2c_3QTgRmo0eVVXewUP0du8S0VNpM2VaOcvaWd3gY11DsW6f_evb9Ke8cUyJq2-YEkkiGkCmXTL',\n",
323
+ " 'width': 3024}],\n",
324
+ " 'place_id': 'ChIJ371CmcWe4jARYiOXygYM3zY',\n",
325
+ " 'plus_code': {'compound_code': 'PGXR+FQ Bangkok',\n",
326
+ " 'global_code': '7P52PGXR+FQ'},\n",
327
+ " 'price_level': 1,\n",
328
+ " 'rating': 4.5,\n",
329
+ " 'reference': 'ChIJ371CmcWe4jARYiOXygYM3zY',\n",
330
+ " 'scope': 'GOOGLE',\n",
331
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
332
+ " 'user_ratings_total': 198,\n",
333
+ " 'vicinity': '17 ซอย ราชดำริ1 Lumphini, Pathum Wan'},\n",
334
+ " {'business_status': 'OPERATIONAL',\n",
335
+ " 'geometry': {'location': {'lat': 13.7526881, 'lng': 100.5418073},\n",
336
+ " 'viewport': {'northeast': {'lat': 13.75407252989272,\n",
337
+ " 'lng': 100.5431658798927},\n",
338
+ " 'southwest': {'lat': 13.75137287010728, 'lng': 100.5404662201073}}},\n",
339
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
340
+ " 'icon_background_color': '#FF9E67',\n",
341
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
342
+ " 'name': 'Sakha Restaurant',\n",
343
+ " 'opening_hours': {'open_now': True},\n",
344
+ " 'photos': [{'height': 4032,\n",
345
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/100517471815290245216\">Morris</a>'],\n",
346
+ " 'photo_reference': 'AelY_CvkKNi1XCRF8KXUW4vPRhWopBByEvtowejh1kBeT9SwxvR55Ynpf185gaGQl5MrWM9BHzPZoZcUnMT9CSY_xbJpcye2pYQw2NsYKn3oaF0i_YNLLLyLkLkyBm7XdMjscrqUF89HcmpJg_O8eG0SuRf_iBEc-WHRUWlA0xZnI8SbDWgW',\n",
347
+ " 'width': 3024}],\n",
348
+ " 'place_id': 'ChIJVf0_Fsae4jARu_sU5nUULtA',\n",
349
+ " 'plus_code': {'compound_code': 'QG3R+3P Bangkok',\n",
350
+ " 'global_code': '7P52QG3R+3P'},\n",
351
+ " 'rating': 4.5,\n",
352
+ " 'reference': 'ChIJVf0_Fsae4jARu_sU5nUULtA',\n",
353
+ " 'scope': 'GOOGLE',\n",
354
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
355
+ " 'user_ratings_total': 58,\n",
356
+ " 'vicinity': '447/37 Soi Ratchaprarop 4, Makkasan, Ratchathewi'},\n",
357
+ " {'business_status': 'OPERATIONAL',\n",
358
+ " 'geometry': {'location': {'lat': 13.7453562, 'lng': 100.5337972},\n",
359
+ " 'viewport': {'northeast': {'lat': 13.74668762989272,\n",
360
+ " 'lng': 100.5351349798927},\n",
361
+ " 'southwest': {'lat': 13.74398797010728, 'lng': 100.5324353201073}}},\n",
362
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
363
+ " 'icon_background_color': '#FF9E67',\n",
364
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
365
+ " 'name': 'Ohkajhu Siam Square One',\n",
366
+ " 'opening_hours': {'open_now': True},\n",
367
+ " 'photos': [{'height': 3072,\n",
368
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/116484297774759708187\">John May</a>'],\n",
369
+ " 'photo_reference': 'AelY_Cuuyz5uSSoYGhoYaP2PNEsMAzCaLdkXuWl3EzGLUAPE9JFPtUPfRJFxKC2N4rJ2PN5zXc5DaqVdM8BQSAbbEoG1OLLLl2d8swBr781Gy83a4PggxNAQyLy9EkzldTr87T_ruEK_TemfvGuHUw3BsttLv3ORmvKNn5qy3YqNq5dId9CF',\n",
370
+ " 'width': 4080}],\n",
371
+ " 'place_id': 'ChIJV157mDGZ4jARrvO4db7HAvw',\n",
372
+ " 'plus_code': {'compound_code': 'PGWM+4G Bangkok',\n",
373
+ " 'global_code': '7P52PGWM+4G'},\n",
374
+ " 'rating': 4.3,\n",
375
+ " 'reference': 'ChIJV157mDGZ4jARrvO4db7HAvw',\n",
376
+ " 'scope': 'GOOGLE',\n",
377
+ " 'types': ['restaurant',\n",
378
+ " 'store',\n",
379
+ " 'health',\n",
380
+ " 'food',\n",
381
+ " 'point_of_interest',\n",
382
+ " 'establishment'],\n",
383
+ " 'user_ratings_total': 1339,\n",
384
+ " 'vicinity': 'Unit #SS 3009, 388 Rama I Rd, Pathum Wan'},\n",
385
+ " {'business_status': 'OPERATIONAL',\n",
386
+ " 'geometry': {'location': {'lat': 13.7466714, 'lng': 100.5398638},\n",
387
+ " 'viewport': {'northeast': {'lat': 13.74802122989272,\n",
388
+ " 'lng': 100.5412136298927},\n",
389
+ " 'southwest': {'lat': 13.74532157010728, 'lng': 100.5385139701073}}},\n",
390
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
391
+ " 'icon_background_color': '#FF9E67',\n",
392
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
393
+ " 'name': 'Baan Ying Isan & Grill, Floor 3',\n",
394
+ " 'opening_hours': {'open_now': True},\n",
395
+ " 'photos': [{'height': 3024,\n",
396
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/113103653740302511759\">A Google User</a>'],\n",
397
+ " 'photo_reference': 'AelY_CspZumKXxG8sJ8daiteT7vHlNzChAc0pI8oIGKlhy-Bxf--jInJCBJOvSpFjudQCNLDLXxxrouUBj3OhvGlUFr5lqVPfifPzxgl8IZd4yRtaIxEi9TyV3iYNY8wXG_T4h_m2gq1HC4fddLt0V1269golC2EZMe_17ZQC_nB4JeSwa6c',\n",
398
+ " 'width': 4032}],\n",
399
+ " 'place_id': 'ChIJp04t5s-e4jARy8oMsCZT4fg',\n",
400
+ " 'plus_code': {'compound_code': 'PGWQ+MW Bangkok',\n",
401
+ " 'global_code': '7P52PGWQ+MW'},\n",
402
+ " 'rating': 4.1,\n",
403
+ " 'reference': 'ChIJp04t5s-e4jARy8oMsCZT4fg',\n",
404
+ " 'scope': 'GOOGLE',\n",
405
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
406
+ " 'user_ratings_total': 386,\n",
407
+ " 'vicinity': '4, 4/1-4/2,4/4, Central World, 3rd Floor, Rajdamri Road, Pathumwan, Pathum Wan'},\n",
408
+ " {'business_status': 'OPERATIONAL',\n",
409
+ " 'geometry': {'location': {'lat': 13.734214, 'lng': 100.5273655},\n",
410
+ " 'viewport': {'northeast': {'lat': 13.73559442989272,\n",
411
+ " 'lng': 100.5287203298927},\n",
412
+ " 'southwest': {'lat': 13.73289477010728, 'lng': 100.5260206701073}}},\n",
413
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
414
+ " 'icon_background_color': '#FF9E67',\n",
415
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
416
+ " 'name': 'Chula 50 Kitchen',\n",
417
+ " 'opening_hours': {'open_now': True},\n",
418
+ " 'photos': [{'height': 3024,\n",
419
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/117331921612988982216\">Nijaya</a>'],\n",
420
+ " 'photo_reference': 'AelY_Cue0Qd_3l-tqxhyZia3e_w4-DLz0Ri4w653dOtxyC2eJJoh12tryLcQpjpDAM8DlKa-7kcTbKauBMr0qzy3616MwlGLaErKZ05AKouqIMXTx_38Q7xNhVGsgpZxL8Bh9w7hFM2QKvoVpvj-10qpzkeIsn7cVTKQTPKo3zBjwQ0duMhm',\n",
421
+ " 'width': 4032}],\n",
422
+ " 'place_id': 'ChIJcQ8J1TCZ4jARRBaANjybQI0',\n",
423
+ " 'plus_code': {'compound_code': 'PGMG+MW Bangkok',\n",
424
+ " 'global_code': '7P52PGMG+MW'},\n",
425
+ " 'price_level': 1,\n",
426
+ " 'rating': 4.1,\n",
427
+ " 'reference': 'ChIJcQ8J1TCZ4jARRBaANjybQI0',\n",
428
+ " 'scope': 'GOOGLE',\n",
429
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
430
+ " 'user_ratings_total': 821,\n",
431
+ " 'vicinity': '262 ซ. จุฬาลงกรณ์ 50 Wang Mai, Pathum Wan'},\n",
432
+ " {'business_status': 'OPERATIONAL',\n",
433
+ " 'geometry': {'location': {'lat': 13.7352442, 'lng': 100.5421743},\n",
434
+ " 'viewport': {'northeast': {'lat': 13.73655452989272,\n",
435
+ " 'lng': 100.5436026298927},\n",
436
+ " 'southwest': {'lat': 13.73385487010728, 'lng': 100.5409029701073}}},\n",
437
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
438
+ " 'icon_background_color': '#FF9E67',\n",
439
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
440
+ " 'name': 'Khrua Nai Baan',\n",
441
+ " 'opening_hours': {'open_now': True},\n",
442
+ " 'photos': [{'height': 4032,\n",
443
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/100481796849900824855\">Daniel Sakariassen</a>'],\n",
444
+ " 'photo_reference': 'AelY_CudWjlIIrn7sYi0vjAlCBMBFA2jctZs7lPY6VPrur2IqGoYiPrs1GlW3aIjDXE01_kWQMcT5feI36FIveSlU3ieF-nJVjrohwkABMWchRd8srOc_SrVPVIdSFpW7AequqSqP3ZNXZx2rsb4HPcFwTY3UToi0WsKMo-6B7ouEKX2m_uD',\n",
445
+ " 'width': 3024}],\n",
446
+ " 'place_id': 'ChIJy-yYmtme4jARWdKwmvIB9Gc',\n",
447
+ " 'plus_code': {'compound_code': 'PGPR+3V Bangkok',\n",
448
+ " 'global_code': '7P52PGPR+3V'},\n",
449
+ " 'price_level': 2,\n",
450
+ " 'rating': 4.3,\n",
451
+ " 'reference': 'ChIJy-yYmtme4jARWdKwmvIB9Gc',\n",
452
+ " 'scope': 'GOOGLE',\n",
453
+ " 'types': ['meal_delivery',\n",
454
+ " 'meal_takeaway',\n",
455
+ " 'restaurant',\n",
456
+ " 'food',\n",
457
+ " 'point_of_interest',\n",
458
+ " 'establishment'],\n",
459
+ " 'user_ratings_total': 932,\n",
460
+ " 'vicinity': '90/2 ซอยหลังสวน ถนนเพลินจิต Lumphini, Pathum Wan'},\n",
461
+ " {'business_status': 'OPERATIONAL',\n",
462
+ " 'geometry': {'location': {'lat': 13.7589595, 'lng': 100.5113613},\n",
463
+ " 'viewport': {'northeast': {'lat': 13.76031872989272,\n",
464
+ " 'lng': 100.5127062798927},\n",
465
+ " 'southwest': {'lat': 13.75761907010728, 'lng': 100.5100066201073}}},\n",
466
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
467
+ " 'icon_background_color': '#FF9E67',\n",
468
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
469
+ " 'name': 'Neua Tun Nang Loeng',\n",
470
+ " 'opening_hours': {'open_now': True},\n",
471
+ " 'photos': [{'height': 3024,\n",
472
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/101204685801512010222\">A Google User</a>'],\n",
473
+ " 'photo_reference': 'AelY_Csbz9BJnMDSTKpGaYc2UvzhzdtxVsEuN9zPibqGNw2C2fEimD9LXx8c2-fVd_gZCMGpVu48ihL5XCgUSq9x-A1xkggIsrEXnAXxYFnDfBcrdDkgibnvo1064LfDzbB8kn9v3kiazhGDHsBADM5LGnQtE2jY1GqCDuwYQtsWuZyhQy4B',\n",
474
+ " 'width': 4032}],\n",
475
+ " 'place_id': 'ChIJ35IPmECZ4jARvr7OecVtBGM',\n",
476
+ " 'plus_code': {'compound_code': 'QG56+HG Bangkok',\n",
477
+ " 'global_code': '7P52QG56+HG'},\n",
478
+ " 'price_level': 1,\n",
479
+ " 'rating': 4.6,\n",
480
+ " 'reference': 'ChIJ35IPmECZ4jARvr7OecVtBGM',\n",
481
+ " 'scope': 'GOOGLE',\n",
482
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
483
+ " 'user_ratings_total': 890,\n",
484
+ " 'vicinity': '11 Soi Nakhon Sawan 2, Wat Sommanat, Pom Prap Sattru Phai'},\n",
485
+ " {'business_status': 'OPERATIONAL',\n",
486
+ " 'geometry': {'location': {'lat': 13.7461102, 'lng': 100.5236554},\n",
487
+ " 'viewport': {'northeast': {'lat': 13.74746827989272,\n",
488
+ " 'lng': 100.5249552798927},\n",
489
+ " 'southwest': {'lat': 13.74476862010728, 'lng': 100.5222556201073}}},\n",
490
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
491
+ " 'icon_background_color': '#FF9E67',\n",
492
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
493
+ " 'name': 'Ming Phochana',\n",
494
+ " 'opening_hours': {'open_now': True},\n",
495
+ " 'photos': [{'height': 2268,\n",
496
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/106198363291758062631\">Sukhum Truengtrachitkul</a>'],\n",
497
+ " 'photo_reference': 'AelY_CufYCHRj9dZvIuzw0tboFiI0XHrYEll0QykjNn8dWeEXJKbqFxHGQ5VKpP5U4aKp47YplK6aZS1zE_yImOIetDhhti2ChHZhfOZ69FRoaxF-8RbUtG_qxFxf4MZo3hlPRYUTwpHk7p_wKx-SNfTYKjlwf8ZAR4R8_mKAys8j8jGl5Td',\n",
498
+ " 'width': 4032}],\n",
499
+ " 'place_id': 'ChIJmd3lCSmZ4jARYoIvzwoxiho',\n",
500
+ " 'plus_code': {'compound_code': 'PGWF+CF Bangkok',\n",
501
+ " 'global_code': '7P52PGWF+CF'},\n",
502
+ " 'rating': 4.2,\n",
503
+ " 'reference': 'ChIJmd3lCSmZ4jARYoIvzwoxiho',\n",
504
+ " 'scope': 'GOOGLE',\n",
505
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
506
+ " 'user_ratings_total': 325,\n",
507
+ " 'vicinity': '683 ถนน บรรทัดทอง Wang Mai, Pathum Wan'},\n",
508
+ " {'business_status': 'OPERATIONAL',\n",
509
+ " 'geometry': {'location': {'lat': 13.7610679, 'lng': 100.5374132},\n",
510
+ " 'viewport': {'northeast': {'lat': 13.76240467989272,\n",
511
+ " 'lng': 100.5387567298927},\n",
512
+ " 'southwest': {'lat': 13.75970502010728, 'lng': 100.5360570701073}}},\n",
513
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
514
+ " 'icon_background_color': '#FF9E67',\n",
515
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
516
+ " 'name': 'Northeastern Thai',\n",
517
+ " 'opening_hours': {'open_now': True},\n",
518
+ " 'photos': [{'height': 3024,\n",
519
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/100883581885709245229\">Tatsuya Sonnyu</a>'],\n",
520
+ " 'photo_reference': 'AelY_Ct74WJjR8PUcoaAve9axKBMrRM-xEchZgV5SVxFnD06spQv_PNTun5eJIrX6wkBlgQNnjpn0T8fdanCmymXIklKzRBmqyABjIZqcjG-ojvBRxuS7De1741nfY8mO7JjHy9sImxJ_CSPBbPFwqagjUJ6iFZDESGi0kaAdyqXbrAuWLcB',\n",
521
+ " 'width': 4032}],\n",
522
+ " 'place_id': 'ChIJZ5XY5bae4jARUv0Ljrhk2ug',\n",
523
+ " 'plus_code': {'compound_code': 'QG6P+CX Bangkok',\n",
524
+ " 'global_code': '7P52QG6P+CX'},\n",
525
+ " 'price_level': 1,\n",
526
+ " 'rating': 3.9,\n",
527
+ " 'reference': 'ChIJZ5XY5bae4jARUv0Ljrhk2ug',\n",
528
+ " 'scope': 'GOOGLE',\n",
529
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
530
+ " 'user_ratings_total': 418,\n",
531
+ " 'vicinity': 'ซอย ราชวิถี 9 Ratchawithi Rd, Thanon Phaya Thai, Ratchathewi'},\n",
532
+ " {'business_status': 'OPERATIONAL',\n",
533
+ " 'geometry': {'location': {'lat': 13.749108, 'lng': 100.5411004},\n",
534
+ " 'viewport': {'northeast': {'lat': 13.75046297989272,\n",
535
+ " 'lng': 100.5424115298927},\n",
536
+ " 'southwest': {'lat': 13.74776332010728, 'lng': 100.5397118701073}}},\n",
537
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
538
+ " 'icon_background_color': '#FF9E67',\n",
539
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
540
+ " 'name': 'Jsuneetomyum',\n",
541
+ " 'opening_hours': {'open_now': True},\n",
542
+ " 'photos': [{'height': 2704,\n",
543
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/117204015866668242289\">Colin Chow</a>'],\n",
544
+ " 'photo_reference': 'AelY_Cv9jauFO6pQIMlVhhs57GV9vzw8OolyYPFN2rgIkWJiUO9fILxTiUz8p9PowmrLvt8E3mDDaq3CO85H_ffBHWSy75SYaLWA8gFskKidajvrpnrV1l52-nxFQC9MVmN3Pi9JzNK0ZwRUZwa2Ej1zFXxUr7qErvlmgo9BVVWHQ2rO82N4',\n",
545
+ " 'width': 4056}],\n",
546
+ " 'place_id': 'ChIJP6dwhsWe4jARU7roepjvIqs',\n",
547
+ " 'plus_code': {'compound_code': 'PGXR+JC Bangkok',\n",
548
+ " 'global_code': '7P52PGXR+JC'},\n",
549
+ " 'price_level': 1,\n",
550
+ " 'rating': 4.4,\n",
551
+ " 'reference': 'ChIJP6dwhsWe4jARU7roepjvIqs',\n",
552
+ " 'scope': 'GOOGLE',\n",
553
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
554
+ " 'user_ratings_total': 358,\n",
555
+ " 'vicinity': '9 Ratchadamri Rd, Lumphini, Pathum Wan'},\n",
556
+ " {'business_status': 'OPERATIONAL',\n",
557
+ " 'geometry': {'location': {'lat': 13.7417739, 'lng': 100.5491335},\n",
558
+ " 'viewport': {'northeast': {'lat': 13.74312892989272,\n",
559
+ " 'lng': 100.5504482798927},\n",
560
+ " 'southwest': {'lat': 13.74042927010728, 'lng': 100.5477486201073}}},\n",
561
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
562
+ " 'icon_background_color': '#FF9E67',\n",
563
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
564
+ " 'name': 'Breakfast Story Phloen Chit',\n",
565
+ " 'opening_hours': {'open_now': True},\n",
566
+ " 'photos': [{'height': 3024,\n",
567
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/113103653740302511759\">A Google User</a>'],\n",
568
+ " 'photo_reference': 'AelY_Cv1teqBgEXWGqLIjb3G5utyeJsPrT0Q7DbbVH3aZ4jsAL9t6pcMr-H69pIL41rOh197j1nn6Kl0LHiFZapKTpmO90p_zRGGnaXuixnbInXBDvVnIvQYGcAoxMxpBLqBN3aYNugtD8qAJ3vdugNmEbMBdh9_Mh1gu8Yydg7STairdPFc',\n",
569
+ " 'width': 4032}],\n",
570
+ " 'place_id': 'ChIJF5udxZSf4jARicc-U9Mo4y0',\n",
571
+ " 'plus_code': {'compound_code': 'PGRX+PM Bangkok',\n",
572
+ " 'global_code': '7P52PGRX+PM'},\n",
573
+ " 'price_level': 2,\n",
574
+ " 'rating': 4.6,\n",
575
+ " 'reference': 'ChIJF5udxZSf4jARicc-U9Mo4y0',\n",
576
+ " 'scope': 'GOOGLE',\n",
577
+ " 'types': ['restaurant',\n",
578
+ " 'cafe',\n",
579
+ " 'store',\n",
580
+ " 'food',\n",
581
+ " 'point_of_interest',\n",
582
+ " 'establishment'],\n",
583
+ " 'user_ratings_total': 1295,\n",
584
+ " 'vicinity': '888, Mahatun Plaza, 3rd Floor (above Blue Cheri, 34-35 Phloen Chit Rd, Lumphini, Pathum Wan'},\n",
585
+ " {'business_status': 'OPERATIONAL',\n",
586
+ " 'geometry': {'location': {'lat': 13.7562456, 'lng': 100.5298877},\n",
587
+ " 'viewport': {'northeast': {'lat': 13.75758012989272,\n",
588
+ " 'lng': 100.5311803298927},\n",
589
+ " 'southwest': {'lat': 13.75488047010728, 'lng': 100.5284806701073}}},\n",
590
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
591
+ " 'icon_background_color': '#FF9E67',\n",
592
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
593
+ " 'name': 'Pa Sa',\n",
594
+ " 'opening_hours': {'open_now': True},\n",
595
+ " 'photos': [{'height': 3024,\n",
596
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/101031521481016420424\">A Google User</a>'],\n",
597
+ " 'photo_reference': 'AelY_CsGwvDh4wKxt4LNES80egluzjVer1Lz-CaLyfWPJF-1od9NacjWN18KU-syXwhlRFIUJTP-W__PRNLLUeX2LqBVEosnamzAIk3Giok-BxGpNspNEVWFH-NFlNFio4-LnLoLkDCk5bdWyRVuKV73zK_1J2oh2zGXI40Ap5HZbELIaU1p',\n",
598
+ " 'width': 3024}],\n",
599
+ " 'place_id': 'ChIJvTupReyf4jARinKvcO3aE-U',\n",
600
+ " 'plus_code': {'compound_code': 'QG4H+FW Bangkok',\n",
601
+ " 'global_code': '7P52QG4H+FW'},\n",
602
+ " 'rating': 4.9,\n",
603
+ " 'reference': 'ChIJvTupReyf4jARinKvcO3aE-U',\n",
604
+ " 'scope': 'GOOGLE',\n",
605
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
606
+ " 'user_ratings_total': 31,\n",
607
+ " 'vicinity': '268 Soi Phetchaburi 5, Thung Phaya Thai, Ratchathewi'},\n",
608
+ " {'business_status': 'OPERATIONAL',\n",
609
+ " 'geometry': {'location': {'lat': 13.7458231, 'lng': 100.5396662},\n",
610
+ " 'viewport': {'northeast': {'lat': 13.74715152989272,\n",
611
+ " 'lng': 100.5410131298927},\n",
612
+ " 'southwest': {'lat': 13.74445187010728, 'lng': 100.5383134701073}}},\n",
613
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
614
+ " 'icon_background_color': '#FF9E67',\n",
615
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
616
+ " 'name': 'ร้านอาหาร ฮั่วเซ่งฮง เซ็นทรัลเวิลด์ Huasenghong',\n",
617
+ " 'opening_hours': {'open_now': True},\n",
618
+ " 'photos': [{'height': 3024,\n",
619
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/113103653740302511759\">A Google User</a>'],\n",
620
+ " 'photo_reference': 'AelY_CuFQyEMHHndpPy2BzdJqQIrL7AaFpDEVRr_eMPa10OKfl8O8U3yv0QlgioUYsMbfSteESvyImipaWEEfUTSIfDyLuyqLrX57f2iZv4W0PyDtY3kW4TgXGROqiSXwwDYW1BsiQrRH505RgFIvb5bCWWSIk4gwNBIlU41SPzLzpGXIIAR',\n",
621
+ " 'width': 4032}],\n",
622
+ " 'place_id': 'ChIJbXxW6M-e4jARE0x7fKFvHb4',\n",
623
+ " 'plus_code': {'compound_code': 'PGWQ+8V Bangkok',\n",
624
+ " 'global_code': '7P52PGWQ+8V'},\n",
625
+ " 'price_level': 2,\n",
626
+ " 'rating': 4.6,\n",
627
+ " 'reference': 'ChIJbXxW6M-e4jARE0x7fKFvHb4',\n",
628
+ " 'scope': 'GOOGLE',\n",
629
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
630
+ " 'user_ratings_total': 1045,\n",
631
+ " 'vicinity': '4 Ratchadamri Rd, Pathum Wan'},\n",
632
+ " {'business_status': 'OPERATIONAL',\n",
633
+ " 'geometry': {'location': {'lat': 13.7292254, 'lng': 100.534336},\n",
634
+ " 'viewport': {'northeast': {'lat': 13.73059442989272,\n",
635
+ " 'lng': 100.5356763298927},\n",
636
+ " 'southwest': {'lat': 13.72789477010728, 'lng': 100.5329766701073}}},\n",
637
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/restaurant-71.png',\n",
638
+ " 'icon_background_color': '#FF9E67',\n",
639
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/restaurant_pinlet',\n",
640
+ " 'name': 'Shangarila Restaurant Thaniya',\n",
641
+ " 'opening_hours': {'open_now': True},\n",
642
+ " 'photos': [{'height': 3024,\n",
643
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/104331204058144967486\">พิชญุตม์ โชติวรรณ</a>'],\n",
644
+ " 'photo_reference': 'AelY_CvT3RCsDG7ySTfNot6L3dJrTxaJtW-N7c3qSSTZSEmRYuHd-fS1bvySy0Ov3L7k6ATQc7I3wxDYYj6E5PxP8F8zhCxekNCEZ-oSy4PLqN6MKQMxkRQWnQBawLgj772M2XGB9g9PggVuBuu6Ws1HWAL0tX_Uud73An5fKKOEc2STFv26',\n",
645
+ " 'width': 4032}],\n",
646
+ " 'place_id': 'ChIJ2_m48Cuf4jARqVdR9So3yvA',\n",
647
+ " 'plus_code': {'compound_code': 'PGHM+MP Bangkok',\n",
648
+ " 'global_code': '7P52PGHM+MP'},\n",
649
+ " 'price_level': 3,\n",
650
+ " 'rating': 4.4,\n",
651
+ " 'reference': 'ChIJ2_m48Cuf4jARqVdR9So3yvA',\n",
652
+ " 'scope': 'GOOGLE',\n",
653
+ " 'types': ['restaurant', 'food', 'point_of_interest', 'establishment'],\n",
654
+ " 'user_ratings_total': 1982,\n",
655
+ " 'vicinity': '58/3-9 Si Lom Rd, Suriya Wong, Bang Rak'}]"
656
+ ]
657
+ },
658
+ "execution_count": 45,
659
+ "metadata": {},
660
+ "output_type": "execute_result"
661
+ }
662
+ ],
663
+ "source": [
664
+ "def nearby_search(keyword:str, location:str, radius=2000, place_type=None):\n",
665
+ " # Retrieve the API key from environment variables\n",
666
+ " api_key = os.getenv('GPLACES_API_KEY')\n",
667
+ "\n",
668
+ " if not api_key:\n",
669
+ " raise ValueError(\"API key not found. Please set the GOOGLE_MAPS_API_KEY environment variable.\")\n",
670
+ "\n",
671
+ " # Define the endpoint URL\n",
672
+ " url = \"https://maps.googleapis.com/maps/api/place/nearbysearch/json\"\n",
673
+ "\n",
674
+ " # Set up the parameters for the request\n",
675
+ " params = {\n",
676
+ " 'keyword': keyword,\n",
677
+ " 'location': location,\n",
678
+ " 'radius': radius,\n",
679
+ " 'type': place_type,\n",
680
+ " 'key': api_key,\n",
681
+ " }\n",
682
+ "\n",
683
+ " # Send the GET request to the Google Maps API\n",
684
+ " response = requests.get(url, params=params)\n",
685
+ "\n",
686
+ " # Check if the request was successful\n",
687
+ " if response.status_code != 200:\n",
688
+ " raise Exception(f\"Error with request: {response.status_code}, {response.text}\")\n",
689
+ "\n",
690
+ " # Parse the JSON response\n",
691
+ " data = response.json()\n",
692
+ "\n",
693
+ " # Return the response data\n",
694
+ " return data['results']\n",
695
+ "\n",
696
+ "\n",
697
+ "# Example usage\n",
698
+ "location = \"13.744677,100.5295593\" # Latitude and Longitude\n",
699
+ "keyword = \"ร้านอาหาร\"\n",
700
+ "search_results = nearby_search(keyword, location)\n",
701
+ "search_results"
702
+ ]
703
+ }
704
+ ],
705
+ "metadata": {
706
+ "kernelspec": {
707
+ "display_name": "Python 3",
708
+ "language": "python",
709
+ "name": "python3"
710
+ },
711
+ "language_info": {
712
+ "codemirror_mode": {
713
+ "name": "ipython",
714
+ "version": 3
715
+ },
716
+ "file_extension": ".py",
717
+ "mimetype": "text/x-python",
718
+ "name": "python",
719
+ "nbconvert_exporter": "python",
720
+ "pygments_lexer": "ipython3",
721
+ "version": "3.11.9"
722
+ }
723
+ },
724
+ "nbformat": 4,
725
+ "nbformat_minor": 2
726
+ }
gplace.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ import utils
4
+ from langchain_core.tools import tool
5
+
6
+ utils.load_env()
7
+
8
+
9
+ def find_place_from_text(input_text, location=None, radius=2000):
10
+ "Finds a place based on text input and location bias."
11
+ # Retrieve the API key from environment variables
12
+ api_key = os.getenv('GPLACES_API_KEY')
13
+
14
+ if not api_key:
15
+ raise ValueError("API key not found. Please set the GOOGLE_MAPS_API_KEY environment variable.")
16
+
17
+ # Define the endpoint URL
18
+ url = "https://maps.googleapis.com/maps/api/place/findplacefromtext/json"
19
+
20
+ # Define the parameters for the request
21
+ params = {
22
+ 'fields': 'formatted_address,name,rating,opening_hours,geometry',
23
+ 'input': input_text,
24
+ 'inputtype': 'textquery',
25
+ 'key': api_key
26
+ }
27
+
28
+ params['locationbias'] = f'circle:{radius}@{location}' if location is not None and radius is not None else None
29
+
30
+ # Make the request to the Google Maps API
31
+ response = requests.get(url, params=params)
32
+
33
+ # Check if the request was successful
34
+ if response.status_code == 200:
35
+ return response.json() # Return the JSON response
36
+ else:
37
+ response.raise_for_status() # Raise an exception for HTTP errors
38
+
39
+
40
+ def find_location(input_text:str, location:str=None, radius=2000):
41
+ """Returns the latitude and longitude of a location based on text input."""
42
+ # Call the find_place_from_text function to get the location data
43
+ data = find_place_from_text(input_text, location, radius)
44
+
45
+ # Extract the latitude and longitude from the response
46
+ candidates = data.get('candidates', [])
47
+ if len(candidates)==0:
48
+ raise ValueError("No location found.")
49
+
50
+ # Assuming we're taking the first candidate
51
+ geometry = candidates[0].get('geometry', {})
52
+ location = geometry.get('location', {})
53
+
54
+ latitude = location.get('lat')
55
+ longitude = location.get('lng')
56
+
57
+ if latitude is None or longitude is None:
58
+ raise ValueError("Latitude or Longitude not found in the response.")
59
+
60
+ # Return the latitude and longitude as a formatted string
61
+ return f"{latitude},{longitude}"
62
+
63
+
64
+ def nearby_search(keyword:str, location:str, radius=2000, place_type=None):
65
+ """Searches for nearby places based on a keyword and location."""
66
+ # Retrieve the API key from environment variables
67
+ api_key = os.getenv('GPLACES_API_KEY')
68
+
69
+ if not api_key:
70
+ raise ValueError("API key not found. Please set the GOOGLE_MAPS_API_KEY environment variable.")
71
+
72
+ # Define the endpoint URL
73
+ url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"
74
+
75
+ # Set up the parameters for the request
76
+ params = {
77
+ 'keyword': keyword,
78
+ 'location': location,
79
+ 'radius': radius,
80
+ 'type': place_type,
81
+ 'key': api_key,
82
+ }
83
+
84
+ # Send the GET request to the Google Maps API
85
+ response = requests.get(url, params=params)
86
+
87
+ # Check if the request was successful
88
+ if response.status_code != 200:
89
+ raise Exception(f"Error with request: {response.status_code}, {response.text}")
90
+
91
+ # Parse the JSON response
92
+ data = response.json()
93
+
94
+ # Return the response data
95
+ return data['results']
prompt.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "Agent1": {
3
+ "Prompt": "",
4
+ "Greet": ""
5
+ },
6
+ "Agent2": {
7
+ "Prompt": "",
8
+ "Greet": ""
9
+ }
10
+ }
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ langchain
3
+ langchain-core
4
+ langchain-community
5
+ langchain-openai
6
+ langchain-chroma
7
+ langchain-text-splitters
8
+
9
+ googlemaps
tools.ipynb ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "# gplace_tools.py\n",
10
+ "from gplace import find_place_from_text, find_location, nearby_search\n",
11
+ "from langgraph.prebuilt import ToolNode\n",
12
+ "from langchain_core.tools import tool\n",
13
+ "\n",
14
+ "find_place_from_text = tool(find_place_from_text)\n",
15
+ "find_location = tool(find_location)\n",
16
+ "nearby_search = tool(nearby_search)\n",
17
+ "\n",
18
+ "tools = [find_place_from_text, find_location, nearby_search]\n",
19
+ "\n",
20
+ "# Create ToolNodes for each tool\n",
21
+ "tool_node = ToolNode(tools)"
22
+ ]
23
+ }
24
+ ],
25
+ "metadata": {
26
+ "kernelspec": {
27
+ "display_name": "Python 3",
28
+ "language": "python",
29
+ "name": "python3"
30
+ },
31
+ "language_info": {
32
+ "codemirror_mode": {
33
+ "name": "ipython",
34
+ "version": 3
35
+ },
36
+ "file_extension": ".py",
37
+ "mimetype": "text/x-python",
38
+ "name": "python",
39
+ "nbconvert_exporter": "python",
40
+ "pygments_lexer": "ipython3",
41
+ "version": "3.11.9"
42
+ }
43
+ },
44
+ "nbformat": 4,
45
+ "nbformat_minor": 2
46
+ }
tools.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from gplace import find_place_from_text, find_location, nearby_search
2
+ from langgraph.prebuilt import ToolNode
3
+ from langchain_core.tools import tool
4
+
5
+ find_place_from_text = tool(find_place_from_text)
6
+ find_location = tool(find_location)
7
+ nearby_search = tool(nearby_search)
8
+
9
+ tools = [find_place_from_text, find_location, nearby_search]
10
+
11
+ # Create ToolNodes for each tool
12
+ tool_node = ToolNode(tools)
13
+
14
+
utils.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+ import os
3
+
4
+
5
+ def load_env():
6
+ # Load environment variables from the .env file
7
+ load_dotenv("./API_keys.env")
8
+ # os.getenv('OPENAI_API_KEY')