DBExportTool / app.py
joycecast's picture
Upload 8 files
3aaca8e verified
Raw
History Blame Contribute Delete
17.6 kB
#!/usr/bin/env python3
"""
Notion to Excel Exporter - Hugging Face Gradio Application
Exports data from Notion databases with multiple export modes.
"""
import os
import gradio as gr
from datetime import datetime
from typing import Optional, Tuple
import traceback
# Import exporters
from notion_exporter import NotionExcelExporter, load_notion_config_from_env
from entry_milestone_exporter import EntryMilestoneExporter
from mawb_milestone_exporter import MAWBMilestoneExporter
from notion_integration import NotionIntegration
# Load authentication credentials from environment
HF_USERNAME = os.environ.get("HF_USERNAME", "admin")
HF_PASSWORD = os.environ.get("HF_PASSWORD", "password")
def export_notion_databases(
db_mawb: bool,
db_entry_records: bool,
db_mawb_tasks: bool,
db_mawb_milestones: bool,
db_dwell_report: bool,
start_date: Optional[str],
end_date: Optional[str],
slow_mode: bool,
page_size: int
) -> Tuple[Optional[str], str]:
"""Export selected Notion databases to Excel."""
try:
selected_databases = []
if db_mawb:
selected_databases.append("mawb")
if db_entry_records:
selected_databases.append("entry_record")
if db_mawb_tasks:
selected_databases.append("mawb_task")
if db_mawb_milestones:
selected_databases.append("mawb_milestone")
if db_dwell_report:
selected_databases.append("dwell_report")
if not selected_databases:
return None, "ERROR: Please select at least one database to export."
# Validate dates
date_filter = None
if start_date or end_date:
date_filter = {}
if start_date:
try:
datetime.strptime(start_date, '%Y-%m-%d')
date_filter['start_date'] = start_date
except ValueError:
return None, f"ERROR: Invalid start date format '{start_date}'. Use YYYY-MM-DD format."
if end_date:
try:
datetime.strptime(end_date, '%Y-%m-%d')
date_filter['end_date'] = end_date
except ValueError:
return None, f"ERROR: Invalid end date format '{end_date}'. Use YYYY-MM-DD format."
if start_date and end_date:
start_dt = datetime.strptime(start_date, '%Y-%m-%d')
end_dt = datetime.strptime(end_date, '%Y-%m-%d')
if start_dt > end_dt:
return None, f"ERROR: Start date must be before or equal to end date."
# Export
status_msg = f"Initializing Notion database export...\n"
status_msg += f"Selected databases: {', '.join(selected_databases)}\n"
if date_filter:
status_msg += f"Date filter (created_time): {date_filter}\n"
status_msg += f"Slow mode: {'Enabled' if slow_mode else 'Disabled'}\n"
status_msg += f"Page size: {page_size}\n\n"
exporter = NotionExcelExporter(slow_mode=slow_mode, page_size=page_size)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
if len(selected_databases) == 1:
output_file = f"notion_{selected_databases[0]}_{timestamp}.xlsx"
else:
output_file = f"notion_export_{timestamp}.xlsx"
result_file = exporter.export_selected_databases(
database_names=selected_databases,
output_file=output_file,
date_filter=date_filter
)
status_msg += f"\nExport completed successfully!\n"
status_msg += f"File: {result_file}\n"
status_msg += f"Total API calls: {exporter.api_call_count}\n"
status_msg += f"Databases exported: {len(selected_databases)}\n"
return result_file, status_msg
except Exception as e:
error_msg = f"ERROR during export:\n{str(e)}\n\n"
error_msg += f"Traceback:\n{traceback.format_exc()}"
return None, error_msg
def export_entry_milestones(
mawb_input: Optional[str],
start_date: Optional[str],
end_date: Optional[str]
) -> Tuple[Optional[str], str]:
"""Export entry milestone data to Excel."""
try:
# Validate dates
date_filter = None
if start_date or end_date:
date_filter = {}
if start_date:
try:
datetime.strptime(start_date, '%Y-%m-%d')
date_filter['start_date'] = start_date
except ValueError:
return None, f"ERROR: Invalid start date format '{start_date}'. Use YYYY-MM-DD format."
if end_date:
try:
datetime.strptime(end_date, '%Y-%m-%d')
date_filter['end_date'] = end_date
except ValueError:
return None, f"ERROR: Invalid end date format '{end_date}'. Use YYYY-MM-DD format."
if start_date and end_date:
start_dt = datetime.strptime(start_date, '%Y-%m-%d')
end_dt = datetime.strptime(end_date, '%Y-%m-%d')
if start_dt > end_dt:
return None, f"ERROR: Start date must be before or equal to end date."
# Initialize Notion integration
config = load_notion_config_from_env()
notion = NotionIntegration(config['api_key'], config['database_ids'])
exporter = EntryMilestoneExporter(notion)
# Generate output filename
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
if mawb_input and mawb_input.strip():
output_file = f"entry_milestone_export_specific_{timestamp}.xlsx"
else:
output_file = f"entry_milestone_export_all_{timestamp}.xlsx"
# Status message
status_msg = f"Initializing entry milestone export...\n"
if mawb_input and mawb_input.strip():
mawb_list = exporter.parse_mawb_input(mawb_input)
status_msg += f"MAWBs specified: {len(mawb_list)} ({', '.join(mawb_list[:5])}{'...' if len(mawb_list) > 5 else ''})\n"
else:
status_msg += f"Exporting all entry records\n"
if date_filter:
status_msg += f"Date filter (created_time): {date_filter}\n"
status_msg += "\n"
# Export
result_file = exporter.export_to_excel(
mawb_input=mawb_input if mawb_input and mawb_input.strip() else None,
output_file=output_file,
date_filter=date_filter
)
status_msg += f"\nEntry milestone export completed successfully!\n"
status_msg += f"File: {result_file}\n"
return result_file, status_msg
except Exception as e:
error_msg = f"ERROR during entry milestone export:\n{str(e)}\n\n"
error_msg += f"Traceback:\n{traceback.format_exc()}"
return None, error_msg
def export_mawb_milestones(
mawb_input: Optional[str],
start_date: Optional[str],
end_date: Optional[str]
) -> Tuple[Optional[str], str]:
"""Export SHEIN T01 MAWB milestone data to Excel."""
try:
# Validate dates
date_filter = None
if start_date or end_date:
date_filter = {}
if start_date:
try:
datetime.strptime(start_date, '%Y-%m-%d')
date_filter['start_date'] = start_date
except ValueError:
return None, f"ERROR: Invalid start date format '{start_date}'. Use YYYY-MM-DD format."
if end_date:
try:
datetime.strptime(end_date, '%Y-%m-%d')
date_filter['end_date'] = end_date
except ValueError:
return None, f"ERROR: Invalid end date format '{end_date}'. Use YYYY-MM-DD format."
if start_date and end_date:
start_dt = datetime.strptime(start_date, '%Y-%m-%d')
end_dt = datetime.strptime(end_date, '%Y-%m-%d')
if start_dt > end_dt:
return None, f"ERROR: Start date must be before or equal to end date."
# Initialize Notion integration
config = load_notion_config_from_env()
notion = NotionIntegration(config['api_key'], config['database_ids'])
exporter = MAWBMilestoneExporter(notion)
# Generate output filename
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
if mawb_input and mawb_input.strip():
output_file = f"mawb_milestone_export_specific_{timestamp}.xlsx"
else:
output_file = f"mawb_milestone_export_all_{timestamp}.xlsx"
# Status message
status_msg = f"Initializing SHEIN T01 MAWB milestone export...\n"
if mawb_input and mawb_input.strip():
mawb_list = exporter.parse_mawb_input(mawb_input)
status_msg += f"MAWBs specified: {len(mawb_list)} ({', '.join(mawb_list[:5])}{'...' if len(mawb_list) > 5 else ''})\n"
else:
status_msg += f"Exporting all SHEIN T01 MAWBs\n"
if date_filter:
status_msg += f"Date filter (created_time): {date_filter}\n"
status_msg += "\n"
# Export
result_file = exporter.export_to_excel(
mawb_input=mawb_input if mawb_input and mawb_input.strip() else None,
output_file=output_file,
date_filter=date_filter
)
status_msg += f"\nMAWB milestone export completed successfully!\n"
status_msg += f"File: {result_file}\n"
return result_file, status_msg
except Exception as e:
error_msg = f"ERROR during MAWB milestone export:\n{str(e)}\n\n"
error_msg += f"Traceback:\n{traceback.format_exc()}"
return None, error_msg
# Create Gradio interface with tabs
with gr.Blocks(title="Notion Excel Exporter") as demo:
gr.Markdown("# Notion Data Exporter")
gr.Markdown("Export data from Notion databases to Excel format with multiple export modes.")
with gr.Tabs():
# TAB 1: Notion Database Export
with gr.Tab("Notion Databases"):
gr.Markdown("### Export Raw Notion Database Tables")
gr.Markdown("Export one or more Notion databases with all properties automatically captured.")
with gr.Row():
with gr.Column():
gr.Markdown("**Database Selection**")
db1_mawb = gr.Checkbox(label="MAWB Database", value=False)
db1_entry_records = gr.Checkbox(label="Entry Records Database", value=False)
db1_mawb_tasks = gr.Checkbox(label="MAWB Tasks Database", value=False)
db1_mawb_milestones = gr.Checkbox(label="MAWB Milestones Database", value=False)
db1_dwell_report = gr.Checkbox(label="Dwell Report Database", value=False)
with gr.Column():
gr.Markdown("**Export Options**")
db1_start_date = gr.Textbox(
label="Start Date (Optional - filters by created_time)",
placeholder="YYYY-MM-DD (e.g., 2024-01-01)"
)
db1_end_date = gr.Textbox(
label="End Date (Optional - filters by created_time)",
placeholder="YYYY-MM-DD (e.g., 2024-12-31)"
)
db1_slow_mode = gr.Checkbox(
label="Enable Slow Mode (for large exports)",
value=False
)
db1_page_size = gr.Slider(
minimum=25,
maximum=100,
value=50,
step=5,
label="API Page Size"
)
db1_export_btn = gr.Button("Export Notion Databases", variant="primary")
db1_status = gr.Textbox(label="Status", lines=10, interactive=False)
db1_download = gr.File(label="Download File")
db1_export_btn.click(
fn=export_notion_databases,
inputs=[
db1_mawb, db1_entry_records, db1_mawb_tasks,
db1_mawb_milestones, db1_dwell_report,
db1_start_date, db1_end_date, db1_slow_mode, db1_page_size
],
outputs=[db1_download, db1_status]
)
gr.Markdown("""
**Instructions:**
- Select one or more databases to export
- Optionally filter by created_time using start/end dates
- Multiple databases will be combined into a single Excel file with multiple sheets
""")
# TAB 2: Entry Milestone Export
with gr.Tab("Entry Milestones"):
gr.Markdown("### Export Entry Milestone Data")
gr.Markdown("Export entry milestone tracking data with CBP and CPSC status information.")
with gr.Row():
with gr.Column():
gr.Markdown("**Filter Options**")
entry_mawb_input = gr.Textbox(
label="MAWB Numbers (Optional)",
placeholder="Enter MAWBs (one per line or comma-separated)\nExample: 369-95208794, 370-12345678",
lines=5
)
with gr.Column():
gr.Markdown("**Date Filter (created_time)**")
entry_start_date = gr.Textbox(
label="Start Date (Optional)",
placeholder="YYYY-MM-DD (e.g., 2024-01-01)"
)
entry_end_date = gr.Textbox(
label="End Date (Optional)",
placeholder="YYYY-MM-DD (e.g., 2024-12-31)"
)
entry_export_btn = gr.Button("Export Entry Milestones", variant="primary")
entry_status = gr.Textbox(label="Status", lines=10, interactive=False)
entry_download = gr.File(label="Download File")
entry_export_btn.click(
fn=export_entry_milestones,
inputs=[entry_mawb_input, entry_start_date, entry_end_date],
outputs=[entry_download, entry_status]
)
gr.Markdown("""
**Instructions:**
- Leave MAWB field empty to export all entries
- Or specify MAWBs (comma or newline separated) to export specific entries
- Optionally filter by entry record created_time using start/end dates
- Export includes: Entry, MAWB, POD, CBP status, CPSC status, release dates
""")
# TAB 3: MAWB Milestone Export
with gr.Tab("MAWB Milestones (SHEIN T01)"):
gr.Markdown("### Export SHEIN T01 MAWB Milestone Data")
gr.Markdown("Export aggregated milestone data for SHEIN T01 MAWBs (one row per MAWB).")
with gr.Row():
with gr.Column():
gr.Markdown("**Filter Options**")
mawb_mawb_input = gr.Textbox(
label="MAWB Numbers (Optional)",
placeholder="Enter MAWBs (one per line or comma-separated)\nExample: 369-95208794, 370-12345678",
lines=5
)
with gr.Column():
gr.Markdown("**Date Filter (created_time)**")
mawb_start_date = gr.Textbox(
label="Start Date (Optional)",
placeholder="YYYY-MM-DD (e.g., 2024-01-01)"
)
mawb_end_date = gr.Textbox(
label="End Date (Optional)",
placeholder="YYYY-MM-DD (e.g., 2024-12-31)"
)
mawb_export_btn = gr.Button("Export MAWB Milestones", variant="primary")
mawb_status = gr.Textbox(label="Status", lines=10, interactive=False)
mawb_download = gr.File(label="Download File")
mawb_export_btn.click(
fn=export_mawb_milestones,
inputs=[mawb_mawb_input, mawb_start_date, mawb_end_date],
outputs=[mawb_download, mawb_status]
)
gr.Markdown("""
**Instructions:**
- Leave MAWB field empty to export all SHEIN T01 MAWBs
- Or specify MAWBs (comma or newline separated) to export specific MAWBs
- Optionally filter by MAWB record created_time using start/end dates
- Export includes aggregated data: Entry submission, CBP exam, CPSC review, customs release, warehouse milestones
- Data is aggregated across all related entries and milestone records per MAWB
""")
gr.Markdown("---")
gr.Markdown("""
### General Information
- **Date Filters**: All date filters use the Notion `created_time` field (when the record was created)
- **MAWB Input**: Accepts multiple formats - comma-separated, newline-separated, or tab-separated
- **Export Output**: All exports generate Excel (.xlsx) files with proper formatting
- **No Task Updates**: This tool is for export only - it does not modify any Notion records
""")
# Launch with authentication
if __name__ == "__main__":
demo.launch(
auth=(HF_USERNAME, HF_PASSWORD),
auth_message="Please enter your credentials to access the Notion Exporter",
server_name="0.0.0.0",
server_port=7860,
share=False,
ssr_mode=False
)