Skip to content

web: rename app to flask_app #3435

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions src/auslib/web/admin/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,28 @@
connexion_app = connexion.App(__name__, debug=False, options={"swagger_ui": False})
connexion_app.add_api(spec, validator_map=validator_map, strict_validation=True)
connexion_app.add_api(path.join(current_dir, "swagger", "api_v2.yml"), base_path="/v2", strict_validation=True, validate_responses=True)
app = connexion_app.app
flask_app = connexion_app.app

create_dockerflow_endpoints(app)
create_dockerflow_endpoints(flask_app)


@app.before_request
@flask_app.before_request
def setup_request():
if request.full_path.startswith("/v2"):
from auslib.global_state import dbo

request.transaction = dbo.begin()

if request.method in ("POST", "PUT", "DELETE"):
username = verified_userinfo(request, app.config["AUTH_DOMAIN"], app.config["AUTH_AUDIENCE"])["email"]
username = verified_userinfo(request, flask_app.config["AUTH_DOMAIN"], flask_app.config["AUTH_AUDIENCE"])["email"]
if not username:
log.warning("Login Required")
return problem(401, "Unauthenticated", "Login Required")
# Machine to machine accounts are identified by uninformative clientIds
# In order to keep Balrog permissions more readable, we map them to
# more useful usernames, which are stored in the app config.
if "@" not in username:
username = app.config["M2M_ACCOUNT_MAPPING"].get(username, username)
username = flask_app.config["M2M_ACCOUNT_MAPPING"].get(username, username)
# Even if the user has provided a valid access token, we don't want to assume
# that person should be able to access Balrog (in case auth0 is not configured
# to be restrictive enough.
Expand All @@ -64,7 +64,7 @@ def setup_request():
request.username = username


@app.after_request
@flask_app.after_request
def complete_request(response):
if hasattr(request, "transaction"):
try:
Expand All @@ -78,27 +78,27 @@ def complete_request(response):
return response


@app.errorhandler(BlobValidationError)
@flask_app.errorhandler(BlobValidationError)
def blob_validation_error(error):
return problem(400, "Bad Request", "Invalid Blob", ext={"exception": error.errors})


@app.errorhandler(SignoffRequiredError)
@flask_app.errorhandler(SignoffRequiredError)
def signoff_required_error(error):
return problem(400, "Bad Request", "Signoff Required", ext={"exception": f"{error}"})


@app.errorhandler(ReadOnlyError)
@flask_app.errorhandler(ReadOnlyError)
def read_only_error(error):
return problem(400, "Bad Request", "Read only", ext={"exception": f"{error}"})


@app.errorhandler(PermissionDeniedError)
@flask_app.errorhandler(PermissionDeniedError)
def permission_denied_error(error):
return problem(403, "Forbidden", "Permission Denied", ext={"exception": f"{error}"})


@app.errorhandler(ValueError)
@flask_app.errorhandler(ValueError)
def value_error(error):
return problem(400, "Bad Request", "Unknown error", ext={"exception": f"{error}"})

Expand All @@ -107,12 +107,12 @@ def value_error(error):
# unicode characters (https://github.com/zalando/connexion/issues/604).
# To work around, we catch them and return a 400 (which is what Connexion
# would do if it didn't hit this error).
@app.errorhandler(UnicodeEncodeError)
@flask_app.errorhandler(UnicodeEncodeError)
def unicode(error):
return problem(400, "Unicode Error", "Connexion was unable to parse some unicode data correctly.")


@app.errorhandler(Exception)
@flask_app.errorhandler(Exception)
def ise(error):
capture_exception(error)
log.exception("Caught ISE 500 error: %r", error)
Expand All @@ -122,21 +122,21 @@ def ise(error):
return problem(500, "Internal Server Error", "Internal Server Error")


