|
|
import os |
|
|
import redis |
|
|
from rq import Queue |
|
|
from flask import Flask |
|
|
from flask_sqlalchemy import SQLAlchemy |
|
|
from flask_login import LoginManager |
|
|
from flask_migrate import Migrate |
|
|
from flask_cors import CORS |
|
|
from flask_wtf.csrf import CSRFProtect |
|
|
from config import Config |
|
|
from werkzeug.middleware.proxy_fix import ProxyFix |
|
|
|
|
|
db = SQLAlchemy() |
|
|
login_manager = LoginManager() |
|
|
login_manager.login_view = 'auth.login' |
|
|
login_manager.login_message_category = 'info' |
|
|
migrate = Migrate() |
|
|
csrf = CSRFProtect() |
|
|
|
|
|
|
|
|
def create_app(config_class=Config): |
|
|
app = Flask(__name__) |
|
|
app.config.from_object(config_class) |
|
|
|
|
|
|
|
|
if os.environ.get('RENDER') or os.environ.get('SPACE_ID'): |
|
|
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, |
|
|
x_proto=1, x_host=1, x_prefix=1) |
|
|
|
|
|
|
|
|
csrf.init_app(app) |
|
|
|
|
|
|
|
|
@csrf.exempt |
|
|
def csrf_exempt_api(): |
|
|
pass |
|
|
|
|
|
|
|
|
|
|
|
allowed_origins = [ |
|
|
"http://localhost:3000", |
|
|
"http://localhost:8081", |
|
|
"http://127.0.0.1:3000", |
|
|
"http://127.0.0.1:8081", |
|
|
"http://localhost:19006", |
|
|
"http://127.0.0.1:19006", |
|
|
"http://localhost:8082", |
|
|
"http://127.0.0.1:8082", |
|
|
] |
|
|
|
|
|
extra_origin = os.environ.get('FRONTEND_ORIGIN') |
|
|
if extra_origin and extra_origin not in allowed_origins: |
|
|
allowed_origins.append(extra_origin) |
|
|
|
|
|
|
|
|
CORS(app, |
|
|
resources={ |
|
|
r"/api/*": {"origins": "*"}, |
|
|
r"/auth/api/*": {"origins": "*"}, |
|
|
r"/health": {"origins": "*"} |
|
|
}, |
|
|
methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"], |
|
|
allow_headers=["Content-Type", "Authorization", "X-Requested-With"], |
|
|
supports_credentials=False, |
|
|
max_age=3600) |
|
|
|
|
|
|
|
|
app.config['DEV_MODE'] = os.environ.get( |
|
|
'DEV_MODE', 'False').lower() == 'true' |
|
|
if app.config['DEV_MODE']: |
|
|
print("\033[93m⚠️ Running in DEV_MODE - API calls will be stubbed!\033[0m") |
|
|
|
|
|
db.init_app(app) |
|
|
login_manager.init_app(app) |
|
|
migrate.init_app(app, db) |
|
|
|
|
|
|
|
|
try: |
|
|
redis_url = os.environ.get('REDIS_URL') |
|
|
if not redis_url: |
|
|
raise ValueError( |
|
|
"REDIS_URL not set, worker queue will not be available.") |
|
|
|
|
|
app.redis = redis.from_url(redis_url, ssl_cert_reqs=None) |
|
|
app.logger.info("Redis connection for RQ initialized successfully.") |
|
|
except Exception as e: |
|
|
app.logger.error(f"Failed to initialize Redis connection: {e}") |
|
|
app.redis = None |
|
|
|
|
|
|
|
|
from web_app.main_routes import bp as main_bp |
|
|
app.register_blueprint(main_bp) |
|
|
|
|
|
from web_app.auth_routes import bp as auth_bp |
|
|
app.register_blueprint(auth_bp, url_prefix='/auth') |
|
|
|
|
|
from web_app.api_endpoints import api_bp |
|
|
app.register_blueprint(api_bp) |
|
|
|
|
|
|
|
|
from web_app.assessment_routes import assessment_bp |
|
|
app.register_blueprint(assessment_bp) |
|
|
|
|
|
|
|
|
from web_app import models |
|
|
|
|
|
|
|
|
from web_app.google_oauth import google_bp, bp as google_auth_bp |
|
|
|
|
|
app.register_blueprint(google_bp, url_prefix="/login") |
|
|
|
|
|
app.register_blueprint(google_auth_bp, url_prefix="/auth") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return app |
|
|
|