cfmanager / app.py
HFHash789's picture
Upload folder using huggingface_hub
32e4bbf verified
#!/usr/bin/env python3
"""
Cloudflare Manager Web Interface
For deployment on Hugging Face Spaces
"""
import gradio as gr
import os
from cloudflare_manager import CloudflareManager, CloudflareAccount
def test_connection(email, token):
"""Test Cloudflare API connection"""
try:
account = CloudflareAccount(email=email, token=token, use_api_key=True)
cf = CloudflareManager(account)
if cf.account.account_id:
return f"βœ“ Connected!\n\nAccount: {cf.account.name}\nID: {cf.account.account_id}"
else:
return "βœ— Failed to connect. Please check your credentials."
except Exception as e:
return f"βœ— Error: {str(e)}"
def list_projects(email, token):
"""List all Pages projects"""
try:
account = CloudflareAccount(email=email, token=token, use_api_key=True)
cf = CloudflareManager(account)
projects = cf.list_pages_projects()
if not projects:
return "No projects found."
result = f"Found {len(projects)} project(s):\n\n"
for project in projects:
result += f"πŸ“¦ {project['name']}\n"
result += f" URL: https://{project.get('subdomain', 'N/A')}\n"
result += f" Created: {project.get('created_on', 'N/A')}\n\n"
return result
except Exception as e:
return f"βœ— Error: {str(e)}"
def create_project(email, token, project_name, branch):
"""Create a new Pages project"""
try:
account = CloudflareAccount(email=email, token=token, use_api_key=True)
cf = CloudflareManager(account)
project = cf.create_pages_project(project_name, branch)
if project:
return f"βœ“ Project created!\n\nName: {project['name']}\nURL: https://{project.get('subdomain')}\n"
else:
return "βœ— Failed to create project"
except Exception as e:
return f"βœ— Error: {str(e)}"
def list_zones(email, token):
"""List all zones"""
try:
account = CloudflareAccount(email=email, token=token, use_api_key=True)
cf = CloudflareManager(account)
zones = cf.list_zones()
if not zones:
return "No zones found."
result = f"Found {len(zones)} zone(s):\n\n"
for zone in zones:
result += f"🌐 {zone['name']}\n"
result += f" Zone ID: {zone['id']}\n"
result += f" Status: {zone.get('status', 'unknown')}\n"
nameservers = zone.get('name_servers', [])
if nameservers:
result += f" Nameservers:\n"
for ns in nameservers:
result += f" - {ns}\n"
result += "\n"
return result
except Exception as e:
return f"βœ— Error: {str(e)}"
def create_zone_and_get_ns(email, token, domain_name):
"""Create zone and get nameservers"""
try:
account = CloudflareAccount(email=email, token=token, use_api_key=True)
cf = CloudflareManager(account)
zone = cf.create_zone(domain_name)
if zone:
nameservers = zone.get('name_servers', [])
result = f"βœ“ Zone created for {domain_name}\n\n"
result += f"Zone ID: {zone['id']}\n\n"
result += "πŸ“‹ Add these nameservers to your domain registrar:\n\n"
for ns in nameservers:
result += f" {ns}\n"
return result
else:
return "βœ— Failed to create zone"
except Exception as e:
return f"βœ— Error: {str(e)}"
def bind_domain(email, token, project_name, domain_name):
"""Bind domain to Pages project"""
try:
account = CloudflareAccount(email=email, token=token, use_api_key=True)
cf = CloudflareManager(account)
result_data = cf.add_pages_domain(project_name, domain_name)
if result_data:
result = f"βœ“ Domain bound to project!\n\n"
result += f"Domain: {result_data.get('name')}\n"
result += f"Status: {result_data.get('status')}\n\n"
if result_data.get('validation_data'):
val = result_data['validation_data']
result += f"DNS Validation Required:\n"
result += f" Type: {val.get('type')}\n"
result += f" Name: {val.get('name')}\n"
result += f" Value: {val.get('value')}\n"
return result
else:
return "βœ— Failed to bind domain"
except Exception as e:
return f"βœ— Error: {str(e)}"
def create_worker_route(email, token, zone_id, pattern, script_name):
"""Create worker route"""
try:
account = CloudflareAccount(email=email, token=token, use_api_key=True)
cf = CloudflareManager(account)
route = cf.create_worker_route(zone_id, pattern, script_name)
if route:
return f"βœ“ Worker route created!\n\nRoute ID: {route.get('id')}\nPattern: {pattern}\nScript: {script_name}"
else:
return "βœ— Failed to create route"
except Exception as e:
return f"βœ— Error: {str(e)}"
# Create Gradio interface
with gr.Blocks(title="Cloudflare Manager") as demo:
gr.Markdown("""
# πŸš€ Cloudflare Multi-Account Manager
Manage Cloudflare Pages, Domains, and Workers through a simple web interface.
## Features
- βœ… Pages project management
- βœ… Domain binding
- βœ… Nameserver lookup
- βœ… Worker route configuration
""")
with gr.Row():
with gr.Column():
email_input = gr.Textbox(
label="Cloudflare Email",
placeholder="your-email@example.com",
value=os.getenv("CLOUDFLARE_EMAIL", "")
)
token_input = gr.Textbox(
label="API Token",
type="password",
placeholder="Your API Token",
value=os.getenv("CLOUDFLARE_TOKEN", "")
)
with gr.Tabs():
# Tab 1: Connection Test
with gr.Tab("πŸ”Œ Connection Test"):
test_btn = gr.Button("Test Connection", variant="primary")
test_output = gr.Textbox(label="Result", lines=5)
test_btn.click(
test_connection,
inputs=[email_input, token_input],
outputs=test_output
)
# Tab 2: Pages Projects
with gr.Tab("πŸ“¦ Pages Projects"):
with gr.Row():
with gr.Column():
gr.Markdown("### List Projects")
list_projects_btn = gr.Button("List Projects")
list_projects_output = gr.Textbox(label="Projects", lines=10)
list_projects_btn.click(
list_projects,
inputs=[email_input, token_input],
outputs=list_projects_output
)
with gr.Column():
gr.Markdown("### Create Project")
project_name = gr.Textbox(label="Project Name", placeholder="my-website")
project_branch = gr.Textbox(label="Branch", value="main")
create_project_btn = gr.Button("Create Project", variant="primary")
create_project_output = gr.Textbox(label="Result", lines=10)
create_project_btn.click(
create_project,
inputs=[email_input, token_input, project_name, project_branch],
outputs=create_project_output
)
# Tab 3: Domains & Zones
with gr.Tab("🌐 Domains & Zones"):
with gr.Row():
with gr.Column():
gr.Markdown("### List Zones")
list_zones_btn = gr.Button("List Zones")
list_zones_output = gr.Textbox(label="Zones", lines=10)
list_zones_btn.click(
list_zones,
inputs=[email_input, token_input],
outputs=list_zones_output
)
with gr.Column():
gr.Markdown("### Create Zone & Get Nameservers")
zone_domain = gr.Textbox(label="Domain Name", placeholder="example.com")
create_zone_btn = gr.Button("Create Zone", variant="primary")
create_zone_output = gr.Textbox(label="Result", lines=10)
create_zone_btn.click(
create_zone_and_get_ns,
inputs=[email_input, token_input, zone_domain],
outputs=create_zone_output
)
# Tab 4: Domain Binding
with gr.Tab("πŸ”— Bind Domain"):
gr.Markdown("### Bind Domain to Pages Project")
with gr.Row():
bind_project = gr.Textbox(label="Project Name", placeholder="my-website")
bind_domain_name = gr.Textbox(label="Domain", placeholder="example.com")
bind_btn = gr.Button("Bind Domain", variant="primary")
bind_output = gr.Textbox(label="Result", lines=10)
bind_btn.click(
bind_domain,
inputs=[email_input, token_input, bind_project, bind_domain_name],
outputs=bind_output
)
# Tab 5: Worker Routes
with gr.Tab("⚑ Worker Routes"):
gr.Markdown("### Create Worker Route")
worker_zone_id = gr.Textbox(label="Zone ID", placeholder="abc123...")
worker_pattern = gr.Textbox(label="Route Pattern", placeholder="example.com/api/*")
worker_script = gr.Textbox(label="Script Name", placeholder="my-worker")
worker_btn = gr.Button("Create Route", variant="primary")
worker_output = gr.Textbox(label="Result", lines=10)
worker_btn.click(
create_worker_route,
inputs=[email_input, token_input, worker_zone_id, worker_pattern, worker_script],
outputs=worker_output
)
gr.Markdown("""
---
### πŸ“š Documentation
- [Quick Start Guide](GET_STARTED.md)
- [Usage Guide](USAGE_GUIDE.md)
- [API Reference](API_REFERENCE.md)
### πŸ”‘ API Token Permissions
Your API token needs:
- Account > Cloudflare Pages > Edit
- Zone > DNS > Edit
- Zone > Workers Routes > Edit
### πŸ’‘ Tips
1. Get your API token from: https://dash.cloudflare.com/profile/api-tokens
2. After creating a zone, add the nameservers to your domain registrar
3. DNS propagation takes 5-30 minutes
""")
if __name__ == "__main__":
# Run with sharing enabled for Hugging Face Spaces
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=False
)