| | from fastapi import FastAPI, HTTPException
|
| | from fastapi.middleware.cors import CORSMiddleware
|
| | from fastapi.responses import JSONResponse
|
| | from parallel_miner_v3 import ParallelMiner
|
| | import threading
|
| | from typing import Dict, Optional
|
| | import uvicorn
|
| | import logging
|
| |
|
| |
|
| | logging.basicConfig(level=logging.INFO)
|
| | logger = logging.getLogger(__name__)
|
| |
|
| | app = FastAPI(title="Mining Dashboard API")
|
| |
|
| |
|
| | app.add_middleware(
|
| | CORSMiddleware,
|
| | allow_origins=["*"],
|
| | allow_credentials=True,
|
| | allow_methods=["*"],
|
| | allow_headers=["*"],
|
| | )
|
| |
|
| |
|
| | miner_instance: Optional[ParallelMiner] = None
|
| | mining_thread: Optional[threading.Thread] = None
|
| | is_mining = False
|
| |
|
| | @app.get("/status")
|
| | async def get_status() -> Dict:
|
| | """Get current mining status and statistics"""
|
| | global miner_instance, is_mining
|
| |
|
| | logger.info("Status endpoint called")
|
| | try:
|
| | if not miner_instance:
|
| | logger.info("No miner instance found, returning default values")
|
| | return {
|
| | "status": "Stopped",
|
| | "hashrate": 0,
|
| | "total_hashes": 0,
|
| | "blocks_found": 0,
|
| | "best_hash": None,
|
| | "difficulty": 0
|
| | }
|
| |
|
| | stats = {
|
| | "status": "Running" if is_mining else "Stopped",
|
| | "hashrate": round(miner_instance.current_hashrate / 1000, 2),
|
| | "total_hashes": miner_instance.total_hashes,
|
| | "blocks_found": miner_instance.blocks_found,
|
| | "best_hash": miner_instance.best_hash.hex() if miner_instance.best_hash else None,
|
| | "difficulty": miner_instance.best_hash_difficulty
|
| | }
|
| | logger.info(f"Returning stats: {stats}")
|
| | return stats
|
| | except Exception as e:
|
| | logger.error(f"Error getting status: {str(e)}")
|
| | raise HTTPException(status_code=500, detail=str(e))
|
| |
|
| | @app.post("/start")
|
| | async def start_mining() -> Dict:
|
| | """Start the mining process"""
|
| | global miner_instance, mining_thread, is_mining
|
| |
|
| | logger.info("Start mining endpoint called")
|
| |
|
| | if is_mining:
|
| | logger.warning("Mining is already running")
|
| | raise HTTPException(status_code=400, detail="Mining is already running")
|
| |
|
| | try:
|
| | logger.info("Initializing miner...")
|
| | miner_instance = ParallelMiner(num_cores=5)
|
| | miner_instance.mining = True
|
| | is_mining = True
|
| |
|
| |
|
| | logger.info("Starting mining thread...")
|
| | mining_thread = threading.Thread(
|
| | target=miner_instance.start_mining,
|
| | kwargs={"duration": None}
|
| | )
|
| | mining_thread.daemon = True
|
| | mining_thread.start()
|
| |
|
| | logger.info("Mining started successfully")
|
| | return {"message": "Mining started successfully"}
|
| | except Exception as e:
|
| | logger.error(f"Error starting mining: {str(e)}")
|
| | raise HTTPException(status_code=500, detail=str(e))
|
| |
|
| | @app.post("/api/stop")
|
| | async def stop_mining() -> Dict:
|
| | """Stop the mining process"""
|
| | global miner_instance, is_mining
|
| |
|
| | if not is_mining:
|
| | raise HTTPException(status_code=400, detail="Mining is not running")
|
| |
|
| | try:
|
| | if miner_instance:
|
| | miner_instance.mining = False
|
| | is_mining = False
|
| | return {"message": "Mining stopped successfully"}
|
| | raise HTTPException(status_code=400, detail="No active mining instance found")
|
| | except Exception as e:
|
| | raise HTTPException(status_code=500, detail=str(e))
|
| |
|
| | if __name__ == "__main__":
|
| | uvicorn.run(app, host="0.0.0.0", port=8000) |