import json import logging import os from functools import wraps import connexion import sentry_sdk from flask import redirect, flash, abort, Response from flask_assets import Environment from flask_cors import CORS from flask_executor import Executor from flask_mail import Mail from flask_marshmallow import Marshmallow from flask_migrate import Migrate from flask_sqlalchemy import SQLAlchemy from sentry_sdk.integrations.flask import FlaskIntegration from webassets import Bundle logging.basicConfig(level=logging.INFO) # API, fully defined in api.yml connexion_app = connexion.FlaskApp(__name__) app = connexion_app.app # Executor for long running tasks executor = Executor(app) # Configuration app.config.from_object('config.default') if "TESTING" in os.environ and os.environ["TESTING"] == "true": app.config.from_object('config.testing') app.config.from_pyfile('../config/testing.py') else: app.config.root_path = app.instance_path app.config.from_pyfile('config.py', silent=True) # Connexion Error handling def render_errors(exception): return Response(json.dumps({"error": str(exception)}), status=500, mimetype="application/json") connexion_app.add_error_handler(Exception, render_errors) # Mail settings mail = Mail(app) # Database db = SQLAlchemy(app) migrate = Migrate(app, db) ma = Marshmallow(app) # Asset management url_map = app.url_map try: for rule in url_map.iter_rules('static'): url_map._rules.remove(rule) except ValueError: # no static view was created yet pass app.add_url_rule( app.static_url_path + '/', endpoint='static', view_func=app.send_static_file) assets = Environment(app) assets.init_app(app) assets.url = app.static_url_path scss = Bundle( 'assets/scss/argon.scss', filters='pyscss', output='argon.css' ) assets.register('app_scss', scss) connexion_app.add_api('api.yml', base_path='/v1.0') from communicator import models from communicator import api from communicator import forms from communicator.models import Sample, Deposit from communicator.tables import SampleTable, InventoryDepositTable from communicator import scheduler # Must import this to cause the scheduler to kick off. # Convert list of allowed origins to list of regexes origins_re = [r"^https?:\/\/%s(.*)" % o.replace('.', r'\.') for o in app.config['CORS_ALLOW_ORIGINS']] cors = CORS(connexion_app.app, origins=origins_re) # Sentry error handling if app.config['ENABLE_SENTRY']: sentry_sdk.init( dsn="https://048a9b3ac72f476a8c77b910ad4d7f84@o401361.ingest.sentry.io/5454621", integrations=[FlaskIntegration()], traces_sample_rate=1.0 ) # HTML Pages BASE_HREF = app.config['APPLICATION_ROOT'].strip('/') def superuser(f): @wraps(f) def decorated_function(*args, **kwargs): from communicator.services.user_service import UserService if not UserService().is_valid_user(): flash("You do not have permission to view that page", "warning") logging.info("Permission Denied to user " + UserService().get_user_info()) abort(404) return f(*args, **kwargs) return decorated_function @app.route('/') def new_site(): return redirect(app.config.get('FRONT_END_URL') + "/dashboard") @app.route('/sso') def sso(): from communicator.services.user_service import UserService user = UserService().get_user_info() response = "" response += f"

Current User: {user.display_name} ({user.uid})

" return response @app.route('/debug-sentry') def trigger_error(): division_by_zero = 1 / 0 # Access tokens @app.cli.command() def globus_token(): from communicator.services.ivy_service import IvyService ivy_service = IvyService() ivy_service.get_access_token() @app.cli.command() def count_files_in_ivy(): from communicator.services.ivy_service import IvyService ivy_service = IvyService() count = ivy_service.get_file_count_from_globus() print(f"There are {count} files awaiting transfer") @app.cli.command() def transfer(): from communicator.services.ivy_service import IvyService ivy_service = IvyService() ivy_service.request_transfer()