InklyAI / web_app.py
pravinai's picture
Upload folder using huggingface_hub
8eab354 verified
"""
Flask Web Application for InklyAI Signature Verification UI
"""
from flask import Flask, render_template, request, jsonify, send_from_directory
import os
import uuid
from datetime import datetime
import logging
from werkzeug.utils import secure_filename
from agentai_integration import AgentAISignatureManager, AgentAISignatureAPI
from src.models.siamese_network import SignatureVerifier
from src.data.preprocessing import SignaturePreprocessor
# Initialize Flask app
app = Flask(__name__)
app.config['SECRET_KEY'] = 'inklyai-secret-key-2024'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max file size
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Initialize signature manager
signature_manager = AgentAISignatureManager(
threshold=0.75,
device='auto'
)
# Initialize API wrapper
api = AgentAISignatureAPI(signature_manager)
# Create upload directories
UPLOAD_FOLDER = 'uploads'
REFERENCE_FOLDER = 'uploads/reference'
VERIFICATION_FOLDER = 'uploads/verification'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(REFERENCE_FOLDER, exist_ok=True)
os.makedirs(VERIFICATION_FOLDER, exist_ok=True)
# Allowed file extensions
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'bmp', 'tiff'}
def allowed_file(filename):
"""Check if file extension is allowed."""
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def save_uploaded_file(file, folder):
"""Save uploaded file and return the path."""
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
# Add timestamp to avoid conflicts
name, ext = os.path.splitext(filename)
filename = f"{name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}{ext}"
filepath = os.path.join(folder, filename)
file.save(filepath)
return filepath
return None
@app.route('/')
def index():
"""Main page with signature verification UI."""
return render_template('index.html')
@app.route('/agents')
def agents():
"""Agent management page."""
return render_template('agents.html')
@app.route('/api/agents', methods=['GET'])
def get_agents():
"""Get list of registered agents."""
try:
agents = []
for agent_id, agent_signature in signature_manager.agent_signatures.items():
agents.append({
'agent_id': agent_id,
'created_at': agent_signature.created_at.isoformat(),
'last_verified': agent_signature.last_verified.isoformat() if agent_signature.last_verified else None,
'verification_count': agent_signature.verification_count,
'is_active': agent_signature.is_active
})
return jsonify({
'success': True,
'agents': agents,
'total_agents': len(agents)
})
except Exception as e:
logger.error(f"Error getting agents: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/register-agent', methods=['POST'])
def register_agent():
"""Register a new agent with signature template."""
try:
if 'signature_template' not in request.files:
return jsonify({
'success': False,
'error': 'No signature template file provided'
}), 400
file = request.files['signature_template']
agent_id = request.form.get('agent_id')
if not agent_id:
return jsonify({
'success': False,
'error': 'Agent ID is required'
}), 400
# Save the signature template
filepath = save_uploaded_file(file, REFERENCE_FOLDER)
if not filepath:
return jsonify({
'success': False,
'error': 'Invalid file type. Please upload an image file.'
}), 400
# Register the agent
success = signature_manager.register_agent_signature(agent_id, filepath)
if success:
return jsonify({
'success': True,
'agent_id': agent_id,
'message': 'Agent registered successfully'
})
else:
return jsonify({
'success': False,
'error': 'Failed to register agent'
}), 400
except Exception as e:
logger.error(f"Error registering agent: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/verify', methods=['POST'])
def verify_signatures():
"""Verify two signatures."""
try:
if 'signature1' not in request.files or 'signature2' not in request.files:
return jsonify({
'success': False,
'error': 'Both signature files are required'
}), 400
agent_id = request.form.get('agent_id')
if not agent_id:
return jsonify({
'success': False,
'error': 'Agent ID is required'
}), 400
# Save uploaded files
file1 = request.files['signature1']
file2 = request.files['signature2']
file1_path = save_uploaded_file(file1, VERIFICATION_FOLDER)
file2_path = save_uploaded_file(file2, VERIFICATION_FOLDER)
if not file1_path or not file2_path:
return jsonify({
'success': False,
'error': 'Invalid file types. Please upload image files.'
}), 400
# Verify signatures
similarity, is_genuine = signature_manager.verifier.verify_signatures(
file1_path, file2_path, threshold=signature_manager.threshold
)
# Calculate confidence
confidence = similarity # Simple confidence calculation
# Create verification result
verification_id = str(uuid.uuid4())[:12]
result = {
'success': True,
'is_verified': is_genuine,
'similarity_score': float(similarity),
'confidence': float(confidence),
'verification_id': verification_id,
'timestamp': datetime.now().isoformat(),
'agent_id': agent_id
}
# Log verification
logger.info(f"Verification completed: {result}")
return jsonify(result)
except Exception as e:
logger.error(f"Error verifying signatures: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/verify-agent', methods=['POST'])
def verify_agent_signature():
"""Verify signature against registered agent template."""
try:
if 'signature_image' not in request.files:
return jsonify({
'success': False,
'error': 'Signature image file is required'
}), 400
agent_id = request.form.get('agent_id')
if not agent_id:
return jsonify({
'success': False,
'error': 'Agent ID is required'
}), 400
# Check if agent exists
if agent_id not in signature_manager.agent_signatures:
return jsonify({
'success': False,
'error': 'Agent not found'
}), 404
# Save uploaded file
file = request.files['signature_image']
file_path = save_uploaded_file(file, VERIFICATION_FOLDER)
if not file_path:
return jsonify({
'success': False,
'error': 'Invalid file type. Please upload an image file.'
}), 400
# Verify against agent template
result = signature_manager.verify_agent_signature(agent_id, file_path)
return jsonify({
'success': True,
'is_verified': result.is_verified,
'similarity_score': result.similarity_score,
'confidence': result.confidence,
'verification_id': result.verification_id,
'timestamp': result.timestamp.isoformat(),
'agent_id': agent_id
})
except Exception as e:
logger.error(f"Error verifying agent signature: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/stats', methods=['GET'])
def get_stats():
"""Get verification statistics."""
try:
stats = {}
for agent_id in signature_manager.agent_signatures.keys():
agent_stats = signature_manager.get_agent_verification_stats(agent_id)
stats[agent_id] = agent_stats
return jsonify({
'success': True,
'stats': stats
})
except Exception as e:
logger.error(f"Error getting stats: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/agent-stats/<agent_id>', methods=['GET'])
def get_agent_stats(agent_id):
"""Get statistics for a specific agent."""
try:
stats = signature_manager.get_agent_verification_stats(agent_id)
return jsonify({
'success': True,
'agent_id': agent_id,
'stats': stats
})
except Exception as e:
logger.error(f"Error getting agent stats: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/deactivate-agent/<agent_id>', methods=['POST'])
def deactivate_agent(agent_id):
"""Deactivate an agent."""
try:
success = signature_manager.deactivate_agent(agent_id)
return jsonify({
'success': success,
'agent_id': agent_id,
'action': 'deactivated'
})
except Exception as e:
logger.error(f"Error deactivating agent: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/reactivate-agent/<agent_id>', methods=['POST'])
def reactivate_agent(agent_id):
"""Reactivate an agent."""
try:
success = signature_manager.reactivate_agent(agent_id)
return jsonify({
'success': success,
'agent_id': agent_id,
'action': 'reactivated'
})
except Exception as e:
logger.error(f"Error reactivating agent: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/health', methods=['GET'])
def health_check():
"""Health check endpoint."""
return jsonify({
'status': 'healthy',
'timestamp': datetime.now().isoformat(),
'service': 'InklyAI Web Application',
'agents_registered': len(signature_manager.agent_signatures)
})
@app.errorhandler(413)
def too_large(e):
"""Handle file too large error."""
return jsonify({
'success': False,
'error': 'File too large. Maximum size is 16MB.'
}), 413
@app.errorhandler(404)
def not_found(e):
"""Handle 404 errors."""
return jsonify({
'success': False,
'error': 'Endpoint not found'
}), 404
@app.errorhandler(500)
def internal_error(e):
"""Handle 500 errors."""
return jsonify({
'success': False,
'error': 'Internal server error'
}), 500
def initialize_demo_agents():
"""Initialize demo agents if sample data exists."""
try:
# Register demo agents if sample data exists
demo_agents = [
('Agent_01', 'data/samples/john_doe_1.png'),
('Agent_02', 'data/samples/jane_smith_1.png'),
('Agent_03', 'data/samples/bob_wilson_1.png'),
('Agent_04', 'data/samples/alice_brown_1.png')
]
for agent_id, signature_template in demo_agents:
if os.path.exists(signature_template):
signature_manager.register_agent_signature(agent_id, signature_template)
logger.info(f"Registered agent: {agent_id}")
logger.info("Demo agents initialized successfully")
except Exception as e:
logger.warning(f"Could not initialize demo agents: {e}")
if __name__ == '__main__':
# Initialize demo agents
initialize_demo_agents()
# Start the web application
port = int(os.environ.get('PORT', 8080)) # Use port 8080 instead of 5000
debug = os.environ.get('DEBUG', 'False').lower() == 'true'
logger.info(f"Starting InklyAI Web Application on port {port}")
logger.info(f"Access the application at: http://localhost:{port}")
app.run(host='0.0.0.0', port=port, debug=debug)