@app.after_request
@flask_app.after_request
def add_security_headers(response):
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["Strict-Transport-Security"] = app.config.get("STRICT_TRANSPORT_SECURITY", "max-age=31536000;")
response.headers["Strict-Transport-Security"] = flask_app.config.get("STRICT_TRANSPORT_SECURITY", "max-age=31536000;")
response.headers["Access-Control-Allow-Headers"] = "Authorization, Content-Type"
response.headers["Access-Control-Allow-Methods"] = "OPTIONS, GET, POST, PUT, DELETE"
if "*" in app.config["CORS_ORIGINS"]:
if "*" in flask_app.config["CORS_ORIGINS"]:
response.headers["Access-Control-Allow-Origin"] = "*"
elif "Origin" in request.headers and request.headers["Origin"] in app.config["CORS_ORIGINS"]:
elif "Origin" in request.headers and request.headers["Origin"] in flask_app.config["CORS_ORIGINS"]:
response.headers["Access-Control-Allow-Origin"] = request.headers["Origin"]
if re.match("^/ui/", request.path):
# This enables swagger-ui to dynamically fetch and
# load the swagger specification JSON file containing API definition and examples.
response.headers["X-Frame-Options"] = "SAMEORIGIN"
else:
response.headers["Content-Security-Policy"] = app.config.get("CONTENT_SECURITY_POLICY", "default-src 'none'; frame-ancestors 'none'")
response.headers["Content-Security-Policy"] = flask_app.config.get("CONTENT_SECURITY_POLICY", "default-src 'none'; frame-ancestors 'none'")
return response
34 changes: 17 additions & 17 deletions src/auslib/web/public/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
log = logging.getLogger(__name__)

connexion_app = connexion.App(__name__, specification_dir=".", options={"swagger_ui": False})
app = connexion_app.app
flask_app = connexion_app.app

current_dir = path.dirname(__file__)
web_dir = path.dirname(auslib.web.__file__)
Expand All @@ -32,24 +32,24 @@
connexion_app.add_api(spec, strict_validation=True)


@app.after_request
@flask_app.after_request
def apply_security_headers(response):
# There's no use cases for content served by Balrog to load additional content
# nor be embedded elsewhere, so we apply a strict Content Security Policy.
# We also need to set X-Content-Type-Options to nosniff for Firefox to obey this.
# See https://bugzilla.mozilla.org/show_bug.cgi?id=1332829#c4 for background.
response.headers["Strict-Transport-Security"] = app.config.get("STRICT_TRANSPORT_SECURITY", "max-age=31536000;")
response.headers["X-Content-Type-Options"] = app.config.get("CONTENT_TYPE_OPTIONS", "nosniff")
response.headers["Strict-Transport-Security"] = flask_app.config.get("STRICT_TRANSPORT_SECURITY", "max-age=31536000;")
response.headers["X-Content-Type-Options"] = flask_app.config.get("CONTENT_TYPE_OPTIONS", "nosniff")
if re.match("^/ui/", request.path):
# This enables swagger-ui to dynamically fetch and
# load the swagger specification JSON file containing API definition and examples.
response.headers["X-Frame-Options"] = "SAMEORIGIN"
else:
response.headers["Content-Security-Policy"] = app.config.get("CONTENT_SECURITY_POLICY", "default-src 'none'; frame-ancestors 'none'")
response.headers["Content-Security-Policy"] = flask_app.config.get("CONTENT_SECURITY_POLICY", "default-src 'none'; frame-ancestors 'none'")
return response


@app.errorhandler(404)
@flask_app.errorhandler(404)
def fourohfour(error):
if re.match("^/update", request.path):
"""We don't return 404s for AUS /update endpoints. Instead, we return empty XML files"""
Expand All @@ -63,12 +63,12 @@ def fourohfour(error):
# unicode characters (https://github.com/zalando/connexion/issues/604).
# To work around, we catch them and return a 400 (which is what Connexion
# would do if it didn't hit this error).
@app.errorhandler(UnicodeEncodeError)
@flask_app.errorhandler(UnicodeEncodeError)
def unicode(error):
return problem(400, "Unicode Error", "Connexion was unable to parse some unicode data correctly.")


