Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,41 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
-
import pydeck as pdk
|
| 3 |
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
)
|
| 13 |
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
)
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
)
|
| 25 |
|
| 26 |
-
|
|
|
|
|
|
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
|
|
|
|
|
|
|
|
|
|
| 29 |
with gr.Blocks() as demo:
|
| 30 |
-
gr.Markdown(
|
| 31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
inputs=None,
|
| 36 |
-
outputs=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
)
|
| 38 |
|
| 39 |
demo.launch(
|
| 40 |
-
ssr_mode=False
|
| 41 |
)
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import time
|
| 3 |
+
import random
|
| 4 |
+
|
| 5 |
+
import googlemaps
|
| 6 |
+
import pandas as pd
|
| 7 |
+
import plotly.express as px
|
| 8 |
import gradio as gr
|
|
|
|
| 9 |
|
| 10 |
+
# =====================================================
|
| 11 |
+
# 1. Google Maps API
|
| 12 |
+
# =====================================================
|
| 13 |
+
API_KEY = os.getenv("GOOGLE_MAPS_API_KEY")
|
| 14 |
+
if API_KEY is None:
|
| 15 |
+
raise RuntimeError("GOOGLE_MAPS_API_KEY not set")
|
| 16 |
+
|
| 17 |
+
gmaps = googlemaps.Client(key=API_KEY)
|
| 18 |
+
|
| 19 |
+
# =====================================================
|
| 20 |
+
# 2. Data Fetch
|
| 21 |
+
# =====================================================
|
| 22 |
+
def fetch_places():
|
| 23 |
+
query = "Hawaiian pizza in Seoul"
|
| 24 |
+
rows = []
|
| 25 |
+
|
| 26 |
+
res = gmaps.places(query=query, language="ko")
|
| 27 |
+
|
| 28 |
+
while True:
|
| 29 |
+
for r in res["results"]:
|
| 30 |
+
rows.append({
|
| 31 |
+
"name": r["name"],
|
| 32 |
+
"address": r.get("formatted_address", ""),
|
| 33 |
+
"rating": r.get("rating", 0),
|
| 34 |
+
"lat": r["geometry"]["location"]["lat"],
|
| 35 |
+
"lon": r["geometry"]["location"]["lng"],
|
| 36 |
+
})
|
| 37 |
+
|
| 38 |
+
if "next_page_token" not in res:
|
| 39 |
+
break
|
| 40 |
+
|
| 41 |
+
time.sleep(2)
|
| 42 |
+
res = gmaps.places(
|
| 43 |
+
page_token=res["next_page_token"],
|
| 44 |
+
language="ko",
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
return pd.DataFrame(rows)
|
| 48 |
+
|
| 49 |
+
DATA = fetch_places()
|
| 50 |
+
|
| 51 |
+
# =====================================================
|
| 52 |
+
# 3. Entertainment
|
| 53 |
+
# =====================================================
|
| 54 |
+
QUOTES = [
|
| 55 |
+
"π νμΈμ νμ λ
Όμμ μ΄μ§λ§ λ§μμ΅λλ€",
|
| 56 |
+
"π μ΄ν리μμΈμκ²λ λΉλ°λ‘β¦",
|
| 57 |
+
"π₯ νμμ΄μ νΌμ μ°¬μ± 1ν",
|
| 58 |
+
"π€ λ¨μ§ μ νννμ ",
|
| 59 |
+
"π§ λ―Έκ°μ μμ μ
λλ€",
|
| 60 |
+
]
|
| 61 |
+
|
| 62 |
+
# =====================================================
|
| 63 |
+
# 4. Plotly Map Builder
|
| 64 |
+
# =====================================================
|
| 65 |
+
def build_map(df, zoom=11):
|
| 66 |
+
if df.empty:
|
| 67 |
+
center = dict(lat=37.5665, lon=126.9780)
|
| 68 |
+
else:
|
| 69 |
+
center = dict(lat=df.lat.mean(), lon=df.lon.mean())
|
| 70 |
+
|
| 71 |
+
fig = px.scatter_mapbox(
|
| 72 |
+
df,
|
| 73 |
+
lat="lat",
|
| 74 |
+
lon="lon",
|
| 75 |
+
hover_name="name",
|
| 76 |
+
hover_data={
|
| 77 |
+
"rating": True,
|
| 78 |
+
"address": True,
|
| 79 |
+
"lat": False,
|
| 80 |
+
"lon": False,
|
| 81 |
+
},
|
| 82 |
+
color="rating",
|
| 83 |
+
size="rating",
|
| 84 |
+
size_max=18,
|
| 85 |
+
zoom=zoom,
|
| 86 |
+
center=center,
|
| 87 |
+
height=650,
|
| 88 |
)
|
| 89 |
|
| 90 |
+
# OpenStreetMap β Mapbox ν ν° νμ μμ
|
| 91 |
+
fig.update_layout(
|
| 92 |
+
mapbox_style="open-street-map",
|
| 93 |
+
margin={"r": 0, "t": 0, "l": 0, "b": 0},
|
| 94 |
)
|
| 95 |
|
| 96 |
+
return fig
|
| 97 |
+
|
| 98 |
+
# =====================================================
|
| 99 |
+
# 5. UI Logic
|
| 100 |
+
# =====================================================
|
| 101 |
+
def update(min_rating):
|
| 102 |
+
df = DATA[DATA["rating"] >= min_rating]
|
| 103 |
+
|
| 104 |
+
pct = int(100 * len(df) / len(DATA)) if len(DATA) else 0
|
| 105 |
+
|
| 106 |
+
return (
|
| 107 |
+
build_map(df),
|
| 108 |
+
f"**{len(df)}κ° λ§€μ₯ νμ μ€**",
|
| 109 |
+
f"π Pineapple Power: {pct}%",
|
| 110 |
+
random.choice(QUOTES),
|
| 111 |
)
|
| 112 |
|
| 113 |
+
def random_pick():
|
| 114 |
+
row = DATA.sample(1)
|
| 115 |
+
r = row.iloc[0]
|
| 116 |
|
| 117 |
+
return (
|
| 118 |
+
build_map(row, zoom=15),
|
| 119 |
+
f"""
|
| 120 |
+
### π² μ€λμ νμμ΄μ π
|
| 121 |
+
**{r.name}**
|
| 122 |
+
β {r.rating}
|
| 123 |
+
π {r.address}
|
| 124 |
+
""",
|
| 125 |
+
)
|
| 126 |
|
| 127 |
+
# =====================================================
|
| 128 |
+
# 6. Gradio UI
|
| 129 |
+
# =====================================================
|
| 130 |
with gr.Blocks() as demo:
|
| 131 |
+
gr.Markdown(
|
| 132 |
+
"""
|
| 133 |
+
## π μμΈ νμμ΄μ νΌμ μ§λ
|
| 134 |
+
**Plotly κΈ°λ° Β· Gradio/HF Spaces μμ λ²μ **
|
| 135 |
+
"""
|
| 136 |
+
)
|
| 137 |
|
| 138 |
+
with gr.Row():
|
| 139 |
+
with gr.Column(scale=1):
|
| 140 |
+
rating = gr.Slider(0, 5, 3.5, 0.1, label="μ΅μ νμ ")
|
| 141 |
+
count = gr.Markdown()
|
| 142 |
+
power = gr.Markdown()
|
| 143 |
+
quote = gr.Markdown()
|
| 144 |
+
btn = gr.Button("π μ€λμ νμμ΄μ")
|
| 145 |
+
rec = gr.Markdown()
|
| 146 |
+
|
| 147 |
+
with gr.Column(scale=3):
|
| 148 |
+
plot = gr.Plot()
|
| 149 |
+
|
| 150 |
+
rating.change(
|
| 151 |
+
fn=update,
|
| 152 |
+
inputs=rating,
|
| 153 |
+
outputs=[plot, count, power, quote],
|
| 154 |
+
)
|
| 155 |
+
|
| 156 |
+
btn.click(
|
| 157 |
+
fn=random_pick,
|
| 158 |
inputs=None,
|
| 159 |
+
outputs=[plot, rec],
|
| 160 |
+
)
|
| 161 |
+
|
| 162 |
+
demo.load(
|
| 163 |
+
fn=update,
|
| 164 |
+
inputs=rating,
|
| 165 |
+
outputs=[plot, count, power, quote],
|
| 166 |
)
|
| 167 |
|
| 168 |
demo.launch(
|
| 169 |
+
ssr_mode=False # μ§λ μμ μ± β
|
| 170 |
)
|