Snapshot: full project state
This commit is contained in:
81
app.py
Normal file
81
app.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Payment Recon Search Engine
|
||||
Flask API + static frontend — searches the web for payment processor usage,
|
||||
takes screenshots, and classifies sites with local vision models.
|
||||
"""
|
||||
import json, time, threading, urllib.parse
|
||||
from pathlib import Path
|
||||
from flask import Flask, request, jsonify, send_from_directory
|
||||
from search_engine import search_processor, search_all, PROCESSORS
|
||||
from vision import batch_analyze
|
||||
|
||||
app = Flask(__name__, static_folder='static', static_url_path='')
|
||||
|
||||
# In-memory job queue
|
||||
jobs = {}
|
||||
job_lock = threading.Lock()
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return send_from_directory('static', 'index.html')
|
||||
|
||||
@app.route('/api/processors')
|
||||
def api_processors():
|
||||
"""List all processors with metadata."""
|
||||
return jsonify(PROCESSORS)
|
||||
|
||||
@app.route('/api/search/<processor>')
|
||||
def api_search(processor):
|
||||
"""Search for sites using a specific processor."""
|
||||
industry = request.args.get('industry', '')
|
||||
country = request.args.get('country', 'US')
|
||||
max_results = int(request.args.get('max', 8))
|
||||
|
||||
result = search_processor(processor, industry or None, country or None, max_results)
|
||||
return jsonify(result)
|
||||
|
||||
@app.route('/api/search-all')
|
||||
def api_search_all():
|
||||
"""Search across all processors."""
|
||||
industry = request.args.get('industry', '')
|
||||
country = request.args.get('country', 'US')
|
||||
result = search_all(industry or None, country or None, max_per_processor=4)
|
||||
return jsonify(result)
|
||||
|
||||
@app.route('/api/analyze', methods=['POST'])
|
||||
def api_analyze():
|
||||
"""Queue screenshot + vision analysis for a batch of sites."""
|
||||
data = request.get_json()
|
||||
sites = data.get('sites', [])
|
||||
processor = data.get('processor', 'Unknown')
|
||||
|
||||
job_id = str(int(time.time() * 1000))
|
||||
|
||||
with job_lock:
|
||||
jobs[job_id] = {'status': 'running', 'progress': 0, 'results': [], 'total': len(sites)}
|
||||
|
||||
def run():
|
||||
results = batch_analyze(sites, processor, max_screenshots=min(len(sites), 8))
|
||||
with job_lock:
|
||||
jobs[job_id] = {'status': 'complete', 'progress': 100, 'results': results, 'total': len(sites)}
|
||||
|
||||
threading.Thread(target=run, daemon=True).start()
|
||||
return jsonify({'job_id': job_id, 'status': 'queued', 'total': len(sites)})
|
||||
|
||||
@app.route('/api/job/<job_id>')
|
||||
def api_job_status(job_id):
|
||||
"""Check analysis job status."""
|
||||
with job_lock:
|
||||
job = jobs.get(job_id, {'status': 'not_found'})
|
||||
return jsonify(job)
|
||||
|
||||
@app.route('/api/health')
|
||||
def api_health():
|
||||
return jsonify({'status': 'ok', 'processors': len(PROCESSORS['processors'])})
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("🔍 Payment Recon Engine")
|
||||
print(f" {len(PROCESSORS['processors'])} processors loaded")
|
||||
print(f" http://localhost:5052")
|
||||
app.run(host='0.0.0.0', port=5052, debug=False)
|
||||
Reference in New Issue
Block a user