@app.errorhandler(Exception)
@flask_app.errorhandler(Exception)
def generic(error):
"""Deals with any unhandled exceptions. If the exception is not a
BadDataError, it will be sent to Sentry, and a 400 will be returned,
Expand All @@ -92,7 +92,7 @@ def generic(error):
if isinstance(error, BadDataError):
return Response(status=400, mimetype="text/plain", response=html.escape(message, quote=False))

# Sentry doesn't handle exceptions for `@app.errorhandler(Exception)`
# Sentry doesn't handle exceptions for `@flask_app.errorhandler(Exception)`
# implicitly. If Sentry is not configured, the following call returns None.
capture_exception(error)

Expand All @@ -101,28 +101,28 @@ def generic(error):

# Keeping static files endpoints here due to an issue when returning response for static files.
# Similar issue: https://github.com/zalando/connexion/issues/401
@app.route("/robots.txt")
@flask_app.route("/robots.txt")
def robots():
return send_from_directory(app.static_folder, "robots.txt")
return send_from_directory(flask_app.static_folder, "robots.txt")


@app.route("/contribute.json")
@flask_app.route("/contribute.json")
def contributejson():
return send_from_directory(app.static_folder, "contribute.json")
return send_from_directory(flask_app.static_folder, "contribute.json")


@app.before_request
@flask_app.before_request
def set_cache_control():
# By default, we want a cache that can be shared across requests from
# different users ("public").
# and a maximum age of 90 seconds, to keep our TTL low.
# We bumped this from 60s -> 90s in November, 2016.
setattr(app, "cacheControl", app.config.get("CACHE_CONTROL", "public, max-age=90"))
setattr(flask_app, "cacheControl", flask_app.config.get("CACHE_CONTROL", "public, max-age=90"))


@app.route("/debug/api.yml")
@flask_app.route("/debug/api.yml")
def get_yaml():
if app.config.get("SWAGGER_DEBUG", False):
if flask_app.config.get("SWAGGER_DEBUG", False):
import yaml

app_spec = yaml.dump(spec)
Expand Down
2 changes: 1 addition & 1 deletion tests/admin/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from auslib.blobs.base import createBlob
from auslib.global_state import cache, dbo
from auslib.web.admin.base import app
from auslib.web.admin.base import flask_app as app

from ...fakes import FakeBlob, FakeGCSHistory

Expand Down
2 changes: 1 addition & 1 deletion tests/admin/views/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def my_userinfo(*args, **kwargs):

@pytest.fixture(scope="session")
def api():
from auslib.web.admin.base import app
from auslib.web.admin.base import flask_app as app

app.config["SECRET_KEY"] = "notasecret"
app.config["CORS_ORIGINS"] = "*"
Expand Down
2 changes: 1 addition & 1 deletion tests/blobs/test_apprelease.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from auslib.blobs.base import createBlob
from auslib.errors import BadDataError, BlobValidationError
from auslib.global_state import dbo
from auslib.web.public.base import app
from auslib.web.public.base import flask_app as app

from ..fakes import FakeGCSHistory

Expand Down
2 changes: 1 addition & 1 deletion tests/web/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from auslib.blobs.base import createBlob
from auslib.global_state import dbo
from auslib.web.public.base import app
from auslib.web.public.base import flask_app as app


def setUpModule():
Expand Down
2 changes: 1 addition & 1 deletion tests/web/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from auslib.blobs.base import createBlob
from auslib.errors import BadDataError
from auslib.global_state import cache, dbo
from auslib.web.public.base import app
from auslib.web.public.base import flask_app as app
from auslib.web.public.client import extract_query_version

mock_autograph_exception_count = 0
Expand Down
2 changes: 1 addition & 1 deletion tests/web/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from auslib.AUS import FORCE_FALLBACK_MAPPING, FORCE_MAIN_MAPPING
from auslib.blobs.base import createBlob
from auslib.global_state import dbo
from auslib.web.public.base import app
from auslib.web.public.base import flask_app as app


@pytest.fixture(scope="function")
Expand Down
2 changes: 1 addition & 1 deletion tests/web/test_unicode.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest

from auslib.global_state import dbo
from auslib.web.public.base import app
from auslib.web.public.base import flask_app as app


@pytest.mark.usefixtures("current_db_schema")
Expand Down