File size: 3,556 Bytes
9e5fa5b
 
 
 
 
 
 
 
 
e1128ec
9e5fa5b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6ddeb15
 
 
 
 
 
 
 
 
 
 
 
 
9e5fa5b
 
 
e9af92b
 
 
 
9e5fa5b
 
 
 
 
 
 
 
 
ec76b2b
 
9e5fa5b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import sys
sys.path.insert(0, "/app")

from flask import Flask, request, jsonify, render_template
import json, time, os

from shared.config import Config
from shared.kafka_utils import create_producer

app = Flask(__name__, template_folder=os.getenv("TEMPLATE_FOLDER", "templates"))

producer = create_producer(component_name="Frontend")

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/health')
def health():
    """Health check endpoint."""
    import requests
    status = {
        "status": "healthy",
        "service": "frontend",
        "timestamp": time.time()
    }
    # Check Kafka producer
    try:
        producer.flush(timeout=1)
        status["kafka"] = "connected"
    except Exception as e:
        status["kafka"] = f"error: {e}"
        status["status"] = "degraded"

    # Check matcher connectivity
    try:
        r = requests.get(f"{Config.MATCHER_URL}/health", timeout=2)
        if r.status_code == 200:
            status["matcher"] = "connected"
        else:
            status["matcher"] = f"error: status {r.status_code}"
    except Exception as e:
        status["matcher"] = f"error: {e}"

    return jsonify(status)

@app.route('/order', methods=['POST'])
def send_order():
    if request.is_json:
        data = request.json
    else:
        data = {
            'order_id': request.form.get('order_id') or str(time.time_ns()),
            'symbol': request.form.get('symbol'),
            'type': request.form.get('type'),
            'quantity': int(request.form.get('quantity')),
            'price': float(request.form.get('price')),
            'timestamp': time.time()
        }
    producer.send(Config.ORDERS_TOPIC, value=data)
    producer.flush()
    return jsonify({'status':'sent','data':data})

@app.route('/securities')
def securities():
    symbols = []
    try:
        with open(Config.SECURITIES_FILE) as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#'):
                    symbols.append(line.split('\t')[0])
    except Exception:
        pass
    return jsonify(symbols)

@app.route('/book')
def book():
    import requests
    symbol = request.args.get('symbol', '')
    if not symbol:
        return jsonify({"bids": [], "asks": []})
    r = requests.get(f"{Config.MATCHER_URL}/orderbook/{symbol}", timeout=3)
    return (r.text, r.status_code, {'Content-Type': 'application/json'})

@app.route('/trades')
def trades():
    import requests
    r = requests.get(f"{Config.MATCHER_URL}/trades", timeout=2)
    return (r.text, r.status_code, {'Content-Type': 'application/json'})

if __name__ == '__main__':
    port = int(os.getenv('PORT', '5000'))
    app.run(host='0.0.0.0', port=port)


@app.route('/submit', methods=['POST'])
def submit_order():
    from flask import request
    data = None
    try:
        data = request.get_json(force=True)
    except Exception as e:
        return jsonify({'status':'badjson','error': str(e)}), 400
    if not data:
        return jsonify({'status':'no_data'}), 400
    try:
        fut = producer.send(Config.ORDERS_TOPIC, value=data)
        meta = fut.get(timeout=10)
        producer.flush()
        app.logger.info("Produced order %s -> topic=%s partition=%s offset=%s", data.get('order_id'), meta.topic, meta.partition, meta.offset)
        return jsonify({'status':'sent','data':data})
    except Exception as e:
        app.logger.exception("Failed producing order: %s", e)
        return jsonify({'status':'failed','error':str(e)}), 500