Initial commit
This commit is contained in:
commit
94d8e201f5
10 changed files with 909 additions and 0 deletions
133
app.py
Normal file
133
app.py
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Hostapd Web UI - Flask Application
|
||||
Provides REST API endpoints for managing WiFi stations via hostapd.
|
||||
"""
|
||||
|
||||
from flask import Flask, jsonify, request, render_template
|
||||
from hostapd_client import HostapdClient, HostapdClientError
|
||||
import logging
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Initialize Flask app
|
||||
app = Flask(__name__, template_folder="templates", static_folder="static")
|
||||
|
||||
# Initialize hostapd client
|
||||
# TODO: Make interface configurable via environment variable or config file
|
||||
hostapd_client = HostapdClient(interface="wlan0")
|
||||
|
||||
|
||||
@app.route("/api/v1/sta/list", methods=["GET"])
|
||||
def list_stations():
|
||||
"""
|
||||
GET /api/v1/sta/list
|
||||
Returns JSON array of connected station MAC addresses
|
||||
|
||||
Returns:
|
||||
JSON response with array of MAC addresses or error
|
||||
"""
|
||||
try:
|
||||
stations = hostapd_client.list_stations()
|
||||
logger.info(f"Retrieved {len(stations)} connected stations")
|
||||
return jsonify(stations), 200
|
||||
except HostapdClientError as e:
|
||||
logger.error(f"Failed to list stations: {str(e)}")
|
||||
return jsonify({"error": f"Failed to retrieve station list: {str(e)}"}), 500
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error listing stations: {str(e)}")
|
||||
return jsonify({"error": "Internal server error"}), 500
|
||||
|
||||
|
||||
@app.route("/api/v1/sta/details/<mac>", methods=["GET"])
|
||||
def get_station_details(mac):
|
||||
"""
|
||||
GET /api/v1/sta/details/<mac>
|
||||
Returns JSON object with detailed information about a specific station
|
||||
|
||||
Args:
|
||||
mac (str): MAC address of the station
|
||||
|
||||
Returns:
|
||||
JSON response with station details or error
|
||||
"""
|
||||
try:
|
||||
details = hostapd_client.get_station_details(mac)
|
||||
logger.info(f"Retrieved details for station {mac}")
|
||||
return jsonify(details), 200
|
||||
except HostapdClientError as e:
|
||||
logger.error(f"Failed to get details for {mac}: {str(e)}")
|
||||
if "Invalid MAC address" in str(e):
|
||||
return jsonify({"error": f"Invalid MAC address format: {mac}"}), 400
|
||||
elif "No details found" in str(e):
|
||||
return jsonify({"error": f"Station not found: {mac}"}), 404
|
||||
else:
|
||||
return (
|
||||
jsonify({"error": f"Failed to retrieve station details: {str(e)}"}),
|
||||
500,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error getting details for {mac}: {str(e)}")
|
||||
return jsonify({"error": "Internal server error"}), 500
|
||||
|
||||
|
||||
# Error handlers
|
||||
@app.errorhandler(404)
|
||||
def not_found(error):
|
||||
"""Handle 404 Not Found errors"""
|
||||
return jsonify({"error": "Endpoint not found"}), 404
|
||||
|
||||
|
||||
@app.errorhandler(500)
|
||||
def internal_error(error):
|
||||
"""Handle 500 Internal Server Error"""
|
||||
return jsonify({"error": "Internal server error"}), 500
|
||||
|
||||
|
||||
@app.errorhandler(Exception)
|
||||
def handle_exception(e):
|
||||
"""Handle unhandled exceptions"""
|
||||
logger.error(f"Unhandled exception: {str(e)}")
|
||||
return jsonify({"error": "Internal server error"}), 500
|
||||
|
||||
|
||||
# Health check endpoint
|
||||
@app.route("/health", methods=["GET"])
|
||||
def health_check():
|
||||
"""Health check endpoint"""
|
||||
return jsonify({"status": "healthy", "service": "hostapd-webui"}), 200
|
||||
|
||||
|
||||
# Serve the main web interface
|
||||
@app.route("/", methods=["GET"])
|
||||
def index():
|
||||
"""Serve the main web interface"""
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
# API endpoint with documentation
|
||||
@app.route("/api", methods=["GET"])
|
||||
def api_docs():
|
||||
"""API documentation endpoint"""
|
||||
return (
|
||||
jsonify(
|
||||
{
|
||||
"service": "hostapd-webui",
|
||||
"version": "1.0.0",
|
||||
"endpoints": {
|
||||
"GET /api/v1/sta/list": "Get list of connected stations",
|
||||
"GET /api/v1/sta/details/<mac>": "Get details for specific station",
|
||||
"GET /health": "Health check",
|
||||
},
|
||||
}
|
||||
),
|
||||
200,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run the Flask app
|
||||
# TODO: Make host/port configurable via environment variables
|
||||
app.run(host="0.0.0.0", port=5000, debug=False)
|
||||
Loading…
Add table
Add a link
Reference in a new issue