taiwan-tender / app.py
tbdavid2019's picture
價格顯示優化2
0266b2a
import gradio as gr
import requests
import datetime
import pandas as pd
def format_price(price):
try:
if isinstance(price, (int, float)):
return "{:,}".format(int(price))
return price
except:
return price
# Function to fetch data from the API
def fetch_tenders(date, category, type_, unit_name, unit_id, job_number, name):
base_url = "https://pcc.mlwmlw.org/api/date/tender/"
try:
# Validate and format the date
if not date:
date = datetime.datetime.now().strftime("%Y-%m-%d") # Default to today's date
else:
datetime.datetime.strptime(date, "%Y-%m-%d") # Ensure correct format
url = f"{base_url}{date}"
response = requests.get(url)
response.raise_for_status()
data = response.json()
# Filter data based on inputs
filtered_data = [
{
"標案名稱": f'<a href="{item.get("url", "#")}" target="_blank">{item.get("name", "N/A")}</a>',
"機關名稱": item.get("unit", "N/A"),
"類別": item.get("category", "N/A"),
"招標方式": item.get("type", "N/A"),
"價格": format_price(item.get("price", "N/A")),
"日期": date,
"連結": item.get("url", "N/A")
}
for item in data
if (
(category == "不限" or item.get("category") == category) and
(type_ == "不限" or item.get("type") == type_) and
(not unit_name or unit_name in item.get("unit", "")) and
(not unit_id or unit_id in item.get("unit_id", "")) and
(not job_number or job_number in item.get("job_number", "")) and
(not name or name in item.get("name", ""))
)
]
return pd.DataFrame(filtered_data) if filtered_data else pd.DataFrame([{"查無資料": ""}])
except ValueError:
return pd.DataFrame([{"Error": "日期格式錯誤,請使用 YYYY-MM-DD 格式"}])
except requests.exceptions.RequestException as e:
return pd.DataFrame([{"Error": f"無法取得資料: {str(e)}"}])
# Gradio Interface
def create_interface():
with gr.Blocks() as demo:
gr.Markdown("## 政府招標查詢工具 DAVID888.com\n通過日期、採購性質、招標方式以及其他關鍵字篩選政府招標公告。")
with gr.Row():
date_input = gr.Text(label="查詢日期 (YYYY-MM-DD)", placeholder="可不填, 預設為今天")
category_dropdown = gr.Dropdown(
choices=["不限", "工程類", "財物類", "勞務類"],
label="採購性質",
value="不限"
)
type_dropdown = gr.Dropdown(
choices=[
"不限", "公開取得報價單或企劃書更正公告", "公開招標公告", "公開招標更正公告",
"限制性招標(經公開評選或公開徵求)公告", "限制性招標(經公開評選或公開徵求)更正公告",
"無法決標更正公告", "N/A"
],
label="招標方式",
value="不限"
)
with gr.Row():
unit_name_input = gr.Text(label="機關名稱", placeholder="輸入機關名稱")
unit_id_input = gr.Text(label="機關代碼", placeholder="輸入機關代碼")
job_number_input = gr.Text(label="標案案號", placeholder="輸入標案案號")
name_input = gr.Text(label="標案名稱", placeholder="輸入標案名稱")
submit_button = gr.Button("查詢")
download_button = gr.Button("導出 CSV")
# Output for displaying results
csv_data = gr.State() # Temporary state to store DataFrame
output = gr.HTML(label="查詢結果")
# Handle fetch and display
def handle_query(date, category, type_, unit_name, unit_id, job_number, name):
df = fetch_tenders(date, category, type_, unit_name, unit_id, job_number, name)
return df.to_html(escape=False, index=False), df
# Handle CSV export
def export_csv(df):
file_path = "/tmp/tender_results.csv"
df.to_csv(file_path, index=False)
return file_path
# Button actions
submit_button.click(
handle_query,
inputs=[date_input, category_dropdown, type_dropdown,
unit_name_input, unit_id_input, job_number_input, name_input],
outputs=[output, csv_data]
)
download_button.click(export_csv, inputs=[csv_data], outputs=gr.File())
demo.launch()
if __name__ == "__main__":
create_interface()