DylanonWic commited on
Commit
838e061
1 Parent(s): 4640539

Upload 21 files

Browse files
Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python runtime as a parent image
2
+ FROM python:3.10-slim
3
+
4
+ RUN useradd -m -u 1000 user
5
+ USER user
6
+ ENV PATH="/home/user/.local/bin:$PATH"
7
+
8
+ # Set the working directory in the container
9
+ WORKDIR .
10
+
11
+ COPY --chown=user ./requirements.txt requirements.txt
12
+
13
+ # Copy the current directory contents into the container at /app
14
+ COPY --chown=user . /app
15
+
16
+ # Install any needed packages specified in requirements.txt
17
+ RUN pip install --no-cache-dir -r requirements.txt
18
+
19
+ # Make port 5050 available to the world outside this container
20
+ EXPOSE 5050
21
+
22
+ # Run api.py when the container launches
23
+ CMD ["python", "api.py"]
QA_sample.ipynb ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "from chatbot_multiagent import submitUserMessage\n",
10
+ "import random\n",
11
+ "from math import inf\n",
12
+ "from time import time\n",
13
+ "\n",
14
+ "def QA_sample_test(quesion_test:list[str], num_samples:int=inf):\n",
15
+ " stt = time()\n",
16
+ " # Ensure there are at least 5 lines in the list\n",
17
+ " num_samples = min(10, len(quesion_test))\n",
18
+ " sample_quesion = random.sample(quesion_test, num_samples)\n",
19
+ " \n",
20
+ " result = []\n",
21
+ " for quesion in sample_quesion:\n",
22
+ " try:\n",
23
+ " answer = submitUserMessage(quesion)\n",
24
+ " result.append({'quesion': quesion, 'answer': answer}) \n",
25
+ " except Exception as e:\n",
26
+ " result.append({'quesion': quesion, 'error': e}) \n",
27
+ " print(\"Error: \", e) \n",
28
+ " \n",
29
+ " exet = time() - stt\n",
30
+ " exet_rept = f\"average execution time: {exet/num_samples}sec.\"\n",
31
+ " print(exet_rept)\n",
32
+ " return result, exet_rept"
33
+ ]
34
+ },
35
+ {
36
+ "cell_type": "code",
37
+ "execution_count": 2,
38
+ "metadata": {},
39
+ "outputs": [
40
+ {
41
+ "name": "stdout",
42
+ "output_type": "stream",
43
+ "text": [
44
+ "Error: Error code: 500 - {'error': {'message': 'The model produced invalid content. Consider modifying your prompt if you are seeing this error persistently.', 'type': 'model_error', 'param': None, 'code': None}}\n",
45
+ "Error: Error code: 500 - {'error': {'message': 'The model produced invalid content. Consider modifying your prompt if you are seeing this error persistently.', 'type': 'model_error', 'param': None, 'code': None}}\n",
46
+ "Error: Error code: 500 - {'error': {'message': 'The model produced invalid content. Consider modifying your prompt if you are seeing this error persistently.', 'type': 'model_error', 'param': None, 'code': None}}\n",
47
+ "Error: Error code: 500 - {'error': {'message': 'The model produced invalid content. Consider modifying your prompt if you are seeing this error persistently.', 'type': 'model_error', 'param': None, 'code': None}}\n",
48
+ "average execution time: 31.43109838962555sec.\n"
49
+ ]
50
+ }
51
+ ],
52
+ "source": [
53
+ "with open('./testsets/user_question_testsets.txt', 'r') as file:\n",
54
+ " quesion_test = file.readlines() \n",
55
+ "\n",
56
+ "results, exet_rept = QA_sample_test(quesion_test, num_samples=10)"
57
+ ]
58
+ },
59
+ {
60
+ "cell_type": "code",
61
+ "execution_count": 3,
62
+ "metadata": {},
63
+ "outputs": [
64
+ {
65
+ "name": "stdout",
66
+ "output_type": "stream",
67
+ "text": [
68
+ "Results saved to testsets/QA_smaple.txt\n"
69
+ ]
70
+ }
71
+ ],
72
+ "source": [
73
+ "file_path = 'testsets/QA_smaple.txt'\n",
74
+ "\n",
75
+ "# Open the file in write mode\n",
76
+ "with open(file_path, 'w') as file:\n",
77
+ " # Iterate over each dictionary in the list\n",
78
+ " for result in results:\n",
79
+ " # Iterate over each key-value pair in the dictionary\n",
80
+ " for key, value in result.items():\n",
81
+ " # Write each key-value pair to the file\n",
82
+ " file.write(f\"{key}: \\n\\t{str(value).strip()}\\n\")\n",
83
+ " # Add a blank line between dictionaries\n",
84
+ " file.write(\"\\n\\n\")\n",
85
+ " file.write(\"-\"*200+\"\\n\")\n",
86
+ " \n",
87
+ " file.write(exet_rept)\n",
88
+ "\n",
89
+ "print(f\"Results saved to {file_path}\")"
90
+ ]
91
+ }
92
+ ],
93
+ "metadata": {
94
+ "kernelspec": {
95
+ "display_name": "Python 3",
96
+ "language": "python",
97
+ "name": "python3"
98
+ },
99
+ "language_info": {
100
+ "codemirror_mode": {
101
+ "name": "ipython",
102
+ "version": 3
103
+ },
104
+ "file_extension": ".py",
105
+ "mimetype": "text/x-python",
106
+ "name": "python",
107
+ "nbconvert_exporter": "python",
108
+ "pygments_lexer": "ipython3",
109
+ "version": "3.11.9"
110
+ }
111
+ },
112
+ "nbformat": 4,
113
+ "nbformat_minor": 2
114
+ }
api.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify
2
+ from chatbot_multiagent import submitUserMessage
3
+
4
+ app = Flask(__name__)
5
+
6
+ @app.route('/', methods=['POST'])
7
+ def chatbot():
8
+ user_message = request.json.get('message', '')
9
+
10
+ if not user_message:
11
+ return jsonify({"error": "Message is required"}), 400
12
+
13
+ try:
14
+ response = submitUserMessage(user_message)
15
+ return jsonify({"response": response})
16
+ except Exception as e:
17
+ return jsonify({"error": str(e)}), 500
18
+
19
+ if __name__ == '__main__':
20
+ app.run(host='0.0.0.0', port=5050)
api_request_test.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+
3
+ url = "http://localhost:5000"
4
+ headers = {"Content-Type": "application/json"}
5
+ data = {"message": "Hello, chatbot!"}
6
+
7
+ response = requests.post(url, json=data, headers=headers)
8
+
9
+ if response.status_code == 200:
10
+ print("Chatbot response:", response.json().get("response"))
11
+ else:
12
+ print("Error:", response.json())
app.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import gradio as gr
3
+ from chatbot_multiagent import submitUserMessage
4
+
5
+
6
+ def chat(message:str, history):
7
+ print(message)
8
+ return submitUserMessage(message)
9
+
10
+
11
+ def slow_echo_chat(message, history):
12
+ answer = submitUserMessage(message)
13
+ for i in range(len(answer)):
14
+ time.sleep(0.01)
15
+ yield answer[: i+1]
16
+
17
+
18
+ with gr.Blocks() as demo:
19
+ chatbot = gr.Chatbot(height=600)
20
+ msg = gr.Textbox()
21
+ clear = gr.ClearButton([msg, chatbot])
22
+
23
+ def respond(message, chat_history):
24
+ bot_message = submitUserMessage(message)
25
+ chat_history.append((message, bot_message))
26
+ return "", chat_history
27
+
28
+ msg.submit(respond, [msg, chatbot], [msg, chatbot])
29
+
30
+
31
+ demo.launch()
32
+
33
+ # gr.ChatInterface(chat).launch()
34
+
35
+ # interface = gr.ChatInterface(chat)
36
+ # interface.launch()
chatbot_multiagent.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
chatbot_multiagent.py ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # %%
2
+ import os
3
+ import utils
4
+
5
+ utils.load_env()
6
+ os.environ['LANGCHAIN_TRACING_V2'] = "false"
7
+
8
+ # %%
9
+ from langchain.globals import set_debug, set_verbose
10
+
11
+ set_verbose(True)
12
+ set_debug(False)
13
+
14
+ # %%
15
+ from langchain_core.messages import HumanMessage
16
+ import operator
17
+ import functools
18
+
19
+ # for llm model
20
+ from langchain_openai import ChatOpenAI
21
+ # from langchain_community.chat_models import ChatOpenAI
22
+ from tools import (
23
+ find_place_from_text,
24
+ nearby_search,
25
+ nearby_dense_community,
26
+ google_search,
27
+ population_doc_retriever,
28
+ )
29
+ from typing import Annotated, Sequence, TypedDict
30
+ from langchain_core.messages import (
31
+ AIMessage,
32
+ HumanMessage,
33
+ BaseMessage,
34
+ ToolMessage
35
+ )
36
+ from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
37
+ from langgraph.graph import END, StateGraph, START
38
+
39
+
40
+
41
+ ## tools and LLM
42
+ # Bind the tools to the model
43
+ tools = [population_doc_retriever, find_place_from_text, nearby_search, nearby_dense_community, google_search] # Include both tools if needed
44
+ # tools = [population_doc_retriever, find_place_from_text, nearby_search, google_search] # Include both tools if needed
45
+
46
+ llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
47
+
48
+ ## Create agents
49
+ def create_agent(llm, tools, system_message: str):
50
+ """Create an agent."""
51
+ prompt = ChatPromptTemplate.from_messages(
52
+ [
53
+ (
54
+ "system",
55
+ "You are a helpful AI assistant, collaborating with other assistants."
56
+ " Use the provided tools to progress towards answering the question."
57
+ " If you are unable to fully answer, that's OK, another assistant with different tools "
58
+ " will help where you left off. Execute what you can to make progress."
59
+ " If you or any of the other assistants have the final answer or deliverable,"
60
+ " "
61
+ " You have access to the following tools: {tool_names}.\n{system_message}",
62
+ ),
63
+ MessagesPlaceholder(variable_name="messages"),
64
+ ]
65
+ )
66
+ prompt = prompt.partial(system_message=system_message)
67
+ prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
68
+ #llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])
69
+ return prompt | llm.bind_tools(tools)
70
+ #agent = prompt | llm_with_tools
71
+ #return agent
72
+
73
+
74
+ ## Define state
75
+ # This defines the object that is passed between each node
76
+ # in the graph. We will create different nodes for each agent and tool
77
+ class AgentState(TypedDict):
78
+ messages: Annotated[Sequence[BaseMessage], operator.add]
79
+ sender: str
80
+
81
+
82
+ # Helper function to create a node for a given agent
83
+ def agent_node(state, agent, name):
84
+ result = agent.invoke(state)
85
+ # We convert the agent output into a format that is suitable to append to the global state
86
+ if isinstance(result, ToolMessage):
87
+ pass
88
+ else:
89
+ result = AIMessage(**result.dict(exclude={"type", "name"}), name=name)
90
+ return {
91
+ "messages": [result],
92
+ # Since we have a strict workflow, we can
93
+ # track the sender so we know who to pass to next.
94
+ "sender": name,
95
+ }
96
+
97
+
98
+ ## Define Agents Node
99
+ # Research agent and node
100
+ from prompt import agent_meta
101
+ agent_name = [meta['name'] for meta in agent_meta]
102
+
103
+ agents={}
104
+ agent_nodes={}
105
+
106
+ for meta in agent_meta:
107
+ name = meta['name']
108
+ prompt = meta['prompt']
109
+
110
+ agents[name] = create_agent(
111
+ llm,
112
+ tools,
113
+ system_message=prompt,
114
+ )
115
+
116
+ agent_nodes[name] = functools.partial(agent_node, agent=agents[name], name=name)
117
+
118
+
119
+ ## Define Tool Node
120
+ from langgraph.prebuilt import ToolNode
121
+ from typing import Literal
122
+
123
+ tool_node = ToolNode(tools)
124
+
125
+ def router(state) -> Literal["call_tool", "__end__", "continue"]:
126
+ # This is the router
127
+ messages = state["messages"]
128
+ last_message = messages[-1]
129
+ if "continue" in last_message.content:
130
+ return "continue"
131
+ if last_message.tool_calls:
132
+ # The previous agent is invoking a tool
133
+ return "call_tool"
134
+ if "%SIjfE923hf" in last_message.content:
135
+ # Any agent decided the work is done
136
+ return "__end__"
137
+ else:
138
+ return "continue"
139
+
140
+
141
+
142
+ ## Workflow Graph
143
+ workflow = StateGraph(AgentState)
144
+
145
+ # add agent nodes
146
+ for name, node in agent_nodes.items():
147
+ workflow.add_node(name, node)
148
+
149
+ workflow.add_node("call_tool", tool_node)
150
+
151
+
152
+ workflow.add_conditional_edges(
153
+ "analyst",
154
+ router,
155
+ {"continue": "data_collector", "call_tool": "call_tool", "__end__": END}
156
+ )
157
+
158
+ workflow.add_conditional_edges(
159
+ "data_collector",
160
+ router,
161
+ {"call_tool": "call_tool", "continue": "reporter", "__end__": END}
162
+ )
163
+
164
+ workflow.add_conditional_edges(
165
+ "reporter",
166
+ router,
167
+ {"continue": "data_collector", "call_tool": "call_tool", "__end__": END}
168
+ )
169
+
170
+ workflow.add_conditional_edges(
171
+ "call_tool",
172
+ # Each agent node updates the 'sender' field
173
+ # the tool calling node does not, meaning
174
+ # this edge will route back to the original agent
175
+ # who invoked the tool
176
+ lambda x: x["sender"],
177
+ {name:name for name in agent_name},
178
+ )
179
+ workflow.add_edge(START, "analyst")
180
+ graph = workflow.compile()
181
+
182
+ # %%
183
+ # from IPython.display import Image, display
184
+
185
+ # try:
186
+ # display(Image(graph.get_graph(xray=True).draw_mermaid_png()))
187
+ # except Exception:
188
+ # # This requires some extra dependencies and is optional
189
+ # pass
190
+
191
+ # %%
192
+ # question = "ร้านกาแฟใกล้เซ็นทรัลเวิลด์"
193
+
194
+ # graph = workflow.compile()
195
+
196
+ # events = graph.stream(
197
+ # {
198
+ # "messages": [
199
+ # HumanMessage(
200
+ # question
201
+ # )
202
+ # ],
203
+ # },
204
+ # # Maximum number of steps to take in the graph
205
+ # {"recursion_limit": 20},
206
+ # )
207
+ # for s in events:
208
+ # # print(s)
209
+ # a = list(s.items())[0]
210
+ # a[1]['messages'][0].pretty_print()
211
+
212
+ # %%
213
+ def submitUserMessage(user_input: str) -> str:
214
+ graph = workflow.compile()
215
+
216
+ events = graph.stream(
217
+ {
218
+ "messages": [
219
+ HumanMessage(
220
+ user_input
221
+ )
222
+ ],
223
+ },
224
+ # Maximum number of steps to take in the graph
225
+ {"recursion_limit": 20},
226
+ )
227
+
228
+ events = [e for e in events]
229
+
230
+ response = list(events[-1].values())[0]["messages"][0]
231
+ response = response.content
232
+ response = response.replace("%SIjfE923hf", "")
233
+
234
+ return response
235
+
236
+
237
+ # question = "วิเคราะห์ร้านอาหารแถวลุมพินี เซ็นเตอร์ ลาดพร้าว"
238
+ # submitUserMessage(question)
239
+
240
+
document/community type by district.csv ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ จำนวนชุมชนประเภทต่าง ๆ ในกรุงเทพมหานคร พ.ศ. 2564,,,,,,
2
+ จำแนกตามสำนักงานเขต และประเภทของชุมชน,,,,,,
3
+ สำนักงานเขต,ประเภทชุมชน,,,,,รวม
4
+ ,ชุมชนรูปแบบพิเศษ,ชานเมือง,เมือง,อาคารสูง,แออัด,
5
+ กลุ่มกรุงเทพกลาง,,,,,,
6
+ ดินแดง,-,-,10,5,8,23
7
+ ดุสิต,-,-,26,8,9,43
8
+ ป้อมปราบศัตรูพ่าย,-,-,4,-,10,14
9
+ พญาไท,-,-,-,9,13,22
10
+ พระนคร,-,-,15,-,5,20
11
+ ราชเทวี,-,-,-,7,18,25
12
+ วังทองหลาง,-,-,3,-,16,19
13
+ สัมพันธวงศ์,-,-,17,-,-,17
14
+ ห้วยขวาง,-,-,4,1,17,22
15
+ รวม,0,0,79,30,96,205
16
+ กลุ่มกรุงเทพใต้,,,,,,
17
+ คลองเตย,-,-,11,6,22,39
18
+ บางคอแหลม,-,-,1,1,26,28
19
+ บางนา,-,1,24,2,7,34
20
+ บางรัก,-,-,11,1,3,15
21
+ ปทุมวัน,-,-,2,3,12,17
22
+ พระโขนง,-,-,19,-,25,44
23
+ ยานนาวา,-,-,5,-,12,17
24
+ วัฒนา,-,-,2,-,14,16
25
+ สวนหลวง,-,-,43,-,2,45
26
+ สาทร,-,-,15,1,8,24
27
+ รวม,0,1,133,14,131,279
28
+ กลุ่มกรุงเทพเหนือ,,,,,,
29
+ จตุจักร,-,1,13,6,21,41
30
+ ดอนเมือง,-,1,78,-,17,96
31
+ บางเขน,-,2,56,8,7,73
32
+ บางซื่อ,-,-,2,1,47,50
33
+ ลาดพร้าว,-,2,28,2,4,36
34
+ สายไหม,-,6,68,1,4,79
35
+ หลักสี่,-,1,50,11,15,77
36
+ รวม,0,13,295,29,115,452
37
+ จำนวนชุมชนประเภทต่าง ๆ ในกรุงเทพมหานคร พ.ศ. 2564,,,,,,
38
+ จำแนกตามสำนักงานเขต และประเภทของชุมชน (ต่อ),,,,,,
39
+ สำนักงานเขต,ประเภทชุมชน,,,,,รวม
40
+ ,ชานเมือง,เมือง,หมู่บ้านจัดสรร,อาคารสูง,แออัด,
41
+ กลุ่มกรุงเทพตะวันออก,,,,,,
42
+ คลองสามวา,-,56,28,-,-,84
43
+ คันนายาว,-,3,23,2,14,42
44
+ บางกะปิ,-,1,18,-,8,27
45
+ บึงกุ่ม,-,1,21,-,15,37
46
+ ประเวศ,-,1,38,3,3,45
47
+ มีนบุรี,-,31,30,1,1,63
48
+ ลาดกระบัง,-,30,33,1,1,65
49
+ สะพานสูง,-,21,4,-,4,29
50
+ หนองจอก,-,82,17,-,-,99
51
+ รวม,0,226,212,7,46,491
52
+ กลุ่มกรุงธนเหนือ,,,,,,
53
+ คลองสาน,-,-,5,-,29,34
54
+ จอมทอง,-,6,38,1,3,48
55
+ ตลิ่งชัน,-,27,8,-,8,43
56
+ ทวีวัฒนา,-,6,11,-,-,17
57
+ ธนบุรี,-,-,-,-,43,43
58
+ บางกอกน้อย,-,-,5,1,31,37
59
+ บางกอกใหญ่,-,-,2,-,28,30
60
+ บางพลัด,-,-,7,-,41,48
61
+ รวม,0,39,76,2,183,300
62
+ กลุ่มกรุงธนใต้,,,,,,
63
+ ทุ่งครุ,-,3,23,2,1,29
64
+ บางขุนเทียน,-,17,31,-,3,51
65
+ บางแค,-,5,19,-,23,47
66
+ บางบอน,-,3,7,-,2,12
67
+ ภาษีเจริญ,-,2,37,-,12,51
68
+ ราษฎร์บูรณะ,-,-,2,-,26,28
69
+ หนองแขม,-,42,26,1,2,71
70
+ รวม,0,72,145,3,69,289
71
+ รวมทั้งหมด,0,351,940,85,640,2016
72
+ แหล่งข้อมูล : สำนักงานการพัฒนาชุมชน สำนักพัฒนาสังคม กรุงเทพมหานคร (ข้อมูล ณ วันที่ 25 เม.ย. 65),,,,,,
73
+ หมายเหตุ : ระเบียบกรุงเทพมหานครว่าด้วยชุมชนและกรรมการชุมชน พ.ศ. 2564 ชุมชนแบ่งออกเป็น 5 ประเภท ได้แก่,,,,,,
74
+ หมายเหตุ : ชุมชนแออัด / ชุมชนเมือง / ชุมชนชาญเมือง / ชุมชนอาคารสูง / ชุมชนรูปแบบพิเศษ,,,,,,
document/thailand household expenditures by category.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "เปรียบเทียบร้อยละของค่าใช้จ่ายเฉลี่ยต่อเดือนของครัวเรือน จำแนกตามประเภทค่าใช้จ่าย
2
+ พ.ศ. 2558 - 2564",,,,,,,
3
+ ,,,,,,,
4
+ ประเภทค่าใช้จ่าย*,ร้อยละ,,,,,,
5
+ ,2558,2559,2560,2561,2562,2563,2564
6
+ อาหาร เครื่องดื่ม และยาสูบ,33.7,36.1,35,34.8,33.9,35.6,35.5
7
+ ค่าที่อยู่อาศัยและเครื่องใช้ภายในบ้าน,20.4,19.7,20,19.8,21,20.6,21.4
8
+ การเดินทางและยานพาหนะ,18.3,17.4,17,17.7,17.3,17.2,16
9
+ ใช้ส่วนบุคคล/เครื่องนุ่งห่ม/รองเท้า,6,5.2,5,5,5.9,4.7,4.9
10
+ การสื่อสาร,3.3,3.4,3,3.9,3.7,4,4
11
+ การบันเทิง/การจัดงานพิธี,1.4,1.2,1,1.1,0.9,1,1
12
+ การศึกษา,1.7,1.7,2,1.7,1.5,1.5,1.6
13
+ เวชภัณฑ์/ค่ารักษาพยาบาล,1.1,1.4,2,1.5,1.3,1.5,1.7
14
+ กิจกรรมทางศาสนา,1.2,1,1,1.1,1,0.9,0.9
15
+ "ค่าใช้จ่ายที่ไม่เกี่ยวกับการอุปโภคบริโภค เช่น ค่าภาษี ของขวัญ
16
+ เบี้ยประกันภัย ซื้อสลากกินแบง/หวย ดอกเบี้ย",12.9,12.9,##,13.4,13.5,13,13
document/thailand household expenditures by province.csv ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ค่าใช้จ่ายเฉลี่ยต่อเดือนของครัวเรือน เป็นรายภาค และจังหวัด พ.ศ. 2555 - 2564,,,,,,,,,,,
2
+ หน่วย: บาท,,,,,,,,,,,
3
+ ภาค,จังหวัด,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564
4
+ ทั่วราชอาณาจักร,ทั่วราชอาณาจักร,"18,766.00","19,061.00","20,892.00","21,157.00","21,144.00","21,436.50","21,346.00","20,742.12","21,329.00","21,616.00"
5
+ กรุงเทพมหานคร และ 3 จังหวัด,กรุงเทพมหานคร และ 3 จังหวัด,"31,971.00","32,425.00","31,606.00","30,882.00","32,091.00","33,126.02","33,408.00","30,778.10","31,142.00","31,382.00"
6
+ ,กรุงเทพมหานคร,"33,956.98","35,023.70","34,425.64","33,085.70","35,101.40","35,350.70","34,127.44","31,753.04","32,052.03","31,866.68"
7
+ ,สมุทรปราการ,"25,860.88","26,192.90","22,747.21","22,331.80","24,353.97","24,354.72","23,231.71","21,423.43","23,850.82","27,484.76"
8
+ ,นนทบุรี,"28,731.23","26,946.60","30,812.06","31,381.00","28,828.37","33,313.04","33,808.98","32,189.09","33,042.31","33,995.57"
9
+ ,ปทุมธานี,"30,668.81","29,514.00","30,197.07","29,770.00","31,271.04","33,604.46","43,300.51","37,086.11","33,823.84","31,639.92"
10
+ ภาคกลาง,ภาคกลาง,"19,762.00","19,728.00","21,144.00","21,055.00","20,493.00","21,119.75","21,168.00","20,644.55","21,771.00","22,332.00"
11
+ ,พระนครศรีอยุธยา,"25,215.89","20,493.70","20,409.63","22,218.10","23,095.32","23,780.19","22,790.08","24,439.76","23,391.26","25,326.92"
12
+ ,อ่างทอง,"21,273.24","21,182.50","19,633.96","17,573.60","20,371.91","17,162.48","17,294.67","17,010.98","17,726.59","17,020.79"
13
+ ,ลพบุรี,"17,356.96","15,944.80","14,910.71","17,968.90","15,875.50","16,012.15","17,016.83","16,829.71","19,180.09","21,324.54"
14
+ ,สิงห์บุรี,"23,474.62","22,118.20","19,631.55","22,136.80","19,381.46","20,262.78","19,773.04","19,884.51","20,303.62","20,146.07"
15
+ ,ชัยนาท,"15,535.57","17,766.60","17,090.91","17,163.10","17,495.47","16,162.12","17,187.28","15,762.99","19,835.74","18,292.27"
16
+ ,สระบุรี,"21,412.68","22,765.00","22,811.16","23,017.10","23,964.34","26,635.10","27,581.38","26,007.12","26,045.40","26,503.14"
17
+ ,ชลบุรี,"25,499.01","24,934.20","25,704.10","24,182.00","24,257.06","24,572.50","25,322.87","25,683.70","24,878.44","28,001.46"
18
+ ,ระยอง,"21,023.90","21,872.50","23,303.13","24,433.50","21,024.65","22,698.79","19,409.81","20,806.85","21,451.36","22,365.56"
19
+ ,จันทบุรี,"19,594.74","17,597.30","20,649.74","23,350.80","22,790.42","20,619.92","20,922.15","19,812.57","23,300.20","22,347.34"
20
+ ,ตราด,"15,662.72","16,706.30","18,126.65","18,989.00","18,913.56","20,404.69","20,198.98","18,883.88","19,563.16","19,796.09"
21
+ ,ฉะเชิงเทรา,"23,079.51","26,070.70","23,342.12","21,782.60","21,674.11","21,437.44","19,070.81","17,035.88","18,791.18","18,968.49"
22
+ ,ปราจีนบุรี,"19,733.75","18,314.70","20,789.55","20,994.50","18,156.85","19,268.28","20,782.66","21,677.72","22,470.73","23,318.79"
23
+ ,นครนายก,"16,459.52","17,696.90","17,482.59","18,153.50","17,877.62","18,601.09","19,152.88","19,717.14","20,609.12","21,775.45"
24
+ ,สระแก้ว,"19,531.06","18,571.10","20,227.36","20,576.70","18,413.18","17,609.53","17,543.55","15,827.78","16,939.41","17,347.26"
25
+ ,ราชบุรี,"16,760.17","17,253.20","17,514.63","15,083.90","19,341.33","25,367.36","22,833.63","20,122.78","22,383.58","22,171.08"
26
+ ,กาญจนบุรี,"17,220.34","17,301.10","17,186.70","15,764.80","18,221.02","18,001.28","20,738.75","18,717.16","21,385.86","22,346.86"
27
+ ,สุพรรณบุรี,"12,392.88","13,450.40","14,868.54","14,146.10","13,893.31","15,919.02","14,244.50","14,557.73","14,442.09","14,776.76"
28
+ ,นครปฐม,"20,409.22","21,305.40","25,876.36","26,025.20","22,498.78","20,711.53","24,962.41","24,254.93","24,502.62","24,003.25"
29
+ ,สมุทรสาคร,"18,164.89","18,565.40","22,559.61","22,876.70","21,644.56","20,806.50","20,573.08","19,664.33","23,993.17","22,694.64"
30
+ ,สมุทรสงคราม,"16,953.24","16,557.80","19,510.69","18,801.00","16,909.17","20,863.95","18,755.08","19,028.26","20,424.16","19,239.86"
31
+ ,เพชรบุรี,"19,140.50","18,469.40","20,170.13","22,154.20","20,756.34","23,061.47","20,207.39","20,789.27","22,976.64","22,242.70"
32
+ ,ประจวบคีรีขันธ์,"21,452.15","22,393.00","25,914.62","21,267.70","20,184.45","21,318.44","23,513.15","19,350.27","21,821.30","20,844.56"
33
+ ภาคเหนือ,ภาคเหนือ,"14,010.00","14,066.00","15,286.00","15,268.00","15,769.00","15,329.12","15,240.00","15,644.02","16,490.00","16,441.00"
34
+ ,เชียงใหม่,"14,585.38","11,703.50","13,731.68","11,863.80","14,455.34","15,206.77","15,468.58","15,659.49","18,887.48","17,572.74"
35
+ ,ลำพูน,"17,897.52","20,380.70","20,062.78","20,549.90","20,979.39","20,055.79","18,604.05","19,115.37","20,189.87","19,929.95"
36
+ ,ลำปาง,"15,193.60","15,101.90","16,020.52","15,314.80","16,883.51","16,641.56","16,645.81","17,612.59","16,375.99","15,948.34"
37
+ ,อุตรดิตถ์,"12,015.66","13,550.20","15,219.76","15,814.50","16,370.35","14,799.30","14,666.28","16,355.07","14,544.46","16,530.72"
38
+ ,แพร่,"13,958.50","15,478.60","15,454.61","16,449.20","15,617.89","14,474.40","14,843.86","15,802.50","14,822.23","15,052.87"
39
+ ,น่าน,"13,622.97","14,078.30","13,919.72","14,165.20","14,358.93","14,298.53","15,176.17","15,269.79","16,122.92","16,649.76"
40
+ ,พะเยา,"11,483.66","11,245.10","11,835.15","13,782.70","13,100.65","12,293.42","12,751.80","12,915.79","13,217.25","12,552.05"
41
+ ,เชียงราย,"11,390.92","11,068.20","11,230.83","12,074.60","12,877.74","10,440.72","11,213.48","12,635.31","11,532.11","12,907.69"
42
+ ,แม่ฮ่องสอน,"7,878.90","7,405.10","9,686.13","12,131.40","11,859.40","12,243.25","11,536.21","11,242.74","11,606.13","12,214.19"
43
+ ,นครสวรรค์,"13,932.97","14,268.40","16,192.62","17,128.40","16,076.25","16,045.18","14,794.13","16,001.51","16,568.68","16,151.74"
44
+ ,อุทัยธานี,"13,852.50","13,082.60","15,689.50","16,402.00","17,806.22","16,862.10","15,746.55","15,763.29","14,270.11","15,416.63"
45
+ ,กำแพงเพชร,"15,005.63","16,359.50","17,880.00","17,370.80","17,271.87","16,383.96","16,147.13","15,751.72","18,559.99","19,496.88"
46
+ ,ตาก,"12,656.51","13,148.80","13,918.75","15,175.60","14,140.54","13,112.67","12,527.72","13,910.20","14,719.82","16,506.34"
47
+ ,สุโขทัย,"14,320.57","15,311.50","14,905.00","17,246.40","16,101.76","14,968.09","14,548.42","15,166.31","14,097.73","14,033.63"
48
+ ,พิษณุโลก,"17,458.55","19,927.90","19,002.98","17,649.60","17,731.79","19,338.22","18,048.53","18,124.65","19,387.40","19,300.60"
49
+ ,พิจิตร,"15,483.60","14,791.00","18,687.19","16,854.30","17,734.08","15,868.65","16,601.52","15,752.25","16,327.40","17,398.17"
50
+ ,เพชรบูรณ์,"13,879.27","13,788.90","15,598.93","16,140.80","16,444.81","16,696.21","17,528.49","16,222.51","19,724.79","17,743.26"
51
+ ภาคตะวันออกเฉียงเหนือ,ภาคตะวันออกเฉียงเหนือ,"14,277.00","15,092.00","16,284.00","17,032.00","16,276.00","16,513.01","16,343.00","16,552.64","16,810.00","16,869.00"
52
+ ,นครราชสีมา,"15,396.63","15,618.20","17,771.26","18,645.40","18,488.78","17,840.83","18,195.67","16,888.61","17,939.45","16,289.06"
53
+ ,บุรีรัมย์,"12,938.87","14,342.90","13,951.72","16,086.50","13,053.88","12,686.46","14,580.11","13,502.86","15,289.74","18,834.94"
54
+ ,สุรินทร์,"14,746.46","18,583.80","17,068.78","18,536.90","16,289.26","16,306.82","18,208.86","18,003.99","18,999.16","20,018.13"
55
+ ,ศรีสะเกษ,"12,837.46","13,367.50","14,609.03","18,124.40","14,129.29","15,838.40","13,798.05","14,676.47","14,268.78","13,443.72"
56
+ ,อุบลราชธานี,"14,754.66","13,586.50","15,477.57","13,848.20","13,997.21","16,045.66","14,769.70","13,496.02","15,135.26","15,751.71"
57
+ ,ยโสธร,"12,109.63","12,549.10","15,867.23","14,453.20","15,979.68","13,554.46","12,748.09","13,591.40","12,907.04","14,391.11"
58
+ ,ชัยภูมิ,"16,090.09","15,022.10","17,162.94","16,332.10","17,704.80","17,237.63","15,591.56","15,402.15","15,930.45","16,177.83"
59
+ ,อำนาจเจริญ,"14,240.34","14,161.80","17,528.52","17,029.20","15,550.34","16,575.21","14,612.97","16,693.42","15,184.77","17,206.77"
60
+ ,บึงกาฬ,"17,098.45","20,282.50","20,073.17","23,696.60","22,238.65","19,661.96","18,347.12","22,225.38","21,421.45","19,539.55"
61
+ ,หนองบัวลำภู,"13,355.66","13,663.70","17,622.34","18,760.70","21,456.95","19,043.40","17,295.58","16,007.80","21,173.43","17,840.51"
62
+ ,ขอนแก่น,"12,677.47","13,914.70","15,700.07","16,880.00","15,091.55","16,544.29","17,589.11","17,662.59","17,320.99","15,054.60"
63
+ ,อุดรธานี,"18,346.97","21,438.90","21,619.51","22,535.10","19,103.20","20,015.07","18,696.16","22,576.64","16,692.86","19,747.02"
64
+ ,เลย,"14,313.80","14,916.20","15,789.06","16,231.70","18,625.25","19,102.70","21,055.18","19,220.31","21,015.45","21,012.91"
65
+ ,หนองคาย,"15,011.95","15,670.30","18,360.73","19,277.70","16,532.30","18,815.11","18,129.21","19,104.40","18,943.82","17,903.20"
66
+ ,มหาสารคาม,"14,714.21","15,506.20","14,253.58","14,654.20","18,430.56","17,664.79","17,286.87","18,308.83","19,027.99","20,000.26"
67
+ ,ร้อยเอ็ด,"16,708.42","15,347.50","17,761.85","17,755.50","16,379.71","16,770.21","15,685.74","17,320.40","15,738.71","15,606.70"
68
+ ,กาฬสินธุ์,"11,150.95","12,445.20","12,178.38","12,746.60","11,970.07","11,541.28","11,857.86","13,076.14","13,544.26","14,398.96"
69
+ ,สกลนคร,"11,232.68","13,021.30","13,474.68","14,549.00","15,268.78","15,159.10","15,130.25","14,840.92","16,318.73","16,757.96"
70
+ ,นครพนม,"10,826.03","11,447.10","12,562.25","13,973.10","13,501.08","13,324.50","14,416.97","16,233.73","16,187.32","15,604.73"
71
+ ,มุกดาหาร,"13,015.83","13,146.40","15,202.76","17,767.00","17,021.91","18,368.81","15,761.48","14,901.97","17,546.03","17,970.94"
72
+ ภาคใต้,ภาคใต้,"20,645.00","20,372.00","21,016.00","21,293.00","21,314.00","21,381.41","20,660.00","19,599.58","19,641.00","20,628.00"
73
+ ,นครศรีธรรมราช,"22,102.20","19,364.20","20,661.17","19,828.70","21,011.81","20,051.18","21,135.24","19,170.64","18,940.91","19,574.79"
74
+ ,กระบี่,"19,536.10","20,835.70","32,836.66","28,403.20","24,823.83","24,925.19","24,326.12","23,275.81","26,631.25","24,233.52"
75
+ ,พังงา,"19,208.84","17,899.60","21,719.34","20,716.90","20,255.66","19,958.35","20,703.32","17,998.67","19,292.16","21,200.60"
76
+ ,ภูเก็ต,"27,151.22","25,337.50","28,111.37","27,435.40","30,238.67","32,853.12","30,992.50","32,762.88","31,346.83","32,944.35"
77
+ ,สุราษฎร์ธานี,"27,927.27","28,118.60","26,410.48","26,165.30","24,743.15","24,186.29","25,212.15","23,489.94","23,307.61","25,539.36"
78
+ ,ระนอง,"20,343.22","22,586.60","18,246.94","18,616.90","18,511.33","18,496.89","17,130.73","17,186.76","17,945.54","17,916.32"
79
+ ,ชุมพร,"23,952.43","22,552.30","23,985.40","24,541.80","22,933.28","24,143.88","20,692.85","20,193.54","21,040.06","21,500.62"
80
+ ,สงขลา,"21,382.60","21,669.80","21,744.26","23,617.30","23,466.01","23,693.16","21,127.92","18,017.38","18,136.34","19,655.98"
81
+ ,สตูล,"20,189.97","22,714.70","19,715.22","19,591.20","20,732.92","18,810.72","19,335.78","18,589.49","20,127.52","20,845.48"
82
+ ,ตรัง,"19,617.83","20,922.30","17,107.10","19,794.90","18,599.29","18,768.44","18,648.61","20,143.01","17,904.52","18,296.68"
83
+ ,พัทลุง,"18,404.19","16,635.70","18,514.03","17,143.30","18,420.66","16,807.88","15,947.09","15,848.77","16,817.89","17,578.04"
84
+ ,ปัตตานี,"14,119.15","16,668.10","14,809.34","15,341.10","17,962.18","16,948.61","15,705.85","15,948.56","14,862.49","15,392.67"
85
+ ,ยะลา,"12,883.10","12,521.70","12,370.15","13,453.90","14,122.15","15,483.63","13,301.01","13,595.63","14,141.04","14,927.64"
86
+ ,นราธิวาส,"12,686.17","13,727.80","11,985.95","13,717.40","13,065.80","14,980.10","15,630.54","14,572.65","15,126.26","17,088.68"
document/thailand population data by district.csv ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ จำนวนชุมชน ประชากร ครอบครัว และหลังคาเรือนของชุมชนในกรุงเทพมหานคร พ.ศ. 2564,,,,,,,
2
+ ลำดับ,เขต,ชุมชน (ชุมชน),ประชากร (คน),ครอบครัว (ครอบครัว),หลังคาเรือน (หลัง),Indicator*,*ค่าใช้จ่ายในการเข้าถึงชุมชนมีประสิทธิภาพมากที่สุด
3
+ 25,บางกอกน้อย,37,"104,566","24,109","17,076",2826.108108,
4
+ 24,คลองเตย,39,"84,780","21,784","19,499",2173.846154,
5
+ 43,ปทุมวัน,17,"28,031","8,196","5,557",1648.882353,
6
+ 33,บางคอแหลม,28,"38,148","10,896","7,230",1362.428571,
7
+ 8,ลาดกระบัง,65,"88,325","25,624","24,489",1358.846154,
8
+ 37,สาทร,24,"32,077","8,994","5,411",1336.541667,
9
+ 29,บางนา,34,"42,890","15,132","17,210",1261.470588,
10
+ 5,หลักสี่,77,"96,430","19,341","17,867",1252.337662,
11
+ 9,มีนบุรี,63,"76,028","21,436","20,055",1206.793651,
12
+ 10,บางขุนเทียน,51,"60,038","13,802","13,443",1177.215686,
13
+ 31,สะพานสูง,29,"32,000","9,768","8,513",1103.448276,
14
+ 4,สายไหม,79,"86,847","25,419","24,903",1099.329114,
15
+ 19,ธนบุรี,43,"46,376","16,944","14,929",1078.511628,
16
+ 35,บางกะปิ,27,"28,835","8,700","8,283",1067.962963,
17
+ 16,สวนหลวง,45,"47,408","9,506","8,558",1053.511111,
18
+ 39,พญาไท,22,"22,958","6,364","5,982",1043.545455,
19
+ 44,ทวีวัฒนา,17,"17,506","5,140","4,807",1029.764706,
20
+ 42,วังทองหลาง,19,"19,123","5,570","4,694",1006.473684,
21
+ 17,ประเวศ,45,"43,855","10,324","10,304",974.5555556,
22
+ 28,คลองสาน,34,"33,024","10,219","7,339",971.2941176,
23
+ 27,ลาดพร้าว,36,"34,435","13,194","11,931",956.5277778,
24
+ 6,บางเขน,73,"69,281","22,503","22,396",949.0547945,
25
+ 48,บางรัก,15,"14,165","4,452","3,213",944.3333333,
26
+ 26,บึงกุ่ม,37,"34,245","10,702","10,365",925.5405405,
27
+ 36,ราชเทวี,25,"23,071","8,198","5,942",922.84,
28
+ 11,ภาษีเจริญ,51,"46,644","10,807","9,552",914.5882353,
29
+ 14,จอมทอง,48,"43,767","12,111","9,125",911.8125,
30
+ 13,บางพลัด,48,"42,870","13,392","9,530",893.125,
31
+ 38,ดินแดง,23,"19,950","12,049","6,184",867.3913043,
32
+ 47,วัฒนา,16,"13,575","5,378","3,625",848.4375,
33
+ 2,ดอนเมือง,96,"80,879","26,030","26,073",842.4895833,
34
+ 40,ห้วยขวาง,22,"18,528","4,481","3,805",842.1818182,
35
+ 15,บางแค,47,"38,987","9,647","7,687",829.5106383,
36
+ 32,ทุ่งครุ,29,"23,593","8,536","5,384",813.5517241,
37
+ 45,ยานนาวา,17,"13,820","3,476","2,995",812.9411765,
38
+ 7,หนองแขม,71,"55,310","17,811","16,741",779.0140845,
39
+ 20,ดุสิต,43,"33,416","12,031","8,638",777.1162791,
40
+ 3,คลองสามวา,84,"64,063","19,208","17,445",762.6547619,
41
+ 22,คันนายาว,42,"32,001","10,362","9,776",761.9285714,
42
+ 1,หนองจอก,99,"74,604","19,549","19,630",753.5757576,
43
+ 12,บางซื่อ,50,"37,670","12,130","7,814",753.4,
44
+ 41,พระนคร,20,"14,726","5,758","5,364",736.3,
45
+ 23,จตุจักร,41,"28,540","10,067","9,109",696.097561,
46
+ 21,ตลิ่งชัน,43,"29,734","9,171","7,372",691.4883721,
47
+ 49,ป้อมปราบศัตรูพ่าย,14,"8,332","2,898","2,841",595.1428571,
48
+ 18,พระโขนง,44,"26,030","7,728","5,998",591.5909091,
49
+ 34,ราษฎร์บูรณะ,28,"16,430","6,088","4,097",586.7857143,
50
+ 30,บางกอกใหญ่,30,"17,108","4,728","3,981",570.2666667,
51
+ 50,บางบอน,12,"6,533","2,141","2,472",544.4166667,
52
+ 46,สัมพันธวงศ์,17,"5,117","1,907","2,100",301,
53
+ รวม,,"2,016","1,996,669","583,801","507,334",,
54
+ แหล่งข้อมูล : สำนักงานการพัฒนาชุมชน สำนักพัฒนาสังคม กรุงเทพมหานคร (ข้อมูล ณ วันที่ 25 เม.ย. 65),,,,,,,
gplace.ipynb ADDED
@@ -0,0 +1,1228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os\n",
10
+ "import requests"
11
+ ]
12
+ },
13
+ {
14
+ "cell_type": "code",
15
+ "execution_count": 2,
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. NYLA Fashion Island\\nAddress: 587, 589, 589/7-9 Ram Inthra Rd, Khwaeng Khan Na Yao, Khet Khan Na Yao, Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJeUgI3A5jHTERdzu6oMzUSCk\\nPhone: 02 947 5938\\nWebsite: Unknown\\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. IF Store art & chara สาขา Fasion Island\\nAddress: KI B006-B007 โซนแกรนด์สเตชั่น ซอย 7 ศูนย์การค้าแฟชั่นไอส์แลนด์ ชั้น 2 587,589, 589 7 9 Ram Inthra Rd, Khwaeng Khan Na Yao, Khet Khan Na Yao, Krung Thep Maha Nakhon 10230, Thailand\\nGoogle place ID: ChIJx5zaF3RjHTER8ROSKii-tVQ\\nPhone: 063 232 6356\\nWebsite: https://shopee.co.th/ifstore_art\\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. 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\\n9. Panya Ramintra\\nAddress: Khan Na Yao, Bangkok 10230, Thailand\\nGoogle place ID: ChIJ9e97xwhjHTERR-MWDuKtUYY\\nPhone: Unknown\\nWebsite: Unknown\\n\\n\\n10. 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\\n11. ร้านชุดชั้นใน 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\\n12. 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\\n13. 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": 4,
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": 9,
70
+ "metadata": {},
71
+ "outputs": [
72
+ {
73
+ "name": "stdout",
74
+ "output_type": "stream",
75
+ "text": [
76
+ "{'candidates': [{'formatted_address': '45 1 ตำบล วังกระแจะ เมือง ตราด 23000 ไทย', 'geometry': {'location': {'lat': 15.870032, 'lng': 100.992541}, 'viewport': {'northeast': {'lat': 15.8707744, 'lng': 100.9936482298927}, 'southwest': {'lat': 15.86780479999999, 'lng': 100.9909485701073}}}, 'name': 'โรงแรมสุทธิวารี', 'opening_hours': {'open_now': True}, 'rating': 5}], 'status': 'OK'}\n"
77
+ ]
78
+ }
79
+ ],
80
+ "source": [
81
+ "def find_place_from_text(input_text, location=None, radius=2000):\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 = \"hotel\"\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": 6,
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": 7,
164
+ "metadata": {},
165
+ "outputs": [
166
+ {
167
+ "data": {
168
+ "text/plain": [
169
+ "[{'business_status': 'OPERATIONAL',\n",
170
+ " 'geometry': {'location': {'lat': 13.7455309, 'lng': 100.5198334},\n",
171
+ " 'viewport': {'northeast': {'lat': 13.74692812989272,\n",
172
+ " 'lng': 100.5214657798927},\n",
173
+ " 'southwest': {'lat': 13.74422847010728, 'lng': 100.5187661201073}}},\n",
174
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
175
+ " 'icon_background_color': '#909CE1',\n",
176
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
177
+ " 'name': 'The Twin Towers Hotel',\n",
178
+ " 'opening_hours': {'open_now': True},\n",
179
+ " 'photos': [{'height': 1335,\n",
180
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/115779328569151334983\">A Google User</a>'],\n",
181
+ " 'photo_reference': 'AXCi2Q5REfgaHadtFNqXOFpuxkVdoFf0rM5zy9Piw_WeOcuTwSKMqU2CgFnQoN6BRclj7SQ4s_eccxIdMd-Ul1pvz0EOjBikoWSlxvqLoZIauLg-YzlVvqfpd2bU0OfVKNarBaHYWn2hPMC0n2wShcIaz4I1hc89Bab018M4-BFexDp_gMFc',\n",
182
+ " 'width': 2000}],\n",
183
+ " 'place_id': 'ChIJ_zP3fy-Z4jARWYaBArPXGAg',\n",
184
+ " 'plus_code': {'compound_code': 'PGW9+6W Bangkok',\n",
185
+ " 'global_code': '7P52PGW9+6W'},\n",
186
+ " 'rating': 4,\n",
187
+ " 'reference': 'ChIJ_zP3fy-Z4jARWYaBArPXGAg',\n",
188
+ " 'scope': 'GOOGLE',\n",
189
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
190
+ " 'user_ratings_total': 3326,\n",
191
+ " 'vicinity': '88 ถ.พระราม 6 ตัดใหม่ Rong Muang, Pathum Wan'},\n",
192
+ " {'business_status': 'OPERATIONAL',\n",
193
+ " 'geometry': {'location': {'lat': 13.7467728, 'lng': 100.5294726},\n",
194
+ " 'viewport': {'northeast': {'lat': 13.74811892989272,\n",
195
+ " 'lng': 100.5308482298927},\n",
196
+ " 'southwest': {'lat': 13.74541927010728, 'lng': 100.5281485701073}}},\n",
197
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
198
+ " 'icon_background_color': '#909CE1',\n",
199
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
200
+ " 'name': 'Muangphol Mansion',\n",
201
+ " 'opening_hours': {'open_now': False},\n",
202
+ " 'photos': [{'height': 3000,\n",
203
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/107774912115800487369\">Hassan Ahmadian</a>'],\n",
204
+ " 'photo_reference': 'AXCi2Q4AS3FJWETxFu9WbBFhhNhmjsSQZiKqiIGEVmqYgaPqhsgy9g7bWpjLp5WDzQQTnZPkrpAVnXTIQDxN3y_JF36mBoF0LVqgsrWVumTiokIETibGLIY7pL7ujSc7sqvOkr-WcX6pC9N8AyASE-vszjVYdso6gUCl8DtdalINk-bXBa8r',\n",
205
+ " 'width': 4000}],\n",
206
+ " 'place_id': 'ChIJZzgIrTKZ4jARJYzilmi9T74',\n",
207
+ " 'plus_code': {'compound_code': 'PGWH+PQ Bangkok',\n",
208
+ " 'global_code': '7P52PGWH+PQ'},\n",
209
+ " 'rating': 3.3,\n",
210
+ " 'reference': 'ChIJZzgIrTKZ4jARJYzilmi9T74',\n",
211
+ " 'scope': 'GOOGLE',\n",
212
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
213
+ " 'user_ratings_total': 113,\n",
214
+ " 'vicinity': '8, 931 Rama I Rd, Wang Mai, Pathum Wan'},\n",
215
+ " {'business_status': 'OPERATIONAL',\n",
216
+ " 'geometry': {'location': {'lat': 13.7468712, 'lng': 100.52869},\n",
217
+ " 'viewport': {'northeast': {'lat': 13.74810307989272,\n",
218
+ " 'lng': 100.5300171798927},\n",
219
+ " 'southwest': {'lat': 13.74540342010728, 'lng': 100.5273175201073}}},\n",
220
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
221
+ " 'icon_background_color': '#909CE1',\n",
222
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
223
+ " 'name': 'Lub d Bangkok Siam',\n",
224
+ " 'opening_hours': {'open_now': False},\n",
225
+ " 'photos': [{'height': 4000,\n",
226
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/110664455171949656649\">Lub d Bangkok - Siam Square</a>'],\n",
227
+ " 'photo_reference': 'AXCi2Q6jzkjlHJJaGkIjVVevWBny8MMkNw90qEwgUEaQWAgPbdj4R12eZrVTpoUGawjhwWrDFuWSdEncNcPSncrVFNc2XcbEgE9dpjiGGKSWjUuwO9wFJBKBzEuNq16ey7eVMC8MPQRgqeE0rYKeY1o4IwNEKCEHmKigl3xvnURQ3HMTcPfQ',\n",
228
+ " 'width': 6000}],\n",
229
+ " 'place_id': 'ChIJc33lpDKZ4jARil4bO37UbIs',\n",
230
+ " 'plus_code': {'compound_code': 'PGWH+PF Bangkok',\n",
231
+ " 'global_code': '7P52PGWH+PF'},\n",
232
+ " 'rating': 4.3,\n",
233
+ " 'reference': 'ChIJc33lpDKZ4jARil4bO37UbIs',\n",
234
+ " 'scope': 'GOOGLE',\n",
235
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
236
+ " 'user_ratings_total': 938,\n",
237
+ " 'vicinity': '925, 9 Rama I Rd, Wang Mai, Pathum Wan'},\n",
238
+ " {'business_status': 'OPERATIONAL',\n",
239
+ " 'geometry': {'location': {'lat': 13.7627061, 'lng': 100.5381273},\n",
240
+ " 'viewport': {'northeast': {'lat': 13.76412432989272,\n",
241
+ " 'lng': 100.5396005798927},\n",
242
+ " 'southwest': {'lat': 13.76142467010728, 'lng': 100.5369009201073}}},\n",
243
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
244
+ " 'icon_background_color': '#909CE1',\n",
245
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
246
+ " 'name': 'The Victory View',\n",
247
+ " 'opening_hours': {'open_now': True},\n",
248
+ " 'photos': [{'height': 4000,\n",
249
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/101078213475534837237\">A Google User</a>'],\n",
250
+ " 'photo_reference': 'AXCi2Q5sc9dLfaqO79qSoPvgA6E9rcouVekbl-jKloKDhM5ZVhnKmqEE2k9-jeg4kDUtFt-gE-f5P4YbOU2vdIjGaYg7GJyrzDrT7xLpT_UbIH2Km19g_H-JgQd1D3afrBvjtRklWFwDoCw7TnZtPqyF7GGia6yp4qPp7OLspmGR04BV0oAn',\n",
251
+ " 'width': 6000}],\n",
252
+ " 'place_id': 'ChIJ23PzgMme4jARFOY5eyKACAA',\n",
253
+ " 'plus_code': {'compound_code': 'QG7Q+37 Bangkok',\n",
254
+ " 'global_code': '7P52QG7Q+37'},\n",
255
+ " 'rating': 4,\n",
256
+ " 'reference': 'ChIJ23PzgMme4jARFOY5eyKACAA',\n",
257
+ " 'scope': 'GOOGLE',\n",
258
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
259
+ " 'user_ratings_total': 125,\n",
260
+ " 'vicinity': '34/2-3 Soi Ratchawithi 9, Thanon Phaya Thai, Ratchathewi'},\n",
261
+ " {'business_status': 'OPERATIONAL',\n",
262
+ " 'geometry': {'location': {'lat': 13.7291738, 'lng': 100.5348174},\n",
263
+ " 'viewport': {'northeast': {'lat': 13.73046032989272,\n",
264
+ " 'lng': 100.5361918298927},\n",
265
+ " 'southwest': {'lat': 13.72776067010728, 'lng': 100.5334921701073}}},\n",
266
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
267
+ " 'icon_background_color': '#909CE1',\n",
268
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
269
+ " 'name': 'Pula Silom',\n",
270
+ " 'photos': [{'height': 2736,\n",
271
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/116104521503291528513\">伊藤弘昭</a>'],\n",
272
+ " 'photo_reference': 'AXCi2Q7Jx_Q-bmUQXHf21Up5jca5HIbehddLbxXNbliIJzRtirLIoDxEZBB29hDcPKa4l5xVKWDbHobbvvrO_L2DFMonrHr5s36M3_0dLea9j_KPOhtmXMp1T_0ZMfyX7-fwwN7xivn2o1fJ9k8XduGbbGLAlllgBa0TmT4jEZYN4qcNHRpi',\n",
273
+ " 'width': 3648}],\n",
274
+ " 'place_id': 'ChIJbbU8_yuf4jARUTtSdD5kt7s',\n",
275
+ " 'plus_code': {'compound_code': 'PGHM+MW Bangkok',\n",
276
+ " 'global_code': '7P52PGHM+MW'},\n",
277
+ " 'rating': 4.1,\n",
278
+ " 'reference': 'ChIJbbU8_yuf4jARUTtSdD5kt7s',\n",
279
+ " 'scope': 'GOOGLE',\n",
280
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
281
+ " 'user_ratings_total': 408,\n",
282
+ " 'vicinity': '60/12-15 Si Lom Rd, Silom, Bang Rak'},\n",
283
+ " {'business_status': 'OPERATIONAL',\n",
284
+ " 'geometry': {'location': {'lat': 13.7446989, 'lng': 100.5430063},\n",
285
+ " 'viewport': {'northeast': {'lat': 13.74605242989272,\n",
286
+ " 'lng': 100.5443317298927},\n",
287
+ " 'southwest': {'lat': 13.74335277010728, 'lng': 100.5416320701073}}},\n",
288
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
289
+ " 'icon_background_color': '#909CE1',\n",
290
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
291
+ " 'name': 'Golden House',\n",
292
+ " 'opening_hours': {'open_now': True},\n",
293
+ " 'photos': [{'height': 2017,\n",
294
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/113819510353645451169\">Golden House</a>'],\n",
295
+ " 'photo_reference': 'AXCi2Q7SNGkVzsificYOCpcJLixqVPAvgsnlvH8BqnoPmI5dKRJDzd5v5TOYHyQoZKkGVHoPzjr1Z964FihrKk-k_1PZw_J1ME_nsux1Q_xbozq6iekPVS7n6RvmuH6ueYSp0XTpo0FeawGHoJuy_5DPlHC9nJHYkzsl2mMcF2sb7-jqG1gZ',\n",
296
+ " 'width': 3162}],\n",
297
+ " 'place_id': 'ChIJIcSl3Nqe4jARnLh2qK_RMRo',\n",
298
+ " 'plus_code': {'compound_code': 'PGVV+V5 Bangkok',\n",
299
+ " 'global_code': '7P52PGVV+V5'},\n",
300
+ " 'rating': 3.7,\n",
301
+ " 'reference': 'ChIJIcSl3Nqe4jARnLh2qK_RMRo',\n",
302
+ " 'scope': 'GOOGLE',\n",
303
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
304
+ " 'user_ratings_total': 203,\n",
305
+ " 'vicinity': '1025/5-9 Ploenchit Road, Lumpinee, Pathum Wan'},\n",
306
+ " {'business_status': 'OPERATIONAL',\n",
307
+ " 'geometry': {'location': {'lat': 13.7559816, 'lng': 100.5363536},\n",
308
+ " 'viewport': {'northeast': {'lat': 13.75731082989272,\n",
309
+ " 'lng': 100.5377502298927},\n",
310
+ " 'southwest': {'lat': 13.75461117010728, 'lng': 100.5350505701073}}},\n",
311
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
312
+ " 'icon_background_color': '#909CE1',\n",
313
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
314
+ " 'name': 'Top High Airport Link Hotel',\n",
315
+ " 'opening_hours': {'open_now': True},\n",
316
+ " 'photos': [{'height': 2832,\n",
317
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/109602767181864547532\">A Google User</a>'],\n",
318
+ " 'photo_reference': 'AXCi2Q4dmmfllqiiSF6ET2O85klRu0znHLiv413DFjpor2RQow_l7XzHA-SqwKwO2z1_52DLfGzanhokS0pZscaSKNfS6jPcKC9mCwMllD5ZyOAP8GxyQiyslP5Y5RjAiBkXy8ViRv4aOSthNUehBdks-7yQmII9BxLx-Elpm4InCk46UlmZ',\n",
319
+ " 'width': 4256}],\n",
320
+ " 'place_id': 'ChIJcefUlMme4jARJGbWS6DCn9c',\n",
321
+ " 'plus_code': {'compound_code': 'QG4P+9G Bangkok',\n",
322
+ " 'global_code': '7P52QG4P+9G'},\n",
323
+ " 'rating': 3.9,\n",
324
+ " 'reference': 'ChIJcefUlMme4jARJGbWS6DCn9c',\n",
325
+ " 'scope': 'GOOGLE',\n",
326
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
327
+ " 'user_ratings_total': 1119,\n",
328
+ " 'vicinity': '33 Soi Phetchaburi 11, Thanon Phaya Thai, Ratchathewi'},\n",
329
+ " {'business_status': 'OPERATIONAL',\n",
330
+ " 'geometry': {'location': {'lat': 13.7614685, 'lng': 100.5376939},\n",
331
+ " 'viewport': {'northeast': {'lat': 13.76284452989272,\n",
332
+ " 'lng': 100.5389958798927},\n",
333
+ " 'southwest': {'lat': 13.76014487010728, 'lng': 100.5362962201073}}},\n",
334
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
335
+ " 'icon_background_color': '#909CE1',\n",
336
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
337
+ " 'name': 'Rose Apple Hotel',\n",
338
+ " 'photos': [{'height': 3024,\n",
339
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/109608969410824168250\">Fred</a>'],\n",
340
+ " 'photo_reference': 'AXCi2Q6zjoNtQ1zTKlHiyZ7PRXL2tageAblx1DpY1sYVYImvQw9DRkx86IKGJWiDbUiunBtN2wmFSlO2SYhFDND5Wm7fRBI0ll_8tOv0bFf-iIV-vpeEf_3vx-ABaqgeK7N4vuUnK_21XznpBAu19j5MptYAFiKOPmDYZ6_SJ7aIbsZNkQqu',\n",
341
+ " 'width': 4032}],\n",
342
+ " 'place_id': 'ChIJXTStwbCe4jARXRRo179r6nk',\n",
343
+ " 'plus_code': {'compound_code': 'QG6Q+H3 Bangkok',\n",
344
+ " 'global_code': '7P52QG6Q+H3'},\n",
345
+ " 'rating': 4.4,\n",
346
+ " 'reference': 'ChIJXTStwbCe4jARXRRo179r6nk',\n",
347
+ " 'scope': 'GOOGLE',\n",
348
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
349
+ " 'user_ratings_total': 139,\n",
350
+ " 'vicinity': '29/1 Soi Loet Punya, Thanon Phaya Thai, Ratchathewi'},\n",
351
+ " {'business_status': 'OPERATIONAL',\n",
352
+ " 'geometry': {'location': {'lat': 13.751193, 'lng': 100.5355507},\n",
353
+ " 'viewport': {'northeast': {'lat': 13.75254982989272,\n",
354
+ " 'lng': 100.5368565298927},\n",
355
+ " 'southwest': {'lat': 13.74985017010728, 'lng': 100.5341568701073}}},\n",
356
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
357
+ " 'icon_background_color': '#909CE1',\n",
358
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
359
+ " 'name': 'The Residence Ratchathewi',\n",
360
+ " 'opening_hours': {'open_now': True},\n",
361
+ " 'photos': [{'height': 1068,\n",
362
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/102286478336053372469\">The Residence Rajtaevee</a>'],\n",
363
+ " 'photo_reference': 'AXCi2Q5SM-DKx1XwfyUEK-5LuAzlFJMjmEgByT5v-0Q5iulo2CiIqOaPotdKbRBCObOYwsMfbasqecewPpWrqWQ_Iz6e7sAeSUVDlAfzwszEEb8WZBPG3IiPEUybhxfLmaG_Ubi5vX16bJYjDTjBVN493Tx_7zzkClVJiwVhhpZiDSIVwekh',\n",
364
+ " 'width': 1600}],\n",
365
+ " 'place_id': 'ChIJx0cHr86e4jAReGZBl579QlY',\n",
366
+ " 'plus_code': {'compound_code': 'QG2P+F7 Bangkok',\n",
367
+ " 'global_code': '7P52QG2P+F7'},\n",
368
+ " 'rating': 3.8,\n",
369
+ " 'reference': 'ChIJx0cHr86e4jAReGZBl579QlY',\n",
370
+ " 'scope': 'GOOGLE',\n",
371
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
372
+ " 'user_ratings_total': 442,\n",
373
+ " 'vicinity': '588/1 Phetchaburi Rd, Khwaeng Thanon Phetchaburi, Ratchathewi'},\n",
374
+ " {'business_status': 'OPERATIONAL',\n",
375
+ " 'geometry': {'location': {'lat': 13.7431972, 'lng': 100.5301387},\n",
376
+ " 'viewport': {'northeast': {'lat': 13.74441047989272,\n",
377
+ " 'lng': 100.5314606298927},\n",
378
+ " 'southwest': {'lat': 13.74171082010728, 'lng': 100.5287609701073}}},\n",
379
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
380
+ " 'icon_background_color': '#909CE1',\n",
381
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
382
+ " 'name': 'Pathumwan Princess Hotel',\n",
383
+ " 'opening_hours': {'open_now': True},\n",
384
+ " 'photos': [{'height': 2000,\n",
385
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/105529198599736349764\">A Google User</a>'],\n",
386
+ " 'photo_reference': 'AXCi2Q5vfp2-YyDznWo7BzJjpWdDG46oBD_E361wRvxqbPuTWQXeqw6ZJKLs4ApM57kGqfBWFCM8X4Ge1eMcr1CYyL2G2g2D5xaSjH0aZhOVby1DTuhoaQIutT1dD_bvhLC1L1yOh6_VEagO8MONFPbsVglCBG-5KdYWP8sz5Pb0msg92dLP',\n",
387
+ " 'width': 3000}],\n",
388
+ " 'place_id': 'ChIJFaLTtdKe4jARdKflx49LvdA',\n",
389
+ " 'plus_code': {'compound_code': 'PGVJ+73 Bangkok',\n",
390
+ " 'global_code': '7P52PGVJ+73'},\n",
391
+ " 'rating': 4.5,\n",
392
+ " 'reference': 'ChIJFaLTtdKe4jARdKflx49LvdA',\n",
393
+ " 'scope': 'GOOGLE',\n",
394
+ " 'types': ['shopping_mall',\n",
395
+ " 'tourist_attraction',\n",
396
+ " 'restaurant',\n",
397
+ " 'food',\n",
398
+ " 'lodging',\n",
399
+ " 'point_of_interest',\n",
400
+ " 'establishment'],\n",
401
+ " 'user_ratings_total': 7827,\n",
402
+ " 'vicinity': '444 Phaya Thai Rd, Wang Mai, Pathum Wan'},\n",
403
+ " {'business_status': 'OPERATIONAL',\n",
404
+ " 'geometry': {'location': {'lat': 13.7419343, 'lng': 100.5246099},\n",
405
+ " 'viewport': {'northeast': {'lat': 13.74333472989272,\n",
406
+ " 'lng': 100.5259674798927},\n",
407
+ " 'southwest': {'lat': 13.74063507010728, 'lng': 100.5232678201073}}},\n",
408
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
409
+ " 'icon_background_color': '#909CE1',\n",
410
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
411
+ " 'name': 'HOUSE OF PAPA BANGKOK SIAM',\n",
412
+ " 'opening_hours': {'open_now': True},\n",
413
+ " 'photos': [{'height': 1044,\n",
414
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/107232611473859075352\">A Google User</a>'],\n",
415
+ " 'photo_reference': 'AXCi2Q7jN3KUm4mIFgLRlbT3_UYH3VfSHoCBZX_9ovZXRxxVFG2RyJqj6iOeWGYDnZ0f4NG4cHNrbwNynR4hstsMUDDhafMc5thD8K1iBF-31OivN6fPwA0pqRt9HLNErtmiSxJugmpFqHV2u7q7Y1OCbFOyVfX_c3oLD24mzhkv5T960Ugf',\n",
416
+ " 'width': 1568}],\n",
417
+ " 'place_id': 'ChIJQVtmplSZ4jARsWxKD388HB0',\n",
418
+ " 'plus_code': {'compound_code': 'PGRF+QR Bangkok',\n",
419
+ " 'global_code': '7P52PGRF+QR'},\n",
420
+ " 'rating': 4.2,\n",
421
+ " 'reference': 'ChIJQVtmplSZ4jARsWxKD388HB0',\n",
422
+ " 'scope': 'GOOGLE',\n",
423
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
424
+ " 'user_ratings_total': 165,\n",
425
+ " 'vicinity': '188/44, Soi Chula 16, Wang Mai, Pathum Wan'},\n",
426
+ " {'business_status': 'OPERATIONAL',\n",
427
+ " 'geometry': {'location': {'lat': 13.7471052, 'lng': 100.5289501},\n",
428
+ " 'viewport': {'northeast': {'lat': 13.74819247989272,\n",
429
+ " 'lng': 100.5302628798927},\n",
430
+ " 'southwest': {'lat': 13.74549282010728, 'lng': 100.5275632201073}}},\n",
431
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
432
+ " 'icon_background_color': '#909CE1',\n",
433
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
434
+ " 'name': 'ไอบิส กรุงเทพ สยาม',\n",
435
+ " 'photos': [{'height': 1920,\n",
436
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/106297763246544925516\">Hotel ibis Bangkok Siam</a>'],\n",
437
+ " 'photo_reference': 'AXCi2Q5xaKlLVvq7ppUkSrD2tnTn34qtSlCFgfmE6xsnlhr1DA8wQ22pDGhzknJ1BKfmWax-GKW57vntFfXOVmTzM6fud-hatURpuFzGVmMPmu1716oqhBBk6mRvwRQN5bxsX5Wr_-yV_IOTrcjtTBG5-eCB8yETQeym9mDEVMIzogyoqA45',\n",
438
+ " 'width': 2880}],\n",
439
+ " 'place_id': 'ChIJaUcw7c2e4jAR0sfKCxcl2aM',\n",
440
+ " 'plus_code': {'compound_code': 'PGWH+RH Bangkok',\n",
441
+ " 'global_code': '7P52PGWH+RH'},\n",
442
+ " 'rating': 4.4,\n",
443
+ " 'reference': 'ChIJaUcw7c2e4jAR0sfKCxcl2aM',\n",
444
+ " 'scope': 'GOOGLE',\n",
445
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
446
+ " 'user_ratings_total': 2873,\n",
447
+ " 'vicinity': '927 Rama I Rd, Wangmai, Pathum Wan'},\n",
448
+ " {'business_status': 'OPERATIONAL',\n",
449
+ " 'geometry': {'location': {'lat': 13.7364607, 'lng': 100.5485186},\n",
450
+ " 'viewport': {'northeast': {'lat': 13.73779277989272,\n",
451
+ " 'lng': 100.5499788798927},\n",
452
+ " 'southwest': {'lat': 13.73509312010728, 'lng': 100.5472792201073}}},\n",
453
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
454
+ " 'icon_background_color': '#909CE1',\n",
455
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
456
+ " 'name': 'The Quart Ruamrudee by UHG',\n",
457
+ " 'photos': [{'height': 1108,\n",
458
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/113607345716697552408\">A Google User</a>'],\n",
459
+ " 'photo_reference': 'AXCi2Q6b1PqeLgJRnsC_1ElB0ibnqOOYWLhi7YE8J8RXFjeThrX1q51n0lP9LMzOvlSGxgpzzkbbu1ZPuAFfJ_GZswMXlZClrcN7iSDuMtfMXdL_knJHUBWe-1Eescu0Mnx09aL6gnivm4cDvinyBeBWxG9bDk-d6vcpNoICJ0fiO2MmZd2q',\n",
460
+ " 'width': 1477}],\n",
461
+ " 'place_id': 'ChIJS5Dv_n-f4jARd6xZQlSXjlM',\n",
462
+ " 'plus_code': {'compound_code': 'PGPX+HC Bangkok',\n",
463
+ " 'global_code': '7P52PGPX+HC'},\n",
464
+ " 'rating': 3.9,\n",
465
+ " 'reference': 'ChIJS5Dv_n-f4jARd6xZQlSXjlM',\n",
466
+ " 'scope': 'GOOGLE',\n",
467
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
468
+ " 'user_ratings_total': 538,\n",
469
+ " 'vicinity': '38/3 Soi Ruamrudee Community, Lumphini, Pathum Wan'},\n",
470
+ " {'business_status': 'OPERATIONAL',\n",
471
+ " 'geometry': {'location': {'lat': 13.7322506, 'lng': 100.5271641},\n",
472
+ " 'viewport': {'northeast': {'lat': 13.73356032989272,\n",
473
+ " 'lng': 100.5285219298927},\n",
474
+ " 'southwest': {'lat': 13.73086067010728, 'lng': 100.5258222701073}}},\n",
475
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
476
+ " 'icon_background_color': '#909CE1',\n",
477
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
478
+ " 'name': 'Sam Yan Serene Hotel',\n",
479
+ " 'photos': [{'height': 2268,\n",
480
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/117301360290051310020\">塩谷, 一</a>'],\n",
481
+ " 'photo_reference': 'AXCi2Q7n1pLt2iSHnPmh_q5Mf2g99zD3kKVTJnJfciX6R3SUcQWZ9xw2wC4xDlLgOWwwlwFwyqkc1EB-YBTEXg4RmDbTc5ynGR-ujCNJWJh8GAia999zgcok_-UWt0sta4E_wO4dCV6H_EMdu-iu6qSxxTt-uexcCbW8AHVpKEiwzsaRS5bQ',\n",
482
+ " 'width': 4032}],\n",
483
+ " 'place_id': 'ChIJq_Saj9aY4jAREUtIU3WA4Gk',\n",
484
+ " 'plus_code': {'compound_code': 'PGJG+WV Bangkok',\n",
485
+ " 'global_code': '7P52PGJG+WV'},\n",
486
+ " 'rating': 4,\n",
487
+ " 'reference': 'ChIJq_Saj9aY4jAREUtIU3WA4Gk',\n",
488
+ " 'scope': 'GOOGLE',\n",
489
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
490
+ " 'user_ratings_total': 285,\n",
491
+ " 'vicinity': '38 Si Phraya Rd, Bangkok'},\n",
492
+ " {'business_status': 'OPERATIONAL',\n",
493
+ " 'geometry': {'location': {'lat': 13.7372782, 'lng': 100.5170473},\n",
494
+ " 'viewport': {'northeast': {'lat': 13.73869057989272,\n",
495
+ " 'lng': 100.5184239798927},\n",
496
+ " 'southwest': {'lat': 13.73599092010728, 'lng': 100.5157243201073}}},\n",
497
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
498
+ " 'icon_background_color': '#909CE1',\n",
499
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
500
+ " 'name': 'Metro Hotel',\n",
501
+ " 'opening_hours': {'open_now': True},\n",
502
+ " 'photos': [{'height': 5067,\n",
503
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/105029968180924602999\">A Google User</a>'],\n",
504
+ " 'photo_reference': 'AXCi2Q7cr19LNUMipfJeB7TnqQw6nXsB26EadyXaYKXWhY4D-_dLCE45b14GtGoHkowfV10UsE4N6EmR3w_CsLSOEpeyGkRIU-rnP3-8lf-xyVl6om-Rc6RvpSI2QCx8OrbOJZIl1BBc0icvbAMD-ctah05qNmdiJwR0Kdh8HlAO_8H_zk9Q',\n",
505
+ " 'width': 3378}],\n",
506
+ " 'place_id': 'ChIJIeFfV9aZ4jARpd4v7wFD6BQ',\n",
507
+ " 'plus_code': {'compound_code': 'PGP8+VR Bangkok',\n",
508
+ " 'global_code': '7P52PGP8+VR'},\n",
509
+ " 'rating': 4.8,\n",
510
+ " 'reference': 'ChIJIeFfV9aZ4jARpd4v7wFD6BQ',\n",
511
+ " 'scope': 'GOOGLE',\n",
512
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
513
+ " 'user_ratings_total': 654,\n",
514
+ " 'vicinity': '326, 20-22 Rama IV Rd, Mahapreuttaram, Bang Rak'},\n",
515
+ " {'business_status': 'OPERATIONAL',\n",
516
+ " 'geometry': {'location': {'lat': 13.7465184, 'lng': 100.5408834},\n",
517
+ " 'viewport': {'northeast': {'lat': 13.74800027989272,\n",
518
+ " 'lng': 100.5420810298927},\n",
519
+ " 'southwest': {'lat': 13.74530062010728, 'lng': 100.5393813701073}}},\n",
520
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
521
+ " 'icon_background_color': '#909CE1',\n",
522
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
523
+ " 'name': 'Arnoma Grand Bangkok',\n",
524
+ " 'opening_hours': {'open_now': False},\n",
525
+ " 'photos': [{'height': 2268,\n",
526
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/110341251183134667765\">Joshua Elmer Dungca</a>'],\n",
527
+ " 'photo_reference': 'AXCi2Q5MfTeLf7FACorI5XTlxWwS4AypfcTJ4kFFRZk922b6MMVawZdZndQg92tWUMIdysVxM9TudMI0BtJWYm7nuDsAHDY9h4YLGS8MNdy3ov3FvOKsFJkRMGNwfk3DoAPVAeseLxMh_P8Uz65WdULELRQFlXNZEKeSiYhX4Ctenb_6Ez05',\n",
528
+ " 'width': 4032}],\n",
529
+ " 'place_id': 'ChIJF8c59s-e4jARoz5R8nHRj2Y',\n",
530
+ " 'plus_code': {'compound_code': 'PGWR+J9 Bangkok',\n",
531
+ " 'global_code': '7P52PGWR+J9'},\n",
532
+ " 'rating': 4,\n",
533
+ " 'reference': 'ChIJF8c59s-e4jARoz5R8nHRj2Y',\n",
534
+ " 'scope': 'GOOGLE',\n",
535
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
536
+ " 'user_ratings_total': 2601,\n",
537
+ " 'vicinity': '99 Ratchadamri Rd, Lumphini, Pathum Wan'},\n",
538
+ " {'business_status': 'OPERATIONAL',\n",
539
+ " 'geometry': {'location': {'lat': 13.7339076, 'lng': 100.5265974},\n",
540
+ " 'viewport': {'northeast': {'lat': 13.73522732989272,\n",
541
+ " 'lng': 100.5279341798927},\n",
542
+ " 'southwest': {'lat': 13.73252767010728, 'lng': 100.5252345201073}}},\n",
543
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
544
+ " 'icon_background_color': '#909CE1',\n",
545
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
546
+ " 'name': 'Chatel Bkk',\n",
547
+ " 'opening_hours': {'open_now': True},\n",
548
+ " 'photos': [{'height': 3719,\n",
549
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/106598160335074447056\">A Google User</a>'],\n",
550
+ " 'photo_reference': 'AXCi2Q5XT1UqDzekBotIXdVzCAsxMvwZ34SlJF-d4-vKKbJlYK6AuYmJqNzErrTV0J-6P30JduNShr_gSZ_RKlRAVTcP2dsHvKyg7U5o5dxzGwOthzZXKGPQEsb4JPtyrxyC99H71rhIP_fiypmLgQBvUms1GrsHlNq4CqfcTDngO7MO93x7',\n",
551
+ " 'width': 2479}],\n",
552
+ " 'place_id': 'ChIJFdaF_GSZ4jARuvbTqZTXVDw',\n",
553
+ " 'plus_code': {'compound_code': 'PGMG+HJ Bangkok',\n",
554
+ " 'global_code': '7P52PGMG+HJ'},\n",
555
+ " 'rating': 4.4,\n",
556
+ " 'reference': 'ChIJFdaF_GSZ4jARuvbTqZTXVDw',\n",
557
+ " 'scope': 'GOOGLE',\n",
558
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
559
+ " 'user_ratings_total': 51,\n",
560
+ " 'vicinity': '1523 Rama IV Rd, Wang Mai, Pathum Wan'},\n",
561
+ " {'business_status': 'OPERATIONAL',\n",
562
+ " 'geometry': {'location': {'lat': 13.7571273, 'lng': 100.5219133},\n",
563
+ " 'viewport': {'northeast': {'lat': 13.75845417989272,\n",
564
+ " 'lng': 100.5233274798927},\n",
565
+ " 'southwest': {'lat': 13.75575452010728, 'lng': 100.5206278201073}}},\n",
566
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
567
+ " 'icon_background_color': '#909CE1',\n",
568
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
569
+ " 'name': 'Bangkok City Suite Hotel',\n",
570
+ " 'opening_hours': {'open_now': True},\n",
571
+ " 'photos': [{'height': 3024,\n",
572
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/114354012153022786846\">A Google User</a>'],\n",
573
+ " 'photo_reference': 'AXCi2Q5UyAkBzi6Mfc9I5YPy7GkFHc6n6x0zOixA7U8iDsmS-vVCFLjTbv6fITGoTHqh2YrsVpm-2fmt6_mwHpjqYPn1We7okIhQRf6Lt3eQNRxOydhhk0Qrf5oT9mvx6WEuSUgOP6tPHPCTxY53z-W9zPZmnLCAWc6WO2mnLkVzL0EG2yny',\n",
574
+ " 'width': 4032}],\n",
575
+ " 'place_id': 'ChIJVZaxPHBvHTERUmo7I6b5kt0',\n",
576
+ " 'plus_code': {'compound_code': 'QG4C+VQ Bangkok',\n",
577
+ " 'global_code': '7P52QG4C+VQ'},\n",
578
+ " 'rating': 3.9,\n",
579
+ " 'reference': 'ChIJVZaxPHBvHTERUmo7I6b5kt0',\n",
580
+ " 'scope': 'GOOGLE',\n",
581
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
582
+ " 'user_ratings_total': 1306,\n",
583
+ " 'vicinity': '1 Petchburi Road Khwaeng Thung Phaya Thai, Ratchathewi'},\n",
584
+ " {'business_status': 'OPERATIONAL',\n",
585
+ " 'geometry': {'location': {'lat': 13.7469059, 'lng': 100.5488508},\n",
586
+ " 'viewport': {'northeast': {'lat': 13.74826502989272,\n",
587
+ " 'lng': 100.5502038798927},\n",
588
+ " 'southwest': {'lat': 13.74556537010728, 'lng': 100.5475042201073}}},\n",
589
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
590
+ " 'icon_background_color': '#909CE1',\n",
591
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
592
+ " 'name': 'Nantra Ploenchit hotel',\n",
593
+ " 'photos': [{'height': 4032,\n",
594
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/112882529924094151036\">112882529924094151036</a>'],\n",
595
+ " 'photo_reference': 'AXCi2Q7GqZhH0esGR-zcPCShb-NTd6lBBLoasdckPbr-FKmo-dFkuY3Zpyh464c4Q5vHz80hqRsc0KGrZrFh0ujJwprqjvF4vY3I7FvLAOoh_cPWoU_a87IRZxhilZ8_6NmtUhIjP8bzsdEQgw66eo19rl77YmxA8cJEcQc2fsbNfboauPDu',\n",
596
+ " 'width': 3024}],\n",
597
+ " 'place_id': 'ChIJEV_8Viqf4jARu_t2Fy_JV1Q',\n",
598
+ " 'plus_code': {'compound_code': 'PGWX+PG Bangkok',\n",
599
+ " 'global_code': '7P52PGWX+PG'},\n",
600
+ " 'rating': 3,\n",
601
+ " 'reference': 'ChIJEV_8Viqf4jARu_t2Fy_JV1Q',\n",
602
+ " 'scope': 'GOOGLE',\n",
603
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
604
+ " 'user_ratings_total': 202,\n",
605
+ " 'vicinity': '27/12 Soi Nai Loet, Lumphini, Pathum Wan'},\n",
606
+ " {'business_status': 'OPERATIONAL',\n",
607
+ " 'geometry': {'location': {'lat': 13.7300383, 'lng': 100.5311334},\n",
608
+ " 'viewport': {'northeast': {'lat': 13.73128477989272,\n",
609
+ " 'lng': 100.5325170298927},\n",
610
+ " 'southwest': {'lat': 13.72858512010728, 'lng': 100.5298173701073}}},\n",
611
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
612
+ " 'icon_background_color': '#909CE1',\n",
613
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
614
+ " 'name': '56 Surawong Hotel Bangkok',\n",
615
+ " 'opening_hours': {'open_now': True},\n",
616
+ " 'photos': [{'height': 1067,\n",
617
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/114284465264360387169\">A Google User</a>'],\n",
618
+ " 'photo_reference': 'AXCi2Q4GgGfJLURqRbHSfZ5MAc1dCZf_NUFv9aJ9yhRd5t7XvuXiUQRLPkXuUYRL3M7GCmx_YbvhRCUDLYwFcMEap9trlMS8W10K6ToaY0HjQFfqgy7g6rJfUYU6-_9nDt_oS9XdS9Pp0nK2x9W0wZ2tpZ5zib1JbOp_h9Zdf4ri4Z-wgfla',\n",
619
+ " 'width': 1600}],\n",
620
+ " 'place_id': 'ChIJOw15HtOY4jARCqQ2iTDgqYc',\n",
621
+ " 'plus_code': {'compound_code': 'PGJJ+2F Bangkok',\n",
622
+ " 'global_code': '7P52PGJJ+2F'},\n",
623
+ " 'rating': 3.9,\n",
624
+ " 'reference': 'ChIJOw15HtOY4jARCqQ2iTDgqYc',\n",
625
+ " 'scope': 'GOOGLE',\n",
626
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
627
+ " 'user_ratings_total': 228,\n",
628
+ " 'vicinity': '56 Surawong Rd, Silom, Bang Rak'},\n",
629
+ " []]"
630
+ ]
631
+ },
632
+ "execution_count": 7,
633
+ "metadata": {},
634
+ "output_type": "execute_result"
635
+ }
636
+ ],
637
+ "source": [
638
+ "def nearby_search(keyword:str, location:str, radius=2000, place_type=None):\n",
639
+ " # Retrieve the API key from environment variables\n",
640
+ " api_key = os.getenv('GPLACES_API_KEY')\n",
641
+ "\n",
642
+ " if not api_key:\n",
643
+ " raise ValueError(\"API key not found. Please set the GOOGLE_MAPS_API_KEY environment variable.\")\n",
644
+ "\n",
645
+ " # Define the endpoint URL\n",
646
+ " url = \"https://maps.googleapis.com/maps/api/place/nearbysearch/json\"\n",
647
+ "\n",
648
+ " # Set up the parameters for the request\n",
649
+ " params = {\n",
650
+ " 'keyword': keyword,\n",
651
+ " 'location': location,\n",
652
+ " 'radius': radius,\n",
653
+ " 'type': place_type,\n",
654
+ " 'key': api_key,\n",
655
+ " \"rankPreference\": \"DISTANCE\"\n",
656
+ " }\n",
657
+ "\n",
658
+ " # Send the GET request to the Google Maps API\n",
659
+ " response = requests.get(url, params=params)\n",
660
+ "\n",
661
+ " # Check if the request was successful\n",
662
+ " if response.status_code != 200:\n",
663
+ " raise Exception(f\"Error with request: {response.status_code}, {response.text}\")\n",
664
+ "\n",
665
+ " # Parse the JSON response\n",
666
+ " data = response.json()\n",
667
+ " results = data['results']\n",
668
+ "\n",
669
+ " # search into next page\n",
670
+ " while data.get('next_page_token', False):\n",
671
+ " params = {'next_page_token': data['next_page_token']}\n",
672
+ " response = requests.get(url, params=params)\n",
673
+ " \n",
674
+ " if response.status_code != 200:\n",
675
+ " raise Exception(f\"Error with request: {response.status_code}, {response.text}\")\n",
676
+ " \n",
677
+ " data = response.json()\n",
678
+ " \n",
679
+ " results.append(data['results'])\n",
680
+ " \n",
681
+ "\n",
682
+ " # Return the response data\n",
683
+ " return results\n",
684
+ "\n",
685
+ "\n",
686
+ "# Example usage\n",
687
+ "location = \"13.744677,100.5295593\" # Latitude and Longitude\n",
688
+ "keyword = \"hotel\"\n",
689
+ "search_results = nearby_search(keyword, location)\n",
690
+ "search_results"
691
+ ]
692
+ },
693
+ {
694
+ "cell_type": "code",
695
+ "execution_count": 8,
696
+ "metadata": {},
697
+ "outputs": [
698
+ {
699
+ "data": {
700
+ "text/plain": [
701
+ "[{'geometry': {'location': {'lat': 13.7563309, 'lng': 100.5017651},\n",
702
+ " 'viewport': {'northeast': {'lat': 13.9551109646008,\n",
703
+ " 'lng': 100.9384080394661},\n",
704
+ " 'southwest': {'lat': 13.4940880622837, 'lng': 100.3278135588086}}},\n",
705
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/geocode-71.png',\n",
706
+ " 'icon_background_color': '#7B9EB0',\n",
707
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/generic_pinlet',\n",
708
+ " 'name': 'Bangkok',\n",
709
+ " 'photos': [{'height': 934,\n",
710
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/107853816016331257868\">Harshvardhan Mali</a>'],\n",
711
+ " 'photo_reference': 'AXCi2Q7YQKg0xaKoM2A3vnYzyOIQDC5TrsQxNtbyot19fPkxmovfe5guH88XxTEr5R8FCOErr4FCh0o6j1HixapR7hf4vxt-BqYE7pt_5ALwZaeCvO8b7CAtTX6gTmH7euXg0NbxdLQhUE7h_LB2OaUgr4mBnTVHr2d0pnLYOBoPmuSQbIXP',\n",
712
+ " 'width': 756}],\n",
713
+ " 'place_id': 'ChIJ82ENKDJgHTERIEjiXbIAAQE',\n",
714
+ " 'reference': 'ChIJ82ENKDJgHTERIEjiXbIAAQE',\n",
715
+ " 'scope': 'GOOGLE',\n",
716
+ " 'types': ['locality', 'political'],\n",
717
+ " 'vicinity': 'Bangkok'},\n",
718
+ " {'business_status': 'OPERATIONAL',\n",
719
+ " 'geometry': {'location': {'lat': 13.7431972, 'lng': 100.5301387},\n",
720
+ " 'viewport': {'northeast': {'lat': 13.7444096302915,\n",
721
+ " 'lng': 100.5314597802915},\n",
722
+ " 'southwest': {'lat': 13.7417116697085, 'lng': 100.5287618197085}}},\n",
723
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
724
+ " 'icon_background_color': '#909CE1',\n",
725
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
726
+ " 'name': 'Pathumwan Princess Hotel',\n",
727
+ " 'opening_hours': {'open_now': True},\n",
728
+ " 'photos': [{'height': 2000,\n",
729
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/105529198599736349764\">Pathumwan Princess Hotel</a>'],\n",
730
+ " 'photo_reference': 'AXCi2Q5LkQj0Ts-4Sp_GZYboiNY7C5G7Mq6jPeLjvphMxG5T5C-HKDqOHURuvjxIF52_-5BzLu_9QJk0__pY-cizYAN6GoUEpV_busoOGPt67wmF9d-0Xg8ma_61xPbXC1s2oPvqVLTAMO9586thNfnNZZYRsspucrS0xL4m45-0XjknvQPU',\n",
731
+ " 'width': 3000}],\n",
732
+ " 'place_id': 'ChIJFaLTtdKe4jARdKflx49LvdA',\n",
733
+ " 'plus_code': {'compound_code': 'PGVJ+73 Bangkok, Thailand',\n",
734
+ " 'global_code': '7P52PGVJ+73'},\n",
735
+ " 'rating': 4.5,\n",
736
+ " 'reference': 'ChIJFaLTtdKe4jARdKflx49LvdA',\n",
737
+ " 'scope': 'GOOGLE',\n",
738
+ " 'types': ['shopping_mall',\n",
739
+ " 'lodging',\n",
740
+ " 'tourist_attraction',\n",
741
+ " 'restaurant',\n",
742
+ " 'food',\n",
743
+ " 'point_of_interest',\n",
744
+ " 'establishment'],\n",
745
+ " 'user_ratings_total': 7827,\n",
746
+ " 'vicinity': '444 Phaya Thai Road, Khwaeng Wang Mai, Pathum Wan'},\n",
747
+ " {'business_status': 'OPERATIONAL',\n",
748
+ " 'geometry': {'location': {'lat': 13.7484011, 'lng': 100.5348436},\n",
749
+ " 'viewport': {'northeast': {'lat': 13.7497612802915,\n",
750
+ " 'lng': 100.5361483302915},\n",
751
+ " 'southwest': {'lat': 13.7470633197085, 'lng': 100.5334503697085}}},\n",
752
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
753
+ " 'icon_background_color': '#909CE1',\n",
754
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
755
+ " 'name': 'Siam Kempinski Hotel Bangkok',\n",
756
+ " 'photos': [{'height': 1080,\n",
757
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/101520779225452139808\">Siam Kempinski Hotel Bangkok</a>'],\n",
758
+ " 'photo_reference': 'AXCi2Q7EgE9SGO-SvlsR16qRVmWU6cn3DnYXS9Vc3ee9OegYK0RR9nW3eUEZA03XPAxqb9TurWDybQmlbnzf21ccieSRCGxyPhQjRQG8zySzjWmYA8I-KuTnr1Gnl_LOpmv3d1Q4aHI7SqybBee6mCwiDp4yFlCNzxAgkmn8TmMjEulv4U-_',\n",
759
+ " 'width': 1920}],\n",
760
+ " 'place_id': 'ChIJrfU90s2e4jARs0XZP2DZ4jM',\n",
761
+ " 'plus_code': {'compound_code': 'PGXM+9W Bangkok, Thailand',\n",
762
+ " 'global_code': '7P52PGXM+9W'},\n",
763
+ " 'rating': 4.7,\n",
764
+ " 'reference': 'ChIJrfU90s2e4jARs0XZP2DZ4jM',\n",
765
+ " 'scope': 'GOOGLE',\n",
766
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
767
+ " 'user_ratings_total': 5171,\n",
768
+ " 'vicinity': '991, 9 Rama I Road, Khwaeng Pathum Wan, Pathum Wan'},\n",
769
+ " {'business_status': 'OPERATIONAL',\n",
770
+ " 'geometry': {'location': {'lat': 13.7477183, 'lng': 100.5387477},\n",
771
+ " 'viewport': {'northeast': {'lat': 13.7491090802915,\n",
772
+ " 'lng': 100.5398112302915},\n",
773
+ " 'southwest': {'lat': 13.7464111197085, 'lng': 100.5371132697085}}},\n",
774
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
775
+ " 'icon_background_color': '#909CE1',\n",
776
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
777
+ " 'name': 'Centara Grand & Bangkok Convention Centre at centralwOrld',\n",
778
+ " 'opening_hours': {'open_now': True},\n",
779
+ " 'photos': [{'height': 2832,\n",
780
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/108880770713939695570\">Centara Grand &amp; Bangkok Convention Centre at centralwOrld</a>'],\n",
781
+ " 'photo_reference': 'AXCi2Q7Ta6rxawyYVXTRXdSg2x9t-a80ym0BUeS2ypzi8H0zQzUiQh_JpBu_rx2PfIjnMvCEIDbTbJcm-3ra4G9_HbJrTD7wp5y5HWr7Cd2wnedaBck-VuSdEOHwP5NAYJU0qh_2uAUPGXaOME5WepAUjZr5czm5KPHI3U9Q8oMc5Aodw_QW',\n",
782
+ " 'width': 4148}],\n",
783
+ " 'place_id': 'ChIJf1YJeC-Z4jARNNLn8M9QwMw',\n",
784
+ " 'plus_code': {'compound_code': 'PGXQ+3F Bangkok, Thailand',\n",
785
+ " 'global_code': '7P52PGXQ+3F'},\n",
786
+ " 'rating': 4.6,\n",
787
+ " 'reference': 'ChIJf1YJeC-Z4jARNNLn8M9QwMw',\n",
788
+ " 'scope': 'GOOGLE',\n",
789
+ " 'types': ['bar',\n",
790
+ " 'lodging',\n",
791
+ " 'spa',\n",
792
+ " 'restaurant',\n",
793
+ " 'food',\n",
794
+ " 'point_of_interest',\n",
795
+ " 'establishment'],\n",
796
+ " 'user_ratings_total': 6175,\n",
797
+ " 'vicinity': '999, 99 Rama I Road, Khwaeng Pathum Wan, Pathum Wan'},\n",
798
+ " {'business_status': 'OPERATIONAL',\n",
799
+ " 'geometry': {'location': {'lat': 13.750779, 'lng': 100.5306845},\n",
800
+ " 'viewport': {'northeast': {'lat': 13.7521981302915,\n",
801
+ " 'lng': 100.5321781302915},\n",
802
+ " 'southwest': {'lat': 13.7495001697085, 'lng': 100.5294801697085}}},\n",
803
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
804
+ " 'icon_background_color': '#909CE1',\n",
805
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
806
+ " 'name': 'Evergreen Place Siam by UHG',\n",
807
+ " 'opening_hours': {'open_now': True},\n",
808
+ " 'photos': [{'height': 4752,\n",
809
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/101915072604208031209\">Evergreen Place Bangkok</a>'],\n",
810
+ " 'photo_reference': 'AXCi2Q4muyWoLyCdS-OALMacN_R7o7xCPoGgvlERfZ_NhHG2HH7J_YieoOxuxELqy974nkWvto5G5y0baqoaIeKnIKjjFD95ztA0XRQNG3-3j6EA435MOmiyHifAZpC5Y-o0Hy4QL7DXWZQ_WMu4ZaL4LjlrdWo75XcO_qnMVPCIK1nghWtU',\n",
811
+ " 'width': 3168}],\n",
812
+ " 'place_id': 'ChIJH2h86IGe4jARE5sKrclMXL8',\n",
813
+ " 'plus_code': {'compound_code': 'QG2J+87 Bangkok, Thailand',\n",
814
+ " 'global_code': '7P52QG2J+87'},\n",
815
+ " 'rating': 4.1,\n",
816
+ " 'reference': 'ChIJH2h86IGe4jARE5sKrclMXL8',\n",
817
+ " 'scope': 'GOOGLE',\n",
818
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
819
+ " 'user_ratings_total': 2228,\n",
820
+ " 'vicinity': '318 Phaya Thai Road, Khwaeng Thanon Phetchaburi, Khet Ratchathewi'},\n",
821
+ " {'business_status': 'OPERATIONAL',\n",
822
+ " 'geometry': {'location': {'lat': 13.7511798, 'lng': 100.5356322},\n",
823
+ " 'viewport': {'northeast': {'lat': 13.7525489802915,\n",
824
+ " 'lng': 100.5368556802915},\n",
825
+ " 'southwest': {'lat': 13.7498510197085, 'lng': 100.5341577197085}}},\n",
826
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
827
+ " 'icon_background_color': '#909CE1',\n",
828
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
829
+ " 'name': 'The Residence Ratchathewi',\n",
830
+ " 'opening_hours': {'open_now': True},\n",
831
+ " 'photos': [{'height': 1068,\n",
832
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/102286478336053372469\">The Residence Ratchathewi</a>'],\n",
833
+ " 'photo_reference': 'AXCi2Q40k5jMnJW1S1uGhuZSW94oIfZF8wHpo3Bj6TJC3E4sdysozDQh2lqjxEvpmvAQtGy4Eg6PcTx2HrUUvOIP9Y15DkZFmGn-lMQh8pA5OLCt0GYm06OhU0yQfdXimxI4sf51LoVmCPQe8fmDUslDwGIvofrR_x3JCEP0VCOG0nIkoZwS',\n",
834
+ " 'width': 1600}],\n",
835
+ " 'place_id': 'ChIJx0cHr86e4jAReGZBl579QlY',\n",
836
+ " 'plus_code': {'compound_code': 'QG2P+F7 Bangkok, Thailand',\n",
837
+ " 'global_code': '7P52QG2P+F7'},\n",
838
+ " 'rating': 3.8,\n",
839
+ " 'reference': 'ChIJx0cHr86e4jAReGZBl579QlY',\n",
840
+ " 'scope': 'GOOGLE',\n",
841
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
842
+ " 'user_ratings_total': 442,\n",
843
+ " 'vicinity': '588/1 Phetchaburi Road, Khet Ratchathewi'},\n",
844
+ " {'business_status': 'OPERATIONAL',\n",
845
+ " 'geometry': {'location': {'lat': 13.7513459, 'lng': 100.5310997},\n",
846
+ " 'viewport': {'northeast': {'lat': 13.7528344302915,\n",
847
+ " 'lng': 100.5325368302915},\n",
848
+ " 'southwest': {'lat': 13.7501364697085, 'lng': 100.5298388697085}}},\n",
849
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
850
+ " 'icon_background_color': '#909CE1',\n",
851
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
852
+ " 'name': 'Asia Hotel Bangkok',\n",
853
+ " 'opening_hours': {'open_now': True},\n",
854
+ " 'photos': [{'height': 427,\n",
855
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/115065590130967456230\">Asia Hotel Bangkok</a>'],\n",
856
+ " 'photo_reference': 'AXCi2Q7nMLxEeLXVxZNstAsZ4vDIIYT7CHmklnHs1AAJGRKHwwjF8Blo6GhibN3c1kYltnfCdETbxjybjxNlUCDwOPjUbnsuWWn00LLOxHmr1RxmFgte3N_5yD7NrL7vz3sx_nHorDWjsvlaWS9Hnp1DFUghMBmpOetKLYppCei033sqH4h-',\n",
857
+ " 'width': 640}],\n",
858
+ " 'place_id': 'ChIJH2h86IGe4jARyjZ6wppSlkQ',\n",
859
+ " 'plus_code': {'compound_code': 'QG2J+GC Bangkok, Thailand',\n",
860
+ " 'global_code': '7P52QG2J+GC'},\n",
861
+ " 'rating': 4,\n",
862
+ " 'reference': 'ChIJH2h86IGe4jARyjZ6wppSlkQ',\n",
863
+ " 'scope': 'GOOGLE',\n",
864
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
865
+ " 'user_ratings_total': 5468,\n",
866
+ " 'vicinity': '296 Phaya Thai Road'},\n",
867
+ " {'business_status': 'OPERATIONAL',\n",
868
+ " 'geometry': {'location': {'lat': 13.7497353, 'lng': 100.5403252},\n",
869
+ " 'viewport': {'northeast': {'lat': 13.7510947302915,\n",
870
+ " 'lng': 100.5419947802915},\n",
871
+ " 'southwest': {'lat': 13.7483967697085, 'lng': 100.5392968197085}}},\n",
872
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
873
+ " 'icon_background_color': '#909CE1',\n",
874
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
875
+ " 'name': 'Novotel Bangkok Platinum Pratunam',\n",
876
+ " 'photos': [{'height': 4024,\n",
877
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/104545848999971265611\">Novotel Bangkok Platinum Pratunam</a>'],\n",
878
+ " 'photo_reference': 'AXCi2Q6qBZ56Y6UPn9TtOCZxNBKny35eINZpxu6Ll7MarDESm49gmVQxgfnXD8ry7DYY501I4bmEyaocd0DT1oVse5HR4fe5tLL_xfNR5lIvJ1-2MPnjBvFRJaVJ-0URC0xxL808OuQvPtRVGi6oUuMCZ5aG6KAfMUpukCZ7PZFW_Z7zx67e',\n",
879
+ " 'width': 6048}],\n",
880
+ " 'place_id': 'ChIJN6o_Yc-e4jARBCxlg57zM4s',\n",
881
+ " 'plus_code': {'compound_code': 'PGXR+V4 Bangkok, Thailand',\n",
882
+ " 'global_code': '7P52PGXR+V4'},\n",
883
+ " 'rating': 4.4,\n",
884
+ " 'reference': 'ChIJN6o_Yc-e4jARBCxlg57zM4s',\n",
885
+ " 'scope': 'GOOGLE',\n",
886
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
887
+ " 'user_ratings_total': 4798,\n",
888
+ " 'vicinity': '220 Phetchaburi Road'},\n",
889
+ " {'business_status': 'OPERATIONAL',\n",
890
+ " 'geometry': {'location': {'lat': 13.7467415, 'lng': 100.5287877},\n",
891
+ " 'viewport': {'northeast': {'lat': 13.7480168802915,\n",
892
+ " 'lng': 100.5301780802915},\n",
893
+ " 'southwest': {'lat': 13.7453189197085, 'lng': 100.5274801197085}}},\n",
894
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
895
+ " 'icon_background_color': '#909CE1',\n",
896
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
897
+ " 'name': 'MERCURE BANGKOK SIAM',\n",
898
+ " 'photos': [{'height': 768,\n",
899
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/114445502763328018172\">MERCURE BANGKOK SIAM</a>'],\n",
900
+ " 'photo_reference': 'AXCi2Q4h4s74XCGAsTARx1UNg18HQj3Zq8H1K-V6fC7bSuPDnIvDt3KCNUokAsMNcYe51GuFfrI6HzgnOMTbsS2H8R2vNdV2ux_A2VJQiNT2L7Np-M_gTDIUbYlD_uvyJDZQ-Pd3PknEz4x64mInT25nsq_R6YTq1ZvcrHiy0XZCl1lqX6Al',\n",
901
+ " 'width': 1024}],\n",
902
+ " 'place_id': 'ChIJKS_DaA6Z4jARDH_5sbrMXfI',\n",
903
+ " 'plus_code': {'compound_code': 'PGWH+MG Bangkok, Thailand',\n",
904
+ " 'global_code': '7P52PGWH+MG'},\n",
905
+ " 'rating': 4.4,\n",
906
+ " 'reference': 'ChIJKS_DaA6Z4jARDH_5sbrMXfI',\n",
907
+ " 'scope': 'GOOGLE',\n",
908
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
909
+ " 'user_ratings_total': 2243,\n",
910
+ " 'vicinity': '927 Rama I Road, Wangmai'},\n",
911
+ " {'business_status': 'OPERATIONAL',\n",
912
+ " 'geometry': {'location': {'lat': 13.748779, 'lng': 100.530772},\n",
913
+ " 'viewport': {'northeast': {'lat': 13.7499488302915,\n",
914
+ " 'lng': 100.5321700302915},\n",
915
+ " 'southwest': {'lat': 13.7472508697085, 'lng': 100.5294720697085}}},\n",
916
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
917
+ " 'icon_background_color': '#909CE1',\n",
918
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
919
+ " 'name': 'Hua Chang Heritage Hotel',\n",
920
+ " 'photos': [{'height': 2912,\n",
921
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/115552232905673664668\">มิสสยาม โรงแรมหัวช้าง เฮอริเทจ</a>'],\n",
922
+ " 'photo_reference': 'AXCi2Q6Sbu_BgfBc6TSf5sOYIsTgC8JzttjJIuMgMwsTHAOhwCq-d1QOPKbtwbBNLLS0dfVXu4XHqkYBLYab0AEBtTa59con0Gw2L4F3MgQfjw_Y0mF9R9XgKFHdXMn0XZgyqlEpby-wswex8VgXV-dn9k_eequgTZuuZfGyDGhYsT1C3sYl',\n",
923
+ " 'width': 4271}],\n",
924
+ " 'place_id': 'ChIJUUD5KBOZ4jAR0QLGy07t3BQ',\n",
925
+ " 'plus_code': {'compound_code': 'PGXJ+G8 Bangkok, Thailand',\n",
926
+ " 'global_code': '7P52PGXJ+G8'},\n",
927
+ " 'rating': 4.3,\n",
928
+ " 'reference': 'ChIJUUD5KBOZ4jAR0QLGy07t3BQ',\n",
929
+ " 'scope': 'GOOGLE',\n",
930
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
931
+ " 'user_ratings_total': 1056,\n",
932
+ " 'vicinity': '400 Phaya Thai Road, Khwaeng Wang Mai, Pathum Wan'},\n",
933
+ " {'business_status': 'OPERATIONAL',\n",
934
+ " 'geometry': {'location': {'lat': 13.7417243, 'lng': 100.5410489},\n",
935
+ " 'viewport': {'northeast': {'lat': 13.7429306802915,\n",
936
+ " 'lng': 100.5424668802915},\n",
937
+ " 'southwest': {'lat': 13.7402327197085, 'lng': 100.5397689197085}}},\n",
938
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
939
+ " 'icon_background_color': '#909CE1',\n",
940
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
941
+ " 'name': 'Grande Centre Point Ratchadamri',\n",
942
+ " 'opening_hours': {'open_now': True},\n",
943
+ " 'photos': [{'height': 1999,\n",
944
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/106290596075567109314\">Grande Centre Point Ratchadamri</a>'],\n",
945
+ " 'photo_reference': 'AXCi2Q53dAR1e3p0YCUsrw--FQNC6neK_zSj7XU5g_tc21UVLf8VbQjX9rPnjq-gdyQa-kzRV9RD-X3Eg9uzoiTU8VAjQ0NioZH_MPqfSwAF2elwNdMZZH24hWmkkf5GnZmx0bZLRjKQjF-dITj_EnIYP9Extu-HmFIOlDENhXuD4t1o89JA',\n",
946
+ " 'width': 3214}],\n",
947
+ " 'place_id': 'ChIJMckScdqe4jARnCUZdPKRjF8',\n",
948
+ " 'plus_code': {'compound_code': 'PGRR+MC Bangkok, Thailand',\n",
949
+ " 'global_code': '7P52PGRR+MC'},\n",
950
+ " 'rating': 4.5,\n",
951
+ " 'reference': 'ChIJMckScdqe4jARnCUZdPKRjF8',\n",
952
+ " 'scope': 'GOOGLE',\n",
953
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
954
+ " 'user_ratings_total': 3963,\n",
955
+ " 'vicinity': '153, 2 Thanon Ratchadamri, Khwaeng Lumphini, Pathum Wan'},\n",
956
+ " {'business_status': 'OPERATIONAL',\n",
957
+ " 'geometry': {'location': {'lat': 13.7468712, 'lng': 100.52869},\n",
958
+ " 'viewport': {'northeast': {'lat': 13.7481022302915,\n",
959
+ " 'lng': 100.5300163302915},\n",
960
+ " 'southwest': {'lat': 13.7454042697085, 'lng': 100.5273183697085}}},\n",
961
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
962
+ " 'icon_background_color': '#909CE1',\n",
963
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
964
+ " 'name': 'Lub d Bangkok Siam',\n",
965
+ " 'opening_hours': {'open_now': False},\n",
966
+ " 'photos': [{'height': 4000,\n",
967
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/110664455171949656649\">Lub d Bangkok Siam</a>'],\n",
968
+ " 'photo_reference': 'AXCi2Q7qVqiYRLZVt_dOCtImxbBVKNRmBCSzQ2v--5_YEibb3-6bO79iKRmn_LlFv1AvQ1K2hl5j24-PQYHJD5KC48NeZ-lFx5yvpYlQ41WJqpHoNc2TFIC-NGH61WnCnofVXvKh4xG1v-1N1dGqXG0ote0-VaxF3VJB5EqX8c4ePn4GdozI',\n",
969
+ " 'width': 6000}],\n",
970
+ " 'place_id': 'ChIJc33lpDKZ4jARil4bO37UbIs',\n",
971
+ " 'plus_code': {'compound_code': 'PGWH+PF Bangkok, Thailand',\n",
972
+ " 'global_code': '7P52PGWH+PF'},\n",
973
+ " 'rating': 4.3,\n",
974
+ " 'reference': 'ChIJc33lpDKZ4jARil4bO37UbIs',\n",
975
+ " 'scope': 'GOOGLE',\n",
976
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
977
+ " 'user_ratings_total': 938,\n",
978
+ " 'vicinity': '925, 9 Rama I Road, Khwaeng Wang Mai, Pathum Wan'},\n",
979
+ " {'business_status': 'OPERATIONAL',\n",
980
+ " 'geometry': {'location': {'lat': 13.7505658, 'lng': 100.5320207},\n",
981
+ " 'viewport': {'northeast': {'lat': 13.75196523029151,\n",
982
+ " 'lng': 100.5333065302915},\n",
983
+ " 'southwest': {'lat': 13.7492672697085, 'lng': 100.5306085697085}}},\n",
984
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
985
+ " 'icon_background_color': '#909CE1',\n",
986
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
987
+ " 'name': 'VIE Hotel Bangkok - MGallery',\n",
988
+ " 'photos': [{'height': 4016,\n",
989
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/112525229722496996483\">VIE Hotel Bangkok - MGallery</a>'],\n",
990
+ " 'photo_reference': 'AXCi2Q7TveQ9nEBfcLD4-zSxR0YKeU9Dds7U8lV-Uq6Dqn_lE-cEGoRo4f8EU_W8AMOqKB3Sd2Q67lWjdRhwXG0EhZ1SCwJlzv6ScLyvCjB_p1fhFL3CZP8BiwFzBO6pwMKp3FDXGjxv4MxuJNuCf6Dhy1q9Evyn8L4jbGIM5drEAcX0Uo5E',\n",
991
+ " 'width': 6016}],\n",
992
+ " 'place_id': 'ChIJQwHqwrWe4jAR8yoMrZmtzaU',\n",
993
+ " 'plus_code': {'compound_code': 'QG2J+6R Bangkok, Thailand',\n",
994
+ " 'global_code': '7P52QG2J+6R'},\n",
995
+ " 'rating': 4.5,\n",
996
+ " 'reference': 'ChIJQwHqwrWe4jAR8yoMrZmtzaU',\n",
997
+ " 'scope': 'GOOGLE',\n",
998
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
999
+ " 'user_ratings_total': 2352,\n",
1000
+ " 'vicinity': '117 39, 40 Phaya Thai Road'},\n",
1001
+ " {'business_status': 'OPERATIONAL',\n",
1002
+ " 'geometry': {'location': {'lat': 13.7400527, 'lng': 100.5399569},\n",
1003
+ " 'viewport': {'northeast': {'lat': 13.74149933029151,\n",
1004
+ " 'lng': 100.5412330302915},\n",
1005
+ " 'southwest': {'lat': 13.7388013697085, 'lng': 100.5385350697085}}},\n",
1006
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
1007
+ " 'icon_background_color': '#909CE1',\n",
1008
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
1009
+ " 'name': 'The St. Regis Bangkok',\n",
1010
+ " 'photos': [{'height': 320,\n",
1011
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/110177766871190441187\">The St. Regis Bangkok</a>'],\n",
1012
+ " 'photo_reference': 'AXCi2Q5MpeB0BkgSi1uUIdWT8oWziRVQEpZPeqwJw3RnzXL5wTAGgaAHsu8pfR1o1S9FvfSopFMe6HpmGOi7YCkazz5svGa4JhciyaT2T6eojpXkrKBYD_z1RLgn8bp7-TH4ewCyf8oWioRrKLfoPh3iNQGWi7QG3GrmLoCP_5cIIyfDCLaE',\n",
1013
+ " 'width': 480}],\n",
1014
+ " 'place_id': 'ChIJZ-0rstCe4jARS_6948lrmZU',\n",
1015
+ " 'plus_code': {'compound_code': 'PGRQ+2X Bangkok, Thailand',\n",
1016
+ " 'global_code': '7P52PGRQ+2X'},\n",
1017
+ " 'price_level': 3,\n",
1018
+ " 'rating': 4.6,\n",
1019
+ " 'reference': 'ChIJZ-0rstCe4jARS_6948lrmZU',\n",
1020
+ " 'scope': 'GOOGLE',\n",
1021
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
1022
+ " 'user_ratings_total': 3163,\n",
1023
+ " 'vicinity': '159 Thanon Ratchadamri, Khwaeng Lumphini, Pathum Wan'},\n",
1024
+ " {'business_status': 'OPERATIONAL',\n",
1025
+ " 'geometry': {'location': {'lat': 13.7540569, 'lng': 100.5287023},\n",
1026
+ " 'viewport': {'northeast': {'lat': 13.7554363802915,\n",
1027
+ " 'lng': 100.5301208302915},\n",
1028
+ " 'southwest': {'lat': 13.7527384197085, 'lng': 100.5274228697085}}},\n",
1029
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
1030
+ " 'icon_background_color': '#909CE1',\n",
1031
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
1032
+ " 'name': 'Bangkok City Hotel',\n",
1033
+ " 'photos': [{'height': 4032,\n",
1034
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/100808819005846466311\">Aisyah Hassan</a>'],\n",
1035
+ " 'photo_reference': 'AXCi2Q4sZM83sIM9mOC6Idg-_kdWyCGM1YUHs2DaEeVeKDj5lteFPpbTIFAA60Y90LUX3iu75-bhCiCzUNg5-c9jlQiQJ6aSH3KIJasgs0UUh6NZU0wf0ho07k-FUoj-DrnK5kHmfF_H1IU3HKTzJCZJ4hxEMIYXAGeyYdezcGHRwwtb5j-R',\n",
1036
+ " 'width': 3024}],\n",
1037
+ " 'place_id': 'ChIJuyczxTSZ4jAR2rnUC9KTw6o',\n",
1038
+ " 'plus_code': {'compound_code': 'QG3H+JF Bangkok, Thailand',\n",
1039
+ " 'global_code': '7P52QG3H+JF'},\n",
1040
+ " 'rating': 4,\n",
1041
+ " 'reference': 'ChIJuyczxTSZ4jAR2rnUC9KTw6o',\n",
1042
+ " 'scope': 'GOOGLE',\n",
1043
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
1044
+ " 'user_ratings_total': 2112,\n",
1045
+ " 'vicinity': '268 Phetchaburi Road, Khwaeng Thanon Phetchaburi, Khet Ratchathewi'},\n",
1046
+ " {'business_status': 'OPERATIONAL',\n",
1047
+ " 'geometry': {'location': {'lat': 13.7455309, 'lng': 100.5198334},\n",
1048
+ " 'viewport': {'northeast': {'lat': 13.7469272802915,\n",
1049
+ " 'lng': 100.5214649302915},\n",
1050
+ " 'southwest': {'lat': 13.7442293197085, 'lng': 100.5187669697085}}},\n",
1051
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
1052
+ " 'icon_background_color': '#909CE1',\n",
1053
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
1054
+ " 'name': 'The Twin Towers Hotel',\n",
1055
+ " 'opening_hours': {'open_now': True},\n",
1056
+ " 'photos': [{'height': 1335,\n",
1057
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/115779328569151334983\">The Twin Towers Hotel</a>'],\n",
1058
+ " 'photo_reference': 'AXCi2Q5zHHC0HBwk7iR-m5-0F2QtmYVNs16ziY8g9zRKH_ViPHjqvPvE-n5JvuJT-Kjnh3_YoghMyn-SoriXMXxPpNySIw3sP1TjZ5BI8lRC2OVN_b6h3HPUYba9CWzJXn_-320Oho3XGZ-yr54y1t7G4j84SpmWzbwItgY-XmbnlWO36J2m',\n",
1059
+ " 'width': 2000}],\n",
1060
+ " 'place_id': 'ChIJ_zP3fy-Z4jARWYaBArPXGAg',\n",
1061
+ " 'plus_code': {'compound_code': 'PGW9+6W Bangkok, Thailand',\n",
1062
+ " 'global_code': '7P52PGW9+6W'},\n",
1063
+ " 'rating': 4,\n",
1064
+ " 'reference': 'ChIJ_zP3fy-Z4jARWYaBArPXGAg',\n",
1065
+ " 'scope': 'GOOGLE',\n",
1066
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
1067
+ " 'user_ratings_total': 3326,\n",
1068
+ " 'vicinity': '88 ถ.พระราม 6 ตัดใหม่, Khwaeng Rong Muang, Pathum Wan'},\n",
1069
+ " {'business_status': 'OPERATIONAL',\n",
1070
+ " 'geometry': {'location': {'lat': 13.7408604, 'lng': 100.5399556},\n",
1071
+ " 'viewport': {'northeast': {'lat': 13.74230515, 'lng': 100.5413903802915},\n",
1072
+ " 'southwest': {'lat': 13.73950815, 'lng': 100.5386924197085}}},\n",
1073
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
1074
+ " 'icon_background_color': '#909CE1',\n",
1075
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
1076
+ " 'name': 'Anantara Siam Bangkok Hotel',\n",
1077
+ " 'opening_hours': {'open_now': True},\n",
1078
+ " 'photos': [{'height': 1037,\n",
1079
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/106256908812849161304\">Anantara Siam Bangkok Hotel</a>'],\n",
1080
+ " 'photo_reference': 'AXCi2Q6Rc9MGEhM1NGsPvYYoZ7dAi-hedtt97CrRjslZnsfwqbiEE0UkewPBEkVeY7l7QR4-WRlViax1KeVavFPnY7fa4TW6j0ccEY4fHqxifBSHlhDyA-rKK7uDoxsiUqSOfDJfMtxdUSN6jSRmArsILOdOxX6zz_50G5PAjuJA_nFbYocP',\n",
1081
+ " 'width': 1920}],\n",
1082
+ " 'place_id': 'ChIJVwz7GcWe4jARatGDB6rxqcE',\n",
1083
+ " 'plus_code': {'compound_code': 'PGRQ+8X Bangkok, Thailand',\n",
1084
+ " 'global_code': '7P52PGRQ+8X'},\n",
1085
+ " 'rating': 4.6,\n",
1086
+ " 'reference': 'ChIJVwz7GcWe4jARatGDB6rxqcE',\n",
1087
+ " 'scope': 'GOOGLE',\n",
1088
+ " 'types': ['lodging',\n",
1089
+ " 'spa',\n",
1090
+ " 'restaurant',\n",
1091
+ " 'food',\n",
1092
+ " 'point_of_interest',\n",
1093
+ " 'establishment'],\n",
1094
+ " 'user_ratings_total': 5380,\n",
1095
+ " 'vicinity': '155 Rajadamri Road, Khwaeng Lumphini, Pathum Wan'},\n",
1096
+ " {'business_status': 'OPERATIONAL',\n",
1097
+ " 'geometry': {'location': {'lat': 13.7468291, 'lng': 100.5313447},\n",
1098
+ " 'viewport': {'northeast': {'lat': 13.7480164802915,\n",
1099
+ " 'lng': 100.5327981302915},\n",
1100
+ " 'southwest': {'lat': 13.7453185197085, 'lng': 100.5301001697085}}},\n",
1101
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/shopping-71.png',\n",
1102
+ " 'icon_background_color': '#4B96F3',\n",
1103
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/shopping_pinlet',\n",
1104
+ " 'name': 'Siam Discovery',\n",
1105
+ " 'opening_hours': {'open_now': False},\n",
1106
+ " 'photos': [{'height': 2340,\n",
1107
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/104261864986023217768\">S. Ibrahim Nst.</a>'],\n",
1108
+ " 'photo_reference': 'AXCi2Q5Nr0zE2yKY2Pkr89GsijyiE6eQyJ-A5-5AD7JGZhVrzp0_8QjBXaQjQFPCpnEZPL_9EK_fwCiIG6IBmlOjWAQqKcfL81Czkc3b1BDhi9rV-x7_SIuThzhLYsC6utnrTtIqJ6aepwquDJ05BtMjuhe8th8h2GJE8RKPGjjF0LrMtR-I',\n",
1109
+ " 'width': 4160}],\n",
1110
+ " 'place_id': 'ChIJgUSJZM2e4jAREnHS1rSuWRk',\n",
1111
+ " 'plus_code': {'compound_code': 'PGWJ+PG Bangkok, Thailand',\n",
1112
+ " 'global_code': '7P52PGWJ+PG'},\n",
1113
+ " 'rating': 4.4,\n",
1114
+ " 'reference': 'ChIJgUSJZM2e4jAREnHS1rSuWRk',\n",
1115
+ " 'scope': 'GOOGLE',\n",
1116
+ " 'types': ['shopping_mall', 'point_of_interest', 'establishment'],\n",
1117
+ " 'user_ratings_total': 18880,\n",
1118
+ " 'vicinity': '194 Phaya Thai Road, Khwaeng Pathum Wan, Pathum Wan'},\n",
1119
+ " {'business_status': 'OPERATIONAL',\n",
1120
+ " 'geometry': {'location': {'lat': 13.7481275, 'lng': 100.5414289},\n",
1121
+ " 'viewport': {'northeast': {'lat': 13.7494722302915,\n",
1122
+ " 'lng': 100.5427770802915},\n",
1123
+ " 'southwest': {'lat': 13.7467742697085, 'lng': 100.5400791197085}}},\n",
1124
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/lodging-71.png',\n",
1125
+ " 'icon_background_color': '#909CE1',\n",
1126
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/hotel_pinlet',\n",
1127
+ " 'name': 'Aphrodite Inn Bangkok',\n",
1128
+ " 'opening_hours': {'open_now': True},\n",
1129
+ " 'photos': [{'height': 1280,\n",
1130
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/104889790730167599680\">Aphrodite Inn Bangkok</a>'],\n",
1131
+ " 'photo_reference': 'AXCi2Q6EEQ1eZIsi5DslFbjDTEOZApqtYIjZv48JZwNnHCbKRK8cPFGbQod8Iavt8Vb6jt7UCAgUyjLOID96NsRtVMN77VFFmvmL5gR7FxV2Sq7jZfRQacYxeKKDh1gLikbVZ76Qe0r5rbxHP734MmhfpULIWTCXc8Z68JUz1yTBUCoy57wL',\n",
1132
+ " 'width': 1280}],\n",
1133
+ " 'place_id': 'ChIJJ-xLecWe4jARimHRYcEPNS8',\n",
1134
+ " 'plus_code': {'compound_code': 'PGXR+7H Bangkok, Thailand',\n",
1135
+ " 'global_code': '7P52PGXR+7H'},\n",
1136
+ " 'rating': 4.3,\n",
1137
+ " 'reference': 'ChIJJ-xLecWe4jARimHRYcEPNS8',\n",
1138
+ " 'scope': 'GOOGLE',\n",
1139
+ " 'types': ['lodging', 'point_of_interest', 'establishment'],\n",
1140
+ " 'user_ratings_total': 204,\n",
1141
+ " 'vicinity': '61-65 Thanon Ratchadamri, ลุมพินี, Pathum Wan'},\n",
1142
+ " {'geometry': {'location': {'lat': 13.746183, 'lng': 100.5307787},\n",
1143
+ " 'viewport': {'northeast': {'lat': 13.75307941101843,\n",
1144
+ " 'lng': 100.5529221455833},\n",
1145
+ " 'southwest': {'lat': 13.72275417223182, 'lng': 100.5156772173436}}},\n",
1146
+ " 'icon': 'https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/geocode-71.png',\n",
1147
+ " 'icon_background_color': '#7B9EB0',\n",
1148
+ " 'icon_mask_base_uri': 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/generic_pinlet',\n",
1149
+ " 'name': 'Pathum Wan',\n",
1150
+ " 'photos': [{'height': 1800,\n",
1151
+ " 'html_attributions': ['<a href=\"https://maps.google.com/maps/contrib/118254622117013496228\">Nakorn Chong</a>'],\n",
1152
+ " 'photo_reference': 'AXCi2Q6nWG-gVdJIY_3aZwHHeEunCwUQasXaWepe4x_Iy8OvLh53nKVv_RCoDR6QsnDvAqI94qcMrrcFS8ysjH_LktZ54BVkISzB7-qPUkQeW_OWsLDMFvbm59cAV8nKDhSRIhuP0e9X1cClvOdXpAowEPNUMnwVvnrao82p637ynK2OCmFS',\n",
1153
+ " 'width': 4000}],\n",
1154
+ " 'place_id': 'ChIJ9dY-MdSe4jAR8E3iXbIAAQM',\n",
1155
+ " 'reference': 'ChIJ9dY-MdSe4jAR8E3iXbIAAQM',\n",
1156
+ " 'scope': 'GOOGLE',\n",
1157
+ " 'types': ['sublocality_level_1', 'sublocality', 'political'],\n",
1158
+ " 'vicinity': 'Pathum Wan'}]"
1159
+ ]
1160
+ },
1161
+ "execution_count": 8,
1162
+ "metadata": {},
1163
+ "output_type": "execute_result"
1164
+ }
1165
+ ],
1166
+ "source": [
1167
+ "def nearby_dense_community(location:str, radius:int=2000):\n",
1168
+ " # Retrieve the API key from environment variables\n",
1169
+ " api_key = os.getenv('GPLACES_API_KEY')\n",
1170
+ "\n",
1171
+ " if not api_key:\n",
1172
+ " raise ValueError(\"API key not found. Please set the GOOGLE_MAPS_API_KEY environment variable.\")\n",
1173
+ "\n",
1174
+ " # Define the endpoint URL\n",
1175
+ " url = \"https://maps.googleapis.com/maps/api/place/nearbysearch/json\"\n",
1176
+ "\n",
1177
+ " # Set up the parameters for the request\n",
1178
+ " params = {\n",
1179
+ " \"includedTypes\": [\"hotel\", \"mall\", \"school\", \"apartment\"],\n",
1180
+ " 'location': location,\n",
1181
+ " 'radius': radius,\n",
1182
+ " 'key': api_key,\n",
1183
+ " \"rankPreference\": \"DISTANCE\"\n",
1184
+ " }\n",
1185
+ "\n",
1186
+ " # Send the GET request to the Google Maps API\n",
1187
+ " response = requests.get(url, params=params)\n",
1188
+ "\n",
1189
+ " # Check if the request was successful\n",
1190
+ " if response.status_code != 200:\n",
1191
+ " raise Exception(f\"Error with request: {response.status_code}, {response.text}\")\n",
1192
+ "\n",
1193
+ " # Parse the JSON response\n",
1194
+ " data = response.json()\n",
1195
+ " results = data['results']\n",
1196
+ "\n",
1197
+ " # Return the response data\n",
1198
+ " return results\n",
1199
+ "\n",
1200
+ "\n",
1201
+ "location = \"13.744677,100.5295593\" # Latitude and Longitude\n",
1202
+ "search_results = nearby_dense_community(location)\n",
1203
+ "search_results"
1204
+ ]
1205
+ }
1206
+ ],
1207
+ "metadata": {
1208
+ "kernelspec": {
1209
+ "display_name": "Python 3",
1210
+ "language": "python",
1211
+ "name": "python3"
1212
+ },
1213
+ "language_info": {
1214
+ "codemirror_mode": {
1215
+ "name": "ipython",
1216
+ "version": 3
1217
+ },
1218
+ "file_extension": ".py",
1219
+ "mimetype": "text/x-python",
1220
+ "name": "python",
1221
+ "nbconvert_exporter": "python",
1222
+ "pygments_lexer": "ipython3",
1223
+ "version": "3.11.9"
1224
+ }
1225
+ },
1226
+ "nbformat": 4,
1227
+ "nbformat_minor": 2
1228
+ }
gplace.py ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_old(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']
96
+
97
+
98
+ def nearby_search(keyword:str, location:str, radius=2000, place_type=None):
99
+ # Retrieve the API key from environment variables
100
+ api_key = os.getenv('GPLACES_API_KEY')
101
+
102
+ if not api_key:
103
+ raise ValueError("API key not found. Please set the GOOGLE_MAPS_API_KEY environment variable.")
104
+
105
+ # Define the endpoint URL
106
+ url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"
107
+
108
+ # Set up the parameters for the request
109
+ params = {
110
+ 'keyword': keyword,
111
+ 'location': location,
112
+ 'radius': radius,
113
+ 'type': place_type,
114
+ 'key': api_key,
115
+ "rankPreference": "DISTANCE"
116
+ }
117
+
118
+ # Send the GET request to the Google Maps API
119
+ response = requests.get(url, params=params)
120
+
121
+ # Check if the request was successful
122
+ if response.status_code != 200:
123
+ raise Exception(f"Error with request: {response.status_code}, {response.text}")
124
+
125
+ # Parse the JSON response
126
+ data = response.json()
127
+ results = data['results']
128
+
129
+ # search into next page
130
+ while data.get('next_page_token', False):
131
+ params = {'next_page_token': data['next_page_token']}
132
+ response = requests.get(url, params=params)
133
+
134
+ if response.status_code != 200:
135
+ raise Exception(f"Error with request: {response.status_code}, {response.text}")
136
+
137
+ data = response.json()
138
+
139
+ results.append(data['results'])
140
+
141
+
142
+ # Return the response data
143
+ return results
144
+
145
+
146
+ def nearby_dense_community(location:str, radius:int=2000):
147
+ # Retrieve the API key from environment variables
148
+ api_key = os.getenv('GPLACES_API_KEY')
149
+
150
+ if not api_key:
151
+ raise ValueError("API key not found. Please set the GOOGLE_MAPS_API_KEY environment variable.")
152
+
153
+ # Define the endpoint URL
154
+ url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"
155
+
156
+ # Set up the parameters for the request
157
+ params = {
158
+ "includedTypes": ["hotel", "mall", "school", "apartment"],
159
+ 'location': location,
160
+ 'radius': radius,
161
+ 'key': api_key,
162
+ "rankPreference": "DISTANCE"
163
+ }
164
+
165
+ # Send the GET request to the Google Maps API
166
+ response = requests.get(url, params=params)
167
+
168
+ # Check if the request was successful
169
+ if response.status_code != 200:
170
+ raise Exception(f"Error with request: {response.status_code}, {response.text}")
171
+
172
+ # Parse the JSON response
173
+ data = response.json()
174
+ results = data['results']
175
+
176
+ # Return the response data
177
+ return results
prompt.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ agent_meta = [
2
+ {
3
+ "name": "analyst",
4
+ "prompt": """
5
+ You are the Analyst. Extract the location and keyword (e.g., 'shop', 'coffee shop') from the user request and instruct the Data Collector to gather relevant data. Ensure all communication is in English.
6
+ If user continue to ask anything such as "if i open coffee shop here what price should i sell", or "can we sell in price 130 bath here", it your role to answer the customer question based on the data from reporter, please include an reference of your answer and show the reference data, if the data are reported don't search anything don't use a tools just answer from data that reporter provide, and prefix your answer with '%SIjfE923hf' when responding to the user's question.
7
+ """
8
+ },
9
+ {
10
+ "name": "data_collector",
11
+ "prompt": """
12
+ You are the Data Collector. Use the tools to gather data on the location and keyword provided by the Analyst.
13
+ You must provide data on the number of competitors, nearby competitors, the products they sell and their prices, population, community type, household expenditures, and population data.
14
+ Additionally, Always use Google search tools to find information on 'the pricing of [each competitor] in [distinct]', and the human capacity IF the keyword are kind of hotel, search "number of rooms [each competitor] in [distinct]". IF the keyword are kind of school, search "number of student in [each competitor] in [distinct]".
15
+ Use the population data tool to search for population, community type, and household expenditures related to the province or district of the location.
16
+ Then, use nearby_search to get data about nearby competitors. If some data is not provided, make it up.
17
+ If you cannot find some data, assume it yourself (mock it up) but dont let the Reporter know.
18
+ After that, send the data to the Reporter.
19
+ Ensure all communication is in English.
20
+ Maintain accuracy with the data you gather, except for the data you assume.
21
+ """
22
+ },
23
+ {
24
+ "name": "reporter",
25
+ "prompt": """
26
+ You are the Reporter. Organize all the data to generate insights in 2 parts:
27
+ 1. Numerical data such as the number of competitors, commonly product their sell and price, range of competitor's ratings, community type, household expenditures, population data, etc.
28
+ 2. Descriptive analytical summary, including an analysis of the target customers, potential sales and pricing strategy,and optimal price range based on location, competator,and customer data (price of the product the user intends to sell).
29
+ Do not make list of each shop.
30
+ Provide a final report based on the available information. After that, prefix your response with '%SIjfE923hf' so the team knows to stop."""
31
+ }
32
+ ]
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ langchain
3
+ langchain-core
4
+ langchain-community
5
+ langchain-openai
6
+ langchain-chroma
7
+ langchain-text-splitters
8
+ langgraph
9
+
10
+ langchain_google_community
11
+ googlemaps
12
+ beautifulsoup4
13
+ Flask
test.ipynb ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 14,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "data": {
10
+ "text/plain": [
11
+ "97"
12
+ ]
13
+ },
14
+ "execution_count": 14,
15
+ "metadata": {},
16
+ "output_type": "execute_result"
17
+ }
18
+ ],
19
+ "source": [
20
+ "import utils\n",
21
+ "\n",
22
+ "utils.load_env()\n",
23
+ "\n",
24
+ "from langchain.llms import OpenAI\n",
25
+ "\n",
26
+ "# Create an instance of the OpenAI class\n",
27
+ "openai = OpenAI(model_name=\"text-davinci-003\")\n",
28
+ "\n",
29
+ "# Get the maximum context size for the model\n",
30
+ "max_context_size = openai.modelname_to_contextsize(openai.model_name)\n",
31
+ "\n",
32
+ "# Set the max_tokens attribute to a value within the model's maximum context length\n",
33
+ "openai.max_tokens = max_context_size - 1 # or any value less than max_context_size\n",
34
+ "\n",
35
+ "# Alternatively, you can use the max_tokens_for_prompt method\n",
36
+ "prompt = \"Tell me a joke.\"*800\n",
37
+ "openai.max_tokens = openai.max_tokens_for_prompt(prompt)\n",
38
+ "openai.max_tokens"
39
+ ]
40
+ }
41
+ ],
42
+ "metadata": {
43
+ "kernelspec": {
44
+ "display_name": "Python 3",
45
+ "language": "python",
46
+ "name": "python3"
47
+ },
48
+ "language_info": {
49
+ "codemirror_mode": {
50
+ "name": "ipython",
51
+ "version": 3
52
+ },
53
+ "file_extension": ".py",
54
+ "mimetype": "text/x-python",
55
+ "name": "python",
56
+ "nbconvert_exporter": "python",
57
+ "pygments_lexer": "ipython3",
58
+ "version": "3.11.9"
59
+ }
60
+ },
61
+ "nbformat": 4,
62
+ "nbformat_minor": 2
63
+ }
testsets/QA_smaple.txt ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ quesion:
2
+ อยากจะเปิดร้านหนังสือแถวๆคู้บอนช่วยวิเคราะห์หน่อย
3
+ error:
4
+ Error code: 500 - {'error': {'message': 'The model produced invalid content. Consider modifying your prompt if you are seeing this error persistently.', 'type': 'model_error', 'param': None, 'code': None}}
5
+
6
+
7
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8
+ quesion:
9
+ วิเคราะห์คู่แข่งของร้านเบเกอรี่ใกล้ตลาดจตุจักร
10
+ answer:
11
+ ### Competitive Analysis Report for Bakeries Near Chatuchak Market
12
+
13
+ #### 1. Numerical Data
14
+
15
+ - **Number of Competitors**: 5 bakeries identified within a 1 km radius of Chatuchak Market.
16
+ - **Competitor Ratings**:
17
+ - Morn Loh Hiang Bakery: 4.6
18
+ - Baked With Hearts: 4.6
19
+ - Bakery by AU: 5
20
+ - Tasty Bakery: 4.6
21
+ - Twentyseven Bakery: 5
22
+ - **Pricing**:
23
+ - Baked With Hearts: Sale Price THB 400.00 (Original Price THB 420.00)
24
+ - Pricing information for other bakeries was not found.
25
+ - **Community Data**:
26
+ - Klong Toey: 39 communities
27
+ - Klong San: 34 communities
28
+ - Yannawa: 17 communities
29
+ - Suan Luang: 45 communities
30
+
31
+ #### 2. Descriptive Analytical Summary
32
+
33
+ **Target Customers**:
34
+ The target customers for bakeries in the Chatuchak area are likely to be local residents, visitors to the Chatuchak Market, and tourists. Given the high ratings of the competitors, it can be inferred that customers are looking for quality baked goods, possibly with a focus on artisanal or specialty items.
35
+
36
+ **Potential Sales and Pricing Strategy**:
37
+ - **Sales Potential**: With a diverse community and a high foot traffic area like Chatuchak Market, there is significant potential for sales. The presence of multiple bakeries indicates a healthy demand for baked goods.
38
+ - **Pricing Strategy**: The pricing for baked goods should be competitive yet reflective of quality. Given that Baked With Hearts has a sale price of THB 400.00, a similar pricing strategy could be adopted, with promotional offers to attract customers.
39
+
40
+ **Optimal Price Range**:
41
+ Based on the competitor's pricing and the community's economic status, an optimal price range for baked goods could be between THB 350.00 to THB 450.00. This range allows for competitive pricing while ensuring a profit margin.
42
+
43
+ ### Conclusion
44
+ The bakery market near Chatuchak Market is competitive, with several high-rated establishments. To succeed, a new bakery should focus on quality, customer experience, and strategic pricing. Engaging with the community and leveraging the high foot traffic in the area will be crucial for attracting customers.
45
+
46
+
47
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
48
+ quesion:
49
+ วิเคราะห์การเปิดร้านอาหารใกล้สยามพารากอน
50
+ answer:
51
+ ### Final Report on Opening a Restaurant Near Siam Paragon
52
+
53
+ #### 1. Numerical Data
54
+ - **Competitors**: There are approximately 21 restaurants within a 1 km radius of Siam Paragon.
55
+ - **Competitor Ratings**:
56
+ - Highest Rating: 4.9 (Shree Bhavan Pure South Indian Vegetarian Restaurant)
57
+ - Lowest Rating: 4.2 (Ñam Ñam Pasta and Tapas)
58
+ - **Population**: Bangkok has a population of around 10.5 million, with a significant urban metropolitan demographic.
59
+ - **Household Expenditures**: Average monthly household expenditure is between 30,000 - 40,000 THB.
60
+ - **Restaurant Pricing**:
61
+ - **Street Food**: 60-100 THB per meal.
62
+ - **Budget Restaurants**: 50-300 THB per meal.
63
+ - **Mid-Range Restaurants**: 150-1,200 THB per meal.
64
+ - **High-End Restaurants**: 1,000-2,000 THB or more.
65
+
66
+ #### 2. Descriptive Analytical Summary
67
+ **Target Customers**:
68
+ The target customers around Siam Paragon include both locals and tourists, with a focus on middle to upper-class individuals who frequent shopping malls and enjoy dining out. The area attracts a diverse clientele, including families, young professionals, and expatriates.
69
+
70
+ **Potential Sales and Pricing Strategy**:
71
+ Given the competitive landscape, a restaurant should consider positioning itself within the mid-range to high-end market segment. The pricing strategy could be as follows:
72
+ - **Lunch Menu**: 300-600 THB
73
+ - **Dinner Menu**: 600-1,200 THB
74
+ - **Specialty Items**: Higher pricing for unique or gourmet dishes.
75
+
76
+ **Optimal Price Range**:
77
+ Based on competitor analysis and customer spending habits, an optimal price range for the restaurant could be set between 300-1,200 THB per meal. This range aligns with the pricing of existing competitors while also appealing to the target demographic.
78
+
79
+ In conclusion, opening a restaurant near Siam Paragon presents a promising opportunity, given the high foot traffic, diverse customer base, and potential for strong sales. A well-thought-out menu and pricing strategy, combined with a unique dining experience, could lead to success in this competitive market.
80
+
81
+
82
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
83
+ quesion:
84
+ วิเคราะห์ธุรกิจโรงแรมแถวซอยมิตรภาพ 8
85
+ error:
86
+ Error code: 500 - {'error': {'message': 'The model produced invalid content. Consider modifying your prompt if you are seeing this error persistently.', 'type': 'model_error', 'param': None, 'code': None}}
87
+
88
+
89
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
90
+ quesion:
91
+ วิเคราะห์การเปิดร้านกาแฟใกล้มาบุญครอง
92
+ error:
93
+ Error code: 500 - {'error': {'message': 'The model produced invalid content. Consider modifying your prompt if you are seeing this error persistently.', 'type': 'model_error', 'param': None, 'code': None}}
94
+
95
+
96
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
97
+ quesion:
98
+ Analyze competitors of a bakery near Chatuchak Market
99
+ error:
100
+ Error code: 500 - {'error': {'message': 'The model produced invalid content. Consider modifying your prompt if you are seeing this error persistently.', 'type': 'model_error', 'param': None, 'code': None}}
101
+
102
+
103
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
104
+ quesion:
105
+ ร้านกาแฟใกล้เซ็นทรัลเวิลด์
106
+ answer:
107
+
108
+
109
+
110
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
111
+ quesion:
112
+ Search for grocery stores near Victory Monument and analyze the population
113
+ answer:
114
+ ### Final Report on Grocery Stores and Population Analysis Near Victory Monument
115
+
116
+ #### 1. Numerical Data
117
+
118
+ - **Number of Grocery Stores**: 21
119
+ - **Competitors**:
120
+ - **Siddhartha Grocery Store**: Rating 4.5
121
+ - **Tops Daily Soi Talad Sri Wanit**: Rating 0
122
+ - **Lotus’**: Rating 2.6
123
+ - **Get it Supermarket**: Rating 0
124
+ - **Tops Century**: Rating 3.6
125
+ - **Population**: Approximately 11 million in Bangkok.
126
+ - **Community Type**: Urban, with a mix of residential, commercial, and entertainment areas.
127
+ - **Average Household Expenditure**: Approximately 45,000 THB per month.
128
+ - **Food and Grocery Expenditure**: About 30% of total household spending.
129
+
130
+ #### 2. Descriptive Analytical Summary
131
+
132
+ The area around Victory Monument is characterized by a high density of grocery stores, with 21 competitors in close proximity. The ratings of these stores vary significantly, indicating a mix of customer satisfaction levels. The presence of well-rated stores like Siddhartha Grocery Store suggests a competitive market where quality and service are valued.
133
+
134
+ The population surrounding Victory Monument is part of a larger urban community in Bangkok, which is known for its vibrant commercial activities. With an average household expenditure of 45,000 THB per month, and a significant portion allocated to food and groceries, there is a strong potential customer base for grocery-related businesses.
135
+
136
+ ### Target Customers
137
+ The target customers in this area are likely to be urban dwellers, including families and young professionals, who prioritize convenience and quality in their grocery shopping. The diverse demographic suggests a demand for a variety of products, including fresh produce, ready-to-eat meals, and international food items.
138
+
139
+ ### Potential Sales and Pricing Strategy
140
+ Given the competitive landscape, a pricing strategy that balances affordability with quality will be essential. The optimal price range for grocery items should be aligned with the average market prices, taking into account the pricing strategies of competitors. Offering promotions or loyalty programs could also attract more customers.
141
+
142
+ In conclusion, the Victory Monument area presents a promising opportunity for grocery businesses, with a robust customer base and a competitive environment that encourages quality and service.
143
+
144
+
145
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
146
+ quesion:
147
+ วิเคราะห์ร้านอาหารแถวลุมพินี เซ็นเตอร์ ลาดพร้าว
148
+ answer:
149
+ ### Final Report on Restaurants Near Lumpini Center, Lat Phrao
150
+
151
+ #### 1. Numerical Data
152
+ - **Number of Restaurants Found:** 21
153
+ - **Notable Restaurants and Ratings:**
154
+ - Thai Restaurant: 4.5
155
+ - Thai Flavours: 5
156
+ - ร้านอาหารไทย: 4.8
157
+ - Khun Young's Kitchen: 4.8
158
+ - Kham Thai - Myanmar Restaurant: 5
159
+ - **Population of Bang Kapi District:** Approximately 1,200,000
160
+ - **Average Monthly Household Expenditure:** 34,000 THB
161
+ - **Average Monthly Food Expenditure:** 12,000 THB
162
+ - **Average Monthly Transportation Expenditure:** 10,000 THB
163
+
164
+ #### 2. Descriptive Analytical Summary
165
+ The area around Lumpini Center, Lat Phrao, is characterized by a vibrant dining scene, with a variety of Thai restaurants that have received high ratings from customers. The presence of 21 restaurants within a 1 km radius indicates a competitive market, with options ranging from traditional Thai cuisine to unique dining experiences.
166
+
167
+ **Target Customers:**
168
+ The target customers in this area are likely to be local residents, office workers, and visitors to the nearby hotels and health facilities. Given the urban community type and the average household expenditure, customers are expected to have a moderate to high disposable income, making them willing to spend on dining out.
169
+
170
+ **Potential Sales and Pricing Strategy:**
171
+ Considering the average monthly food expenditure of 12,000 THB, restaurants can adopt a pricing strategy that offers value for money while maintaining quality. The optimal price range for meals could be set between 150 to 500 THB, catering to both budget-conscious diners and those looking for a premium dining experience.
172
+
173
+ **Optimal Price Range:**
174
+ - **Budget Meals:** 150 - 300 THB
175
+ - **Mid-Range Meals:** 300 - 500 THB
176
+ - **Premium Dining:** 500 THB and above
177
+
178
+ In conclusion, the restaurant market near Lumpini Center, Lat Phrao, presents a promising opportunity for new entrants, especially those that can differentiate themselves through unique offerings or exceptional service. The combination of a large population, high household expenditures, and a competitive dining landscape suggests a favorable environment for restaurant businesses.
179
+
180
+
181
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
182
+ quesion:
183
+ Analyze the feasibility of opening a restaurant near Siam Paragon
184
+ answer:
185
+ ### Final Report on the Feasibility of Opening a Restaurant Near Siam Paragon
186
+
187
+ #### 1. Numerical Data
188
+ - **Location**: Siam Paragon, 991/1, Pathumwan, Bangkok, Thailand.
189
+ - **Nearby Competitors**: Approximately 21 restaurants within a 1 km radius.
190
+ - **Competitor Ratings**:
191
+ - Highest: 4.9 (Shree Bhavan)
192
+ - Lowest: 4.2 (Ñam Ñam Pasta and Tapas)
193
+ - **Commonly Offered Products**: Varied cuisines including South Indian, Thai, Italian, and casual dining options.
194
+ - **Price Range**:
195
+ - Casual dining: 300-800 THB per meal.
196
+ - Mid-range dining: 800-1500 THB per meal.
197
+ - High-end dining: 1500 THB and above per meal.
198
+ - **Nearby Dense Communities**: Includes several hotels and attractions such as Pathumwan Princess Hotel, Siam Kempinski Hotel, and Centara Grand & Bangkok Convention Centre.
199
+
200
+ #### 2. Descriptive Analytical Summary
201
+ The area surrounding Siam Paragon is characterized by high foot traffic from both tourists and local residents, making it an attractive location for a new restaurant. The presence of several well-rated competitors indicates a strong market, but also suggests that any new establishment must offer something unique to stand out.
202
+
203
+ **Target Customers**: The target demographic includes affluent locals, tourists, and business travelers, who are likely to seek quality dining experiences.
204
+
205
+ **Potential Sales and Pricing Strategy**: Given the competitive landscape, a pricing strategy should be developed that aligns with the quality of food and service offered. A mid-range pricing strategy (800-1500 THB per meal) could be effective, appealing to both tourists and locals looking for a quality dining experience without venturing into high-end pricing.
206
+
207
+ **Optimal Price Range**: The optimal price range for the restaurant should be set between 800-1500 THB per meal, with a focus on providing exceptional service and a unique dining experience to attract customers away from established competitors.
208
+
209
+ ### Conclusion
210
+ Opening a restaurant near Siam Paragon is feasible, given the high foot traffic and affluent customer base. However, careful consideration must be given to the unique value proposition, pricing strategy, and overall dining experience to successfully compete in this vibrant market.
211
+
212
+
213
+ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
214
+ average execution time: 31.43109838962555sec.
testsets/user_question_testsets.txt ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ coffee shop near mbk center
2
+ วิเคราะห์การเปิดร้านกาแฟใกล้มาบุญครอง
3
+ วิเคราะห์ร้านอาหารแถวลุมพินี เซ็นเตอร์ ลาดพร้าว
4
+ ค้นหาร้านกาแฟใกล้มาบุญครอง พร้อมวิเคราะห์จำนวนประชากร
5
+ Coffee shop near Central World
6
+ Analyze the feasibility of opening a restaurant near Siam Paragon
7
+ Analyze competitors of a bakery near Chatuchak Market
8
+ Search for grocery stores near Victory Monument and analyze the population
9
+ Feasibility analysis for a bookstore near Thonglor
10
+ ร้านกาแฟใกล้เซ็นทรัลเวิลด์
11
+ วิเคราะห์การเปิดร้านอาหารใกล้สยามพารากอน
12
+ วิเคราะห์คู่แข่งของร้านเบเกอรี่ใกล้ตลาดจตุจักร
13
+ ค้นหาร้านของชำใกล้อนุสาวรีย์ชัยฯ พร้อมวิเคราะห์จำนวนประชากร
14
+ วิเคราะห์ความเป็นไปได้ในการเปิดร้านหนังสือใกล้ทองหล่อ
15
+ อยากจะเปิดร้านหนังสือแถวๆคู้บอนช่วยวิเคราะห์หน่อย
16
+ วิเคราะห์การเปิดร้านอาหารแถวนวลจันทร์
17
+ วิเคราะห์การเปิดโรงแรมแถวทองหล่อ
18
+ วิเคราะห์ธุรกิจโรงแรมแถวซอยมิตรภาพ 8
tools.ipynb ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 2,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import gplace\n",
10
+ "\n",
11
+ "location = \"13.744677,100.5295593\" # Latitude and Longitude\n",
12
+ "keyword = \"ร้านกาแฟ\"\n",
13
+ "result = gplace.nearby_search(keyword, location)"
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "code",
18
+ "execution_count": 3,
19
+ "metadata": {},
20
+ "outputs": [],
21
+ "source": [
22
+ "from typing import TypedDict, Optional\n",
23
+ "\n",
24
+ "class NearbyDenseCommunityInput(TypedDict):\n",
25
+ " location_name: str\n",
26
+ " radius: int"
27
+ ]
28
+ },
29
+ {
30
+ "cell_type": "code",
31
+ "execution_count": 4,
32
+ "metadata": {},
33
+ "outputs": [],
34
+ "source": [
35
+ "def find_place_from_text(location:str):\n",
36
+ " \"\"\"Finds a place and related data from the query text\"\"\"\n",
37
+ " \n",
38
+ " result = gplace.find_place_from_text(location)\n",
39
+ " r = result['candidates'][0]\n",
40
+ " return f\"\"\"\n",
41
+ " address: {r['formatted_address']}\\n\n",
42
+ " location: {r['geometry']['location']}\\n\n",
43
+ " name: {r['name']}\\n\n",
44
+ " opening hours: {r['opening_hours']}\\n\n",
45
+ " rating: {r['rating']}\\n\n",
46
+ " \"\"\"\n",
47
+ " \n",
48
+ "def nearby_search(keyword:str, location:str, radius=2000, place_type=None):\n",
49
+ " \"\"\"Searches for many places nearby the location based on a keyword. using keyword like \\\"coffee shop\\\", \\\"restaurants\\\". radius is the range to search from the location\"\"\"\n",
50
+ " location = gplace.find_location(location, radius=radius)\n",
51
+ " result = gplace.nearby_search(keyword, location, radius)\n",
52
+ " \n",
53
+ " strout = \"\"\n",
54
+ " for r in result:\n",
55
+ " # Use .get() to handle missing keys\n",
56
+ " address = r.get('vicinity', 'N/A')\n",
57
+ " location_info = r.get('geometry', {}).get('location', 'N/A')\n",
58
+ " name = r.get('name', 'N/A')\n",
59
+ " opening_hours = r.get('opening_hours', 'N/A')\n",
60
+ " rating = r.get('rating', 'N/A')\n",
61
+ " plus_code = r.get('plus_code', {}).get('global_code', 'N/A')\n",
62
+ " \n",
63
+ " strout += f\"\"\"\n",
64
+ " address: {address}\\n\n",
65
+ " location: {location_info}\\n\n",
66
+ " name: {name}\\n\n",
67
+ " opening hours: {opening_hours}\\n\n",
68
+ " rating: {rating}\\n\n",
69
+ " plus code: {plus_code}\\n\\n\n",
70
+ " \"\"\"\n",
71
+ " return strout\n",
72
+ "\n",
73
+ "def nearby_dense_community(input_dict: NearbyDenseCommunityInput) -> str:\n",
74
+ " \"\"\" getting nearby dense community such as (community mall, hotel, school, etc), by location name, radius(in meters)\n",
75
+ " return list of location community nearby, name, community type.\n",
76
+ " \"\"\"\n",
77
+ " location = input_dict['location_name']\n",
78
+ " radius = input_dict['radius']\n",
79
+ " \n",
80
+ " location_coords = gplace.find_location(location, radius=radius)\n",
81
+ " result = gplace.nearby_dense_community(location_coords, radius)\n",
82
+ " \n",
83
+ " strout = \"\"\n",
84
+ " for r in result:\n",
85
+ " # Use .get() to handle missing keys\n",
86
+ " address = r.get('vicinity', 'N/A')\n",
87
+ " location_types = r.get('types', 'N/A')\n",
88
+ " name = r.get('name', 'N/A')\n",
89
+ " opening_hours = r.get('opening_hours', 'N/A')\n",
90
+ " rating = r.get('rating', 'N/A')\n",
91
+ " plus_code = r.get('plus_code', {}).get('global_code', 'N/A')\n",
92
+ " \n",
93
+ " strout += f\"\"\"\n",
94
+ " name: {name}\\n\n",
95
+ " types: {location_types}\\n\n",
96
+ " \"\"\".strip()\n",
97
+ " return strout\n"
98
+ ]
99
+ },
100
+ {
101
+ "cell_type": "code",
102
+ "execution_count": 5,
103
+ "metadata": {},
104
+ "outputs": [
105
+ {
106
+ "name": "stderr",
107
+ "output_type": "stream",
108
+ "text": [
109
+ "USER_AGENT environment variable not set, consider setting it to identify your requests.\n"
110
+ ]
111
+ }
112
+ ],
113
+ "source": [
114
+ "# gplace_tools.py\n",
115
+ "from langgraph.prebuilt import ToolNode\n",
116
+ "from langchain_core.tools import tool\n",
117
+ "from langchain_core.tools import Tool\n",
118
+ "from langchain_google_community import GoogleSearchAPIWrapper\n",
119
+ "from langchain_community.document_loaders import WebBaseLoader\n",
120
+ "\n",
121
+ "import utils\n",
122
+ "\n",
123
+ "utils.load_env()\n",
124
+ "\n",
125
+ "search = GoogleSearchAPIWrapper()\n",
126
+ "\n",
127
+ "find_place_from_text = tool(find_place_from_text)\n",
128
+ "nearby_search = tool(nearby_search)\n",
129
+ "google_search = Tool(\n",
130
+ " name=\"google_search\",\n",
131
+ " description=\"Search Google for recent results.\",\n",
132
+ " func=search.run,\n",
133
+ ")\n",
134
+ "web_loader = Tool(\n",
135
+ " name=\"google_search\",\n",
136
+ " description=\"Search Google for recent results.\",\n",
137
+ " func=WebBaseLoader,\n",
138
+ ")\n",
139
+ "\n",
140
+ "tools = [find_place_from_text, nearby_search]\n",
141
+ "\n",
142
+ "# Create ToolNodes for each tool\n",
143
+ "tool_node = ToolNode(tools)"
144
+ ]
145
+ },
146
+ {
147
+ "cell_type": "code",
148
+ "execution_count": 6,
149
+ "metadata": {},
150
+ "outputs": [
151
+ {
152
+ "data": {
153
+ "text/plain": [
154
+ "\"name: Bangkok\\n\\n types: ['locality', 'political']name: Metropoint Bangkok Hotel\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: The Grand Fourwings Convention Hotel\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Hua Mak Indoor Stadium\\n\\n types: ['point_of_interest', 'establishment']name: B2 Bangkok Srinagarindra Boutique & Budget Hotel\\n\\n types: ['clothing_store', 'lodging', 'point_of_interest', 'store', 'establishment']name: HappyLand Mansion\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Bangkok Swimming by Kru Jin\\n\\n types: ['point_of_interest', 'establishment']name: Aunchaleena grand Hotel\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Anda Hotel\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Grand Mandarin Residence\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Wallada Place Hotel\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: NIDA Rooms Plubpla Bangkapi 591\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Bangkok Interplace\\n\\n types: ['lodging', 'restaurant', 'food', 'point_of_interest', 'establishment']name: Vejthani Hospital\\n\\n types: ['hospital', 'doctor', 'point_of_interest', 'health', 'establishment']name: โรงแรม ชาลีน่า ปริ้นเซส Chaleena princess\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Royal Pimand\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Baron Residence Hotel\\n\\n types: ['lodging', 'point_of_interest', 'establishment']name: Ridwanun Islam Mosque\\n\\n types: ['mosque', 'place_of_worship', 'point_of_interest', 'establishment']name: Thep Phanom Building\\n\\n types: ['point_of_interest', 'establishment']name: Bang Kapi District\\n\\n types: ['sublocality_level_1', 'sublocality', 'political']\""
155
+ ]
156
+ },
157
+ "execution_count": 6,
158
+ "metadata": {},
159
+ "output_type": "execute_result"
160
+ }
161
+ ],
162
+ "source": [
163
+ "nearby_dense_community({'location_name': 'ลุมพินี เซ็นเตอร์ ลาดพร้าว', 'radius': 8000})"
164
+ ]
165
+ },
166
+ {
167
+ "cell_type": "code",
168
+ "execution_count": 8,
169
+ "metadata": {},
170
+ "outputs": [
171
+ {
172
+ "data": {
173
+ "text/plain": [
174
+ "'Address: 156/2 Dinso Rd, Sao Chingcha, Phra Nakhon, Bangkok 10200 ; Phone: 02-622-1525 ; Open hours: 10 am – 11 pm daily ; Prices: Most dishes are in the price... For those complaining about the price go sit in the street if you want super cheap. It\\'s inside a large shopping mall filled with luxury brands, what do you... If you are looking for quality Mediterranean cuisine in the heart of Bangkok, look no further than Mimosa BKK. ... Don\\'t forget to check for happy hour prices so... PRICE RANGE. $5.00 – $86.00 ; CUISINES. Italian, French, Pizza, Mediterranean, Spanish ; Meals. Lunch, Dinner, Brunch, Drinks. 1790 Followers, 6 Following, 111 Posts - Mimosa | Mediterranean Restaurant Bangkok (@mimosabkk) on Instagram: \"From the sunny shores of the Mediterranean... Mimosa Cake by Fast Buds is a Sativa-dominant hybrid but thanks to the handpicked terpene profile, its strong Sativa high comes hand-in-hand with a nice. ... Bangkok · Discover Our Stores · PAÑPURI FIRST · Our Stores. EN. EN · TH · 简体 · 繁體. Top. MEMORIA MIMOSA. Golden sunshine brightens the sweetness of Mimosa... Jun 10, 2020 ... I studied at Regent\\'s Pattaya throughout high school and moved to Bangkok to pursue a bachelor\\'s degree in Communication Management at... Jan 3, 2022 ... Program in Biotechnology, Faculty of Science, Chulalongkorn University, Bangkok, Thailand. ... Mimosa diplotricha, Nelumbo nucifera, Xyris... Mimosa weed in bangkok High thai ... Sale Price, ฿3000. Mimosa quantity. Add to cart. Compare · Add to wishlist. Follow...'"
175
+ ]
176
+ },
177
+ "execution_count": 8,
178
+ "metadata": {},
179
+ "output_type": "execute_result"
180
+ }
181
+ ],
182
+ "source": [
183
+ "google_search(\"the pricing of Mimosa Bangkok in Bangkok \").replace(\"\\xa0\", \"\")"
184
+ ]
185
+ }
186
+ ],
187
+ "metadata": {
188
+ "kernelspec": {
189
+ "display_name": "Python 3",
190
+ "language": "python",
191
+ "name": "python3"
192
+ },
193
+ "language_info": {
194
+ "codemirror_mode": {
195
+ "name": "ipython",
196
+ "version": 3
197
+ },
198
+ "file_extension": ".py",
199
+ "mimetype": "text/x-python",
200
+ "name": "python",
201
+ "nbconvert_exporter": "python",
202
+ "pygments_lexer": "ipython3",
203
+ "version": "3.11.9"
204
+ }
205
+ },
206
+ "nbformat": 4,
207
+ "nbformat_minor": 2
208
+ }
tools.py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gplace
2
+ from typing import TypedDict, Optional
3
+ from langchain_google_community import GoogleSearchAPIWrapper
4
+ import utils
5
+ ## Document vector store for context
6
+ from langchain_chroma import Chroma
7
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
8
+ from langchain_community.document_loaders import CSVLoader
9
+ from langchain_openai import OpenAIEmbeddings
10
+ import glob
11
+ from langchain_core.tools import tool
12
+
13
+ utils.load_env()
14
+
15
+ search = GoogleSearchAPIWrapper()
16
+
17
+
18
+ class NearbySearchInput(TypedDict):
19
+ keyword: str
20
+ location_name: str
21
+ radius: int
22
+ place_type: Optional[str]
23
+
24
+
25
+ class NearbyDenseCommunityInput(TypedDict):
26
+ location_name: str
27
+ radius: int
28
+
29
+
30
+ # class GoogleSearchInput(TypedDict):
31
+ # keyword: str
32
+
33
+
34
+ # %%
35
+ # @tool
36
+ def find_place_from_text(location:str):
37
+ """Finds a place location and related data from the query text"""
38
+ result = gplace.find_place_from_text(location)
39
+ r = result['candidates'][0]
40
+ # location: {r['geometry']['location']}\n
41
+ return f"""
42
+ # address: {r['formatted_address']}\n
43
+ location_name: {r['name']}\n
44
+ """
45
+ # return f"""
46
+ # address: {r['formatted_address']}\n
47
+ # location: {r['geometry']['location']}\n
48
+ # location_name: {r['name']}\n
49
+ # """
50
+
51
+ # def nearby_search(keyword:str, location:str, radius=2000, place_type=None):
52
+ # """Searches for many places nearby the location based on a keyword. using keyword like \"coffee shop\", \"restaurants\". radius is the range to search from the location"""
53
+ # location = gplace.find_location(location, radius=radius)
54
+ # result = gplace.nearby_search(keyword, location, radius)
55
+
56
+ # strout = ""
57
+ # for r in result:
58
+ # strout = strout + f"""
59
+ # address: {r['vicinity']}\n
60
+ # location: {r['geometry']['location']}\n
61
+ # name: {r['name']}\n
62
+ # opening hours: {r['opening_hours']}\n
63
+ # rating: {r['rating']}\n
64
+ # plus code: {r['plus_code']['global_code']}\n\n
65
+ # """
66
+ # return strout
67
+
68
+
69
+ # @tool
70
+ def nearby_search(input_dict: NearbySearchInput):
71
+ """Searches for many places nearby the location based on a keyword. using keyword like \"coffee shop\", \"restaurants\". radius is the range to search from the location."""
72
+ max_results = 5
73
+ keyword = input_dict['keyword']
74
+ location = input_dict['location_name']
75
+ radius = input_dict.get('radius', 2000)
76
+ place_type = input_dict.get('place_type', None)
77
+
78
+ # Call the internal function to find location
79
+ location_coords = gplace.find_location(location, radius=radius)
80
+ result = gplace.nearby_search(keyword, location_coords, radius)
81
+
82
+ number_results = len(result)
83
+ strout = "number of results more than {}\n".format(number_results) if number_results==60 else "number of results: {}\n".format(number_results)
84
+ for r in result[:max_results]:
85
+ # Use .get() to handle missing keys
86
+ address = r.get('vicinity', 'N/A')
87
+ location_info = r.get('geometry', {}).get('location', 'N/A')
88
+ name = r.get('name', 'N/A')
89
+ opening_hours = r.get('opening_hours', 'N/A')
90
+ rating = r.get('rating', 'N/A')
91
+ plus_code = r.get('plus_code', {}).get('global_code', 'N/A')
92
+
93
+ # strout += f"""
94
+ # address: {address}\n
95
+ # location: {location_info}\n
96
+ # lacation_name: {name}\n
97
+ # opening hours: {opening_hours}\n
98
+ # rating: {rating}\n
99
+ # plus code: {plus_code}\n\n
100
+ # """
101
+
102
+ strout += f"""
103
+ **{name}**\n
104
+ address: {address}\n
105
+ rating: {rating}\n\n
106
+ """
107
+ return strout[:800]
108
+
109
+
110
+ # @tool
111
+ def nearby_dense_community(input_dict: NearbyDenseCommunityInput) -> str:
112
+ """ getting nearby dense community such as (community mall, hotel, school, etc), by location name, radius(in meters)
113
+ return list of location community nearby, name, community type.
114
+ """
115
+ max_results = 5
116
+ location = input_dict['location_name']
117
+ radius = input_dict['radius']
118
+
119
+ location_coords = gplace.find_location(location, radius=radius)
120
+ result = gplace.nearby_dense_community(location_coords, radius)
121
+
122
+ strout = ""
123
+ for r in result[:max_results]:
124
+ # Use .get() to handle missing keys
125
+ address = r.get('vicinity', 'N/A')
126
+ location_types = r.get('types', 'N/A')
127
+ name = r.get('name', 'N/A')
128
+ opening_hours = r.get('opening_hours', 'N/A')
129
+ rating = r.get('rating', 'N/A')
130
+ plus_code = r.get('plus_code', {}).get('global_code', 'N/A')
131
+
132
+ strout += f"""
133
+ name: {name}\n
134
+ types: {location_types}\n
135
+ """
136
+ return strout.strip()[:800]
137
+
138
+
139
+ # @tool
140
+ def google_search(keyword:str):
141
+ """Search Google for recent results. Using keyword as a text query search in google."""
142
+ text = search.run(keyword)
143
+ unicode_chars_to_remove = ["\U000f1676", "\u2764", "\xa0"]
144
+ for char in unicode_chars_to_remove:
145
+ text = text.replace(char, "")
146
+ return text[:800]
147
+
148
+
149
+ ## Document csv
150
+ def get_documents(file_pattern="document/*.csv"):
151
+ file_paths = tuple(glob.glob(file_pattern))
152
+
153
+ all_docs = []
154
+
155
+ for file_path in file_paths:
156
+ loader = CSVLoader(file_path=file_path)
157
+ docs = loader.load()
158
+ all_docs.extend(docs) # Add the documents to the list
159
+
160
+ return all_docs
161
+
162
+
163
+ def get_retriver_from_docs(docs):
164
+ # Split text into chunks separated.
165
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
166
+ splits = text_splitter.split_documents(docs)
167
+
168
+ # Text Vectorization.
169
+ vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
170
+
171
+ # Retrieve and generate using the relevant snippets of the blog.
172
+ retriever = vectorstore.as_retriever()
173
+
174
+ return retriever
175
+
176
+
177
+
178
+
179
+ from langchain.tools.retriever import create_retriever_tool
180
+ from langchain_core.tools import Tool
181
+
182
+
183
+ docs = get_documents()
184
+ retriever = get_retriver_from_docs(docs)
185
+
186
+ population_doc_retriever = create_retriever_tool(
187
+ retriever,
188
+ "search_population_community_household_expenditures_data",
189
+ "Use this tool to retrieve information about population, community and household expenditures. by searching distinct or province"
190
+ )
191
+ # google_search = Tool(
192
+ # name="google_search",
193
+ # description="Search Google for recent results. Using keyword as a text query search in google.",
194
+ # func=google_search,
195
+ # )
196
+ # find_place_from_text = Tool(
197
+ # name="find_place_from_text",
198
+ # description="Finds a place location and related data from the query text",
199
+ # func=find_place_from_text,
200
+ # )
201
+ # nearby_search = Tool(
202
+ # name="nearby_search",
203
+ # description="""Searches for many places nearby the location based on a keyword. using keyword like \"coffee shop\", \"restaurants\". radius is the range to search from the location.""",
204
+ # func=nearby_search,
205
+ # )
206
+ # nearby_dense_community = Tool(
207
+ # name="nearby_dense_community",
208
+ # description="""getting nearby dense community such as (community mall, hotel, school, etc), by location name, radius(in meters)
209
+ # return list of location community nearby, name, community type""",
210
+ # func=nearby_dense_community,
211
+ # )
212
+ google_search = tool(google_search)
213
+ find_place_from_text = tool(find_place_from_text)
214
+ nearby_search = tool(nearby_search)
215
+ nearby_dense_community = tool(nearby_dense_community)
utils.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+ import os
3
+ import json
4
+
5
+
6
+ def load_agent_meta():
7
+ with open('./prompt.json', 'r') as file:
8
+ prompt_data = json.load(file)
9
+ return prompt_data
10
+
11
+
12
+ def load_env():
13
+ # Load environment variables from the .env file
14
+ load_dotenv("./API_keys.env")
15
+ # os.getenv('OPENAI_API_KEY')