from flask import Flask, render_template, request, redirect, url_for, jsonify, session from flask_sqlalchemy import SQLAlchemy from flask_socketio import SocketIO, emit import uuid from datetime import datetime, timezone import requests import time import threading from cryptography.fernet import Fernet import os import random STOCK_START_TIME = None STOCK_START_PRICE_AN = 1.27 STOCK_START_PRICE_ASTRAFOODS = 2.50 STOCK_START_PRICE_NOVASWEETS = 0.85 def get_an_price(): if STOCK_START_TIME is None: return STOCK_START_PRICE_AN elapsed = time.time() - STOCK_START_TIME steps = int(elapsed / 0.5) if steps == 0: return STOCK_START_PRICE_AN random.seed(int(STOCK_START_TIME)) price = STOCK_START_PRICE_AN for i in range(steps): volatility = random.uniform(-0.15, 0.15) trend = 0.000014 change = volatility + trend price += change if price < 0.01: price = 0.01 return round(price, 2) def get_astrafoods_price(): if STOCK_START_TIME is None: return STOCK_START_PRICE_ASTRAFOODS elapsed = time.time() - STOCK_START_TIME steps = int(elapsed / 0.5) if steps == 0: return STOCK_START_PRICE_ASTRAFOODS random.seed(int(STOCK_START_TIME) + 1000) price = STOCK_START_PRICE_ASTRAFOODS for i in range(steps): volatility = random.uniform(-0.02, 0.02) trend = 0.0000028 change = volatility + trend price += change if price < 0.01: price = 0.01 return round(price, 2) def get_novasweets_price(): if STOCK_START_TIME is None: return STOCK_START_PRICE_NOVASWEETS elapsed = time.time() - STOCK_START_TIME steps = int(elapsed / 0.5) if steps == 0: return STOCK_START_PRICE_NOVASWEETS random.seed(int(STOCK_START_TIME) + 2000) price = STOCK_START_PRICE_NOVASWEETS for i in range(steps): volatility = random.uniform(-0.20, 0.20) trend = 0.000021 change = volatility + trend price += change if price < 0.01: price = 0.01 return round(price, 2) app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///astrapay.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SECRET_KEY'] = 'your-secret-key-here' db = SQLAlchemy(app) socketio = SocketIO(app, cors_allowed_origins="*", async_mode='threading') def background_stock_updates(): while True: if STOCK_START_TIME is not None: price_an = get_an_price() price_astrafoods = get_astrafoods_price() price_novasweets = get_novasweets_price() socketio.emit('stock_update', { 'an': price_an, 'astrafoods': price_astrafoods, 'novasweets': price_novasweets }) time.sleep(0.5) def get_encryption_key(): key_file = 'encryption.key' if os.path.exists(key_file): with open(key_file, 'rb') as f: return f.read() else: key = Fernet.generate_key() with open(key_file, 'wb') as f: f.write(key) return key ENCRYPTION_KEY = get_encryption_key() cipher_suite = Fernet(ENCRYPTION_KEY) def encrypt_value(value): if isinstance(value, str): value = value.encode() return cipher_suite.encrypt(value).decode() def decrypt_value(encrypted_value): return cipher_suite.decrypt(encrypted_value.encode()).decode() _CACHED_CONNECT_SID = None _CACHED_BANK_BASE_URL = None _CACHED_REFERER = None def get_cached_credentials(): global _CACHED_CONNECT_SID, _CACHED_BANK_BASE_URL, _CACHED_REFERER if _CACHED_CONNECT_SID is None: _CACHED_CONNECT_SID = decrypt_value(ENCRYPTED_CONNECT_SID) _CACHED_BANK_BASE_URL = decrypt_value(ENCRYPTED_BANK_BASE_URL) _CACHED_REFERER = decrypt_value(ENCRYPTED_REFERER) if not _CACHED_CONNECT_SID: raise ValueError("connect.sid cookie is empty or invalid") return _CACHED_CONNECT_SID, _CACHED_BANK_BASE_URL, _CACHED_REFERER def calculate_fee(amount): if amount < 10: return 0 elif amount < 25: return 1 elif amount < 100: return 3 elif amount < 250: return 5 elif amount < 300: return 6 elif amount < 500: return 8 elif amount < 1000: return 10 elif amount < 2500: return 22 elif amount < 3000: return 24 elif amount < 5000: return 24 else: return 50 def calculate_claim_amounts(amount): fee = 1 if amount <= 100 else 2 fee_percent = fee / amount if amount > 0 else 0 send_amount = amount + fee claim_amount = amount return send_amount, claim_amount, fee_percent def generate_unique_code(): max_attempts = 100 for _ in range(max_attempts): code = str(uuid.uuid4()) if not PaymentLink.query.filter_by(id=code).first() and not ClaimLink.query.filter_by(id=code).first(): return code return str(uuid.uuid4()) ENCRYPTED_CONNECT_SID = encrypt_value('s%3AVwn7Au3uVKswFJZouKPlHXNq09DbJeRE.MoiRQgUAUd5rXCx%2BTjkIjFl6pzMtMLG716lrWgeMGSE') ENCRYPTED_API_URL = encrypt_value('https://astra-bank-moh1812.replit.app/api/transactions') ENCRYPTED_REFERER = encrypt_value('https://astra-bank-moh1812.replit.app/') ENCRYPTED_ETAG = encrypt_value('W/"6e3-L0zHI4rHMa4nHmyewyA/4y+lL6c"') ENCRYPTED_BANK_BASE_URL = encrypt_value('https://astra-bank-moh1812.replit.app') class PaymentLink(db.Model): id = db.Column(db.String(36), primary_key=True) amount = db.Column(db.Integer, nullable=False) description = db.Column(db.String(500), nullable=False) recipient_email = db.Column(db.String(255), nullable=True) created_at = db.Column(db.DateTime, default=datetime.utcnow) paid = db.Column(db.Boolean, default=False) def __repr__(self): return f'' class ClaimLink(db.Model): id = db.Column(db.String(36), primary_key=True) amount = db.Column(db.Integer, nullable=False) send_amount = db.Column(db.Integer, nullable=False) claim_amount = db.Column(db.Integer, nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) verified = db.Column(db.Boolean, default=False) claimed = db.Column(db.Boolean, default=False) claimer_email = db.Column(db.String(255), nullable=True) def __repr__(self): return f'' def get_transactions(): url = decrypt_value(ENCRYPTED_API_URL) referer = decrypt_value(ENCRYPTED_REFERER) connect_sid = decrypt_value(ENCRYPTED_CONNECT_SID) headers = { 'accept': '*/*', 'accept-language': 'en-US,en;q=0.9', 'cache-control': 'no-cache', 'pragma': 'no-cache', 'priority': 'u=1, i', 'referer': referer, 'sec-ch-ua': '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', 'sec-ch-ua-mobile': '?1', 'sec-ch-ua-platform': '"Android"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Mobile Safari/537.36' } cookies = { 'connect.sid': connect_sid } try: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Fetching transactions from API: {url}") response = requests.get(url, headers=headers, cookies=cookies, timeout=10) print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] API Response Status: {response.status_code}") transactions = response.json() print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] API Response: Received {len(transactions) if isinstance(transactions, list) else 'N/A'} transactions") if isinstance(transactions, list) and len(transactions) > 0: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Latest transaction: ID={transactions[0].get('id')}, Amount={transactions[0].get('amount')}, Type={transactions[0].get('transactionType')}, CreatedAt={transactions[0].get('createdAt')}") return transactions except Exception as e: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Error fetching transactions: {e}") return [] def check_for_payment(amount): try: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Checking for payment: Amount={amount}") transactions = get_transactions() current_time = time.time() one_minute_ago = current_time - 60 print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Checking transactions from last minute (since {datetime.fromtimestamp(one_minute_ago).strftime('%Y-%m-%d %H:%M:%S')})") matching_transactions = [] for transaction in transactions: if (transaction.get('amount') == amount and transaction.get('transactionType') == 'received'): matching_transactions.append(transaction) print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Found matching transaction: ID={transaction.get('id')}, Amount={transaction.get('amount')}, CreatedAt={transaction.get('createdAt')}") created_at_str = transaction.get('createdAt') if created_at_str: try: iso_str = created_at_str.replace('Z', '+00:00') created_at = datetime.fromisoformat(iso_str) created_at_timestamp = created_at.timestamp() age_seconds = current_time - created_at_timestamp print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Transaction age: {age_seconds:.2f} seconds") if created_at_timestamp >= one_minute_ago: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] ✓ Payment found! Transaction ID: {transaction.get('id')}") return transaction else: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Transaction too old (>{age_seconds:.2f}s), skipping") except Exception as e: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Error parsing timestamp: {e}") continue if matching_transactions: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Found {len(matching_transactions)} matching transaction(s) but none within last minute") else: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] No matching transactions found for amount {amount}") return None except Exception as e: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Error checking for payment: {e}") return None def get_user_uuid(email): try: base_url = decrypt_value(ENCRYPTED_BANK_BASE_URL) connect_sid = decrypt_value(ENCRYPTED_CONNECT_SID) referer = decrypt_value(ENCRYPTED_REFERER) url = f"{base_url}/api/user" params = {'email': email} headers = { 'accept': '*/*', 'accept-language': 'en-US,en;q=0.9', 'cache-control': 'no-cache', 'priority': 'u=1, i', 'referer': referer, 'sec-ch-ua': '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', 'sec-ch-ua-mobile': '?1', 'sec-ch-ua-platform': '"Android"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Mobile Safari/537.36' } cookies = { 'connect.sid': connect_sid } response = requests.get(url, params=params, headers=headers, cookies=cookies, timeout=10) if response.status_code == 200: return response.text.strip() else: print(f"Error getting user UUID: {response.status_code} - {response.text}") return None except Exception as e: print(f"Error getting user UUID: {e}") return None def send_money(to_user_id, amount, description): try: base_url = decrypt_value(ENCRYPTED_BANK_BASE_URL) connect_sid = decrypt_value(ENCRYPTED_CONNECT_SID) referer = decrypt_value(ENCRYPTED_REFERER) url = f"{base_url}/api/send-money" headers = { 'accept': '*/*', 'accept-language': 'en-US,en;q=0.9', 'cache-control': 'no-cache', 'content-type': 'application/json', 'origin': base_url, 'pragma': 'no-cache', 'priority': 'u=1, i', 'referer': referer, 'sec-ch-ua': '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', 'sec-ch-ua-mobile': '?1', 'sec-ch-ua-platform': '"Android"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Mobile Safari/537.36' } cookies = { 'connect.sid': connect_sid } data = { 'toUserId': to_user_id, 'amount': amount, 'description': description } response = requests.post(url, json=data, headers=headers, cookies=cookies, timeout=10) if response.status_code == 200: return True, response.json() else: print(f"Error sending money: {response.status_code} - {response.text}") return False, response.text except Exception as e: print(f"Error sending money: {e}") return False, str(e) def get_friend_requests(): max_retries = 3 for attempt in range(max_retries): try: connect_sid, base_url, referer = get_cached_credentials() if not connect_sid: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] ERROR: connect.sid cookie is empty!") return [] url = f"{base_url}/api/friends" headers = { 'accept': '*/*', 'accept-language': 'en-US,en;q=0.9', 'cache-control': 'no-cache', 'pragma': 'no-cache', 'priority': 'u=1, i', 'referer': referer, 'sec-ch-ua': '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', 'sec-ch-ua-mobile': '?1', 'sec-ch-ua-platform': '"Android"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Mobile Safari/537.36', 'Cookie': f'connect.sid={connect_sid}' } cookies = { 'connect.sid': connect_sid } response = requests.get(url, headers=headers, cookies=cookies, timeout=10) if response.status_code == 200: return response.json() elif response.status_code == 401: if attempt < max_retries - 1: time.sleep((attempt + 1) * 2) continue else: return [] else: return [] except Exception as e: if attempt < max_retries - 1: time.sleep((attempt + 1) * 2) continue else: return [] return [] def accept_friend_request(friend_id): max_retries = 3 for attempt in range(max_retries): try: connect_sid, base_url, referer = get_cached_credentials() if not connect_sid: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] ERROR: connect.sid cookie is empty!") return False url = f"{base_url}/api/friends/{friend_id}/accept" headers = { 'accept': '*/*', 'accept-language': 'en-US,en;q=0.9', 'cache-control': 'no-cache', 'content-length': '0', 'origin': base_url, 'pragma': 'no-cache', 'priority': 'u=1, i', 'referer': referer, 'sec-ch-ua': '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', 'sec-ch-ua-mobile': '?1', 'sec-ch-ua-platform': '"Android"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Mobile Safari/537.36', 'Cookie': f'connect.sid={connect_sid}' } cookies = { 'connect.sid': connect_sid } response = requests.post(url, headers=headers, cookies=cookies, timeout=10) if response.status_code == 200: return True elif response.status_code == 401: if attempt < max_retries - 1: time.sleep((attempt + 1) * 2) continue else: return False else: return False except Exception as e: if attempt < max_retries - 1: time.sleep((attempt + 1) * 2) continue else: return False return False def background_friend_request_checker(): while True: try: friends = get_friend_requests() if isinstance(friends, list): for friend in friends: if isinstance(friend, dict): friendship_status = friend.get('friendshipStatus') if friendship_status == 'pending': email = friend.get('email', 'unknown') friend_id = friend.get('id') print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Pending friend request from: {email}") if friend_id: if accept_friend_request(friend_id): print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] ✓ Accepted friend request from {email}") else: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] ✗ Failed to accept friend request from {email}") except Exception as e: pass time.sleep(10) with app.app_context(): db.create_all() @app.route('/') def home(): return render_template('home.html') @app.route('/create-payment-link', methods=['POST']) def create_payment_link(): try: data = request.get_json() if not data or 'amount' not in data or 'description' not in data or 'recipient_email' not in data: return jsonify({'error': 'Missing required fields'}), 400 amount = data['amount'] description = data['description'] recipient_email = data.get('recipient_email', '').strip() if not isinstance(amount, int) or amount <= 0: return jsonify({'error': 'Invalid amount'}), 400 if amount > 10000: return jsonify({'error': 'Maximum 10,000 Astras per payment link'}), 400 if not description or len(description.strip()) == 0: return jsonify({'error': 'Description cannot be empty'}), 400 if not recipient_email: return jsonify({'error': 'Recipient email is required'}), 400 payment_link = PaymentLink( id=generate_unique_code(), amount=amount, description=description.strip(), recipient_email=recipient_email ) db.session.add(payment_link) db.session.commit() payment_url = url_for('view_payment', payment_id=payment_link.id, _external=True) return jsonify({ 'success': True, 'payment_id': payment_link.id, 'payment_url': payment_url }) except Exception as e: db.session.rollback() return jsonify({'error': str(e)}), 500 @app.route('/init-payment-check/') def init_payment_check(payment_id): try: payment_link = PaymentLink.query.get_or_404(payment_id) fee = calculate_fee(payment_link.amount) total_amount = payment_link.amount + fee return jsonify({ 'amount': payment_link.amount, 'fee': fee, 'total_amount': total_amount }) except Exception as e: return jsonify({'error': str(e)}), 500 @app.route('/check-payment/') def check_payment_status(payment_id): try: payment_link = PaymentLink.query.get_or_404(payment_id) fee = calculate_fee(payment_link.amount) total_amount = payment_link.amount + fee payment_transaction = check_for_payment(total_amount) if payment_transaction: return jsonify({ 'payment_received': True, 'transaction': { 'id': payment_transaction.get('id'), 'amount': payment_transaction.get('amount'), 'from_email': payment_transaction.get('counterpartEmail'), 'description': payment_transaction.get('description') } }) else: return jsonify({'payment_received': False}) except Exception as e: return jsonify({'error': str(e)}), 500 @app.route('/pay/', methods=['POST']) def process_payment(payment_id): try: payment_link = PaymentLink.query.get_or_404(payment_id) if payment_link.paid: return jsonify({'error': 'Payment already completed'}), 400 payment_link.paid = True db.session.commit() if payment_link.recipient_email: try: fee = calculate_fee(payment_link.amount) amount_to_send = payment_link.amount - fee user_uuid = get_user_uuid(payment_link.recipient_email) if user_uuid: success, result = send_money( to_user_id=user_uuid, amount=amount_to_send, description=payment_link.description ) if success: print(f"Successfully sent {amount_to_send} Astras to {payment_link.recipient_email} (fee: {fee})") else: print(f"Failed to send money: {result}") else: print(f"Could not find user UUID for email: {payment_link.recipient_email}") except Exception as e: print(f"Error processing recipient payment: {e}") return jsonify({'success': True, 'message': 'Payment confirmed successfully'}) except Exception as e: db.session.rollback() return jsonify({'error': str(e)}), 500 @app.route('/check-link/') def check_link(link_id): try: payment_link = PaymentLink.query.filter_by(id=link_id).first() if payment_link: return jsonify({ 'exists': True, 'type': 'payment' }) claim_link = ClaimLink.query.filter_by(id=link_id).first() if claim_link: return jsonify({ 'exists': True, 'type': 'claim' }) return jsonify({ 'exists': False }), 404 except Exception as e: return jsonify({'error': str(e)}), 500 @app.route('/pay/') def view_payment(payment_id): payment_link = PaymentLink.query.get_or_404(payment_id) fee = calculate_fee(payment_link.amount) total_amount = payment_link.amount + fee return render_template('payment.html', amount=payment_link.amount, fee=fee, total_amount=total_amount, description=payment_link.description, paid=payment_link.paid, payment_id=payment_link.id, recipient_email=payment_link.recipient_email) @app.route('/bank') def bank(): return render_template('bank.html') @app.route('/create-claim-link', methods=['POST']) def create_claim_link(): try: data = request.get_json() if not data or 'amount' not in data: return jsonify({'error': 'Missing required fields'}), 400 amount = data['amount'] if not isinstance(amount, int) or amount <= 0: return jsonify({'error': 'Invalid amount'}), 400 if amount > 10000: return jsonify({'error': 'Maximum 10,000 Astras per claim link'}), 400 send_amount, claim_amount, fee_percent = calculate_claim_amounts(amount) claim_link = ClaimLink( id=generate_unique_code(), amount=amount, send_amount=send_amount, claim_amount=claim_amount ) db.session.add(claim_link) db.session.commit() claim_url = url_for('view_claim', claim_id=claim_link.id, _external=True) return jsonify({ 'success': True, 'claim_id': claim_link.id, 'claim_url': claim_url, 'send_amount': send_amount, 'claim_amount': claim_amount }) except Exception as e: db.session.rollback() return jsonify({'error': str(e)}), 500 @app.route('/claim/') def view_claim(claim_id): claim_link = ClaimLink.query.get_or_404(claim_id) fee = 1 if claim_link.amount <= 100 else 2 fee_percent = int((fee / claim_link.amount) * 100) if claim_link.amount > 0 else 0 return render_template('claim.html', amount=claim_link.amount, send_amount=claim_link.send_amount, claim_amount=claim_link.claim_amount, fee=fee, fee_percent=int(fee_percent), verified=claim_link.verified, claimed=claim_link.claimed, claimer_email=claim_link.claimer_email, claim_id=claim_link.id) @app.route('/check-claim-verification/') def check_claim_verification(claim_id): try: claim_link = ClaimLink.query.get_or_404(claim_id) if claim_link.verified: return jsonify({'verified': True}) payment_transaction = check_for_payment(claim_link.send_amount) if payment_transaction: claim_link.verified = True db.session.commit() print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Claim link {claim_id} verified") return jsonify({'verified': True}) else: return jsonify({'verified': False}) except Exception as e: print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Error checking claim verification: {e}") return jsonify({'error': str(e)}), 500 @app.route('/claim/', methods=['POST']) def process_claim(claim_id): try: data = request.get_json() claim_link = ClaimLink.query.get_or_404(claim_id) if claim_link.claimed: return jsonify({'error': 'Claim link already used'}), 400 if not claim_link.verified: return jsonify({'error': 'Claim link not verified yet'}), 400 if not data or 'email' not in data: return jsonify({'error': 'Email is required'}), 400 email = data['email'].strip() if not email: return jsonify({'error': 'Email cannot be empty'}), 400 user_uuid = get_user_uuid(email) if not user_uuid: return jsonify({'error': 'User not found'}), 404 success, result = send_money( to_user_id=user_uuid, amount=claim_link.claim_amount, description=f'Claim link {claim_id}' ) if success: claim_link.claimed = True claim_link.claimer_email = email db.session.commit() return jsonify({'success': True, 'message': f'{claim_link.claim_amount} Astras sent to {email}'}) else: return jsonify({'error': f'Failed to send money: {result}'}), 500 except Exception as e: db.session.rollback() return jsonify({'error': str(e)}), 500 @socketio.on('connect') def handle_connect(): pass if __name__ == '__main__': stock_thread = threading.Thread(target=background_stock_updates, daemon=True) stock_thread.start() friend_thread = threading.Thread(target=background_friend_request_checker, daemon=True) friend_thread.start() socketio.run(app, debug=True, host='0.0.0.0', port=7860, allow_unsafe_werkzeug=True)