Files
feldman/app.py

125 lines
3.9 KiB
Python
Raw Normal View History

from flask import Flask, request, jsonify
from functools import wraps
import psycopg2
from psycopg2.extras import RealDictCursor
import os
import hashlib
from datetime import datetime
app = Flask(__name__)
H_INSTANCIA = os.environ.get('H_INSTANCIA')
DB_HOST = os.environ.get('DB_HOST', '172.17.0.1')
DB_PORT = os.environ.get('DB_PORT', '5432')
DB_NAME = os.environ.get('DB_NAME', 'corp')
DB_USER = os.environ.get('DB_USER', 'corp')
DB_PASSWORD = os.environ.get('DB_PASSWORD', 'corp')
PORT = int(os.environ.get('PORT', 5054))
def get_db():
return psycopg2.connect(
host=DB_HOST, port=DB_PORT, database=DB_NAME,
user=DB_USER, password=DB_PASSWORD,
cursor_factory=RealDictCursor
)
def require_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth_key = request.headers.get('X-Auth-Key')
if not auth_key or auth_key != H_INSTANCIA:
return jsonify({'error': 'Unauthorized'}), 401
return f(*args, **kwargs)
return decorated
def generate_hash(data):
return hashlib.sha256(f"{data}{datetime.now().isoformat()}".encode()).hexdigest()[:64]
@app.route('/health', methods=['GET'])
def health():
try:
conn = get_db()
cur = conn.cursor()
cur.execute('SELECT 1')
cur.close()
conn.close()
return jsonify({'status': 'healthy', 'service': 'feldman', 'version': '1.0.0'})
except Exception as e:
return jsonify({'status': 'unhealthy', 'error': str(e)}), 500
@app.route('/s-contract', methods=['GET'])
def s_contract():
return jsonify({
'service': 'feldman',
'version': '1.0.0',
'contract_version': 'S-CONTRACT v2.1',
'description': 'Receives routed OK flows from ALFRED/JARED',
'endpoints': {
'/health': {'method': 'GET', 'auth': False},
'/recibir': {'method': 'POST', 'auth': True, 'desc': 'Receive completed flow'},
'/completados': {'method': 'GET', 'auth': True, 'desc': 'List completed flows'},
'/stats': {'method': 'GET', 'auth': True, 'desc': 'Statistics'}
}
})
@app.route('/recibir', methods=['POST'])
@require_auth
def recibir():
data = request.get_json() or {}
h_completado = generate_hash(str(data))
conn = get_db()
cur = conn.cursor()
cur.execute('''
INSERT INTO completados
(h_completado, h_instancia_origen, h_ejecucion, flujo_nombre, datos, notas)
VALUES (%s, %s, %s, %s, %s, %s)
RETURNING id, h_completado, created_at
''', (
h_completado,
data.get('h_instancia_origen', 'unknown'),
data.get('h_ejecucion', ''),
data.get('flujo_nombre', ''),
psycopg2.extras.Json(data),
data.get('notas', '')
))
result = cur.fetchone()
conn.commit()
cur.close()
conn.close()
return jsonify({'success': True, 'registro': dict(result), 'service': 'feldman'})
@app.route('/completados', methods=['GET'])
@require_auth
def completados():
limit = request.args.get('limit', 50, type=int)
conn = get_db()
cur = conn.cursor()
cur.execute('SELECT * FROM completados ORDER BY created_at DESC LIMIT %s', (limit,))
records = cur.fetchall()
cur.close()
conn.close()
return jsonify({'completados': [dict(r) for r in records], 'count': len(records)})
@app.route('/stats', methods=['GET'])
@require_auth
def stats():
conn = get_db()
cur = conn.cursor()
cur.execute('SELECT COUNT(*) as total FROM completados')
total = cur.fetchone()['total']
cur.execute('''
SELECT DATE(created_at) as fecha, COUNT(*) as count
FROM completados
GROUP BY DATE(created_at)
ORDER BY fecha DESC LIMIT 7
''')
por_dia = {str(r['fecha']): r['count'] for r in cur.fetchall()}
cur.close()
conn.close()
return jsonify({'total': total, 'por_dia': por_dia})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=PORT, debug=False)