Skip to content

Commit

Permalink
Merge pull request #7 from release-engineering/update-dependencies
Browse files Browse the repository at this point in the history
Update dependencies
  • Loading branch information
hluk authored Nov 10, 2023
2 parents 3868079 + 562b94f commit e82bdd3
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 52 deletions.
14 changes: 4 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# This will produce an image to be used in Openshift
# Build should be triggered from repo root like:
# docker build -f Dockerfile --tag <IMAGE_TAG>

FROM registry.fedoraproject.org/fedora-minimal:38

ARG GITHUB_SHA
Expand Down Expand Up @@ -32,18 +28,16 @@ ENV \
COPY . /opt/app-root/src/resultsdb_frontend/

RUN microdnf -y install \
findutils \
httpd \
mod_ssl \
python3-mod_wsgi \
python3-pip \
python3-cachelib \
python3-flask \
python3-iso8601 \
python3-resultsdb_api \
rpm-build \
&& pip3 install --upgrade --upgrade-strategy eager \
-r /opt/app-root/src/resultsdb_frontend/requirements.txt \
&& pip3 install --no-deps /opt/app-root/src/resultsdb_frontend \
&& microdnf -y remove python3-pip \
&& microdnf -y clean all \
&& pip3 install /opt/app-root/src/resultsdb_frontend \
&& install -d /usr/share/resultsdb_frontend/conf \
&& install -p -m 0644 \
/opt/app-root/src/resultsdb_frontend/conf/resultsdb_frontend.conf \
Expand Down
16 changes: 3 additions & 13 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
# This is a list of pypi packages to be installed into virtualenv. Alternatively,
# you can install these as RPMs instead of pypi packages. See the dependecies
# with:
# $ rpmspec -q --requires resultsdb.spec
# $ rpmspec -q --buildrequires resultsdb.spec

# A note for maintainers: Please keep this list in sync and in the same order
# as the spec file.

Flask >= 0.10.1
iso8601 >= 0.1.11
resultsdb_api >= 2.0
six >= 1.10.0
Flask >= 2.2.5
cachelib
iso8601 >= 0.1.11
requests
3 changes: 3 additions & 0 deletions resultsdb_frontend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class Config:
FEDMENU_URL = "https://apps.fedoraproject.org/fedmenu"
FEDMENU_DATA_URL = "https://apps.fedoraproject.org/js/data.js"

# Options for outbound HTTP requests made by python-requests
REQUESTS_TIMEOUT = (6.1, 15)


class ProductionConfig(Config):
DEBUG = False
Expand Down
36 changes: 7 additions & 29 deletions resultsdb_frontend/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,17 @@
request,
url_for,
)
from resultsdb_api import ResultsDBapi, ResultsDBapiException

from resultsdb_frontend import app
from resultsdb_frontend.resultsdb_api import ResultsDBapi

CACHE = SimpleCache()
CACHE_TIMEOUT = 60

RDB_API = None
RDB_API = ResultsDBapi(app.config["RDB_URL"])

main = Blueprint("main", __name__)


@app.before_first_request
def before_first_request():
global RDB_API
RDB_API = ResultsDBapi(app.config["RDB_URL"])


@main.route("/")
@main.route("/index")
def index():
Expand Down Expand Up @@ -80,41 +73,29 @@ def testcase_tokenizer():

@main.route("/groups")
def groups():
try:
groups = RDB_API.get_groups(**dict(request.args))
except ResultsDBapiException as e:
return str(e)
groups = RDB_API.get_groups(**dict(request.args))
return render_template("groups.html", groups=groups)


@main.route("/groups/<group_id>")
def group(group_id):
try:
group = RDB_API.get_group(group_id)
except ResultsDBapiException as e:
return str(e)
group = RDB_API.get_group(group_id)
groups = dict(prev=None, next=None, data=[group])
return render_template("groups.html", groups=groups)


@main.route("/results")
def results():
args = dict(request.args)
try:
results = RDB_API.get_results(**args)
except ResultsDBapiException as e:
return str(e)
results = RDB_API.get_results(**args)
for result in results["data"]:
result["groups"] = (len(result["groups"]), ",".join(result["groups"]))
return render_template("results.html", results=results)


@main.route("/results/<result_id>")
def result(result_id):
try:
result = RDB_API.get_result(id=result_id)
except ResultsDBapiException as e:
return str(e)
result = RDB_API.get_result(id=result_id)
try:
result["groups"] = (len(result["groups"]), ",".join(result["groups"]))
except KeyError:
Expand All @@ -131,9 +112,6 @@ def testcases():

@main.route("/testcases/<path:testcase_name>")
def testcase(testcase_name):
try:
tc = RDB_API.get_testcase(name=testcase_name)
except ResultsDBapiException as e:
return str(e)
tc = RDB_API.get_testcase(name=testcase_name)
tcs = dict(prev=None, next=None, data=[tc])
return render_template("testcases.html", testcases=tcs)
63 changes: 63 additions & 0 deletions resultsdb_frontend/requests_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import logging
from json import dumps

import requests
from flask import current_app, has_app_context
from requests.adapters import HTTPAdapter
from requests.exceptions import ConnectionError, ConnectTimeout, RetryError
from urllib3.exceptions import ProxyError, SSLError
from urllib3.util.retry import Retry

log = logging.getLogger(__name__)


class ErrorResponse(requests.Response):
def __init__(self, status_code, error_message, url):
super().__init__()
self.status_code = status_code
self._error_message = error_message
self.url = url
self.reason = error_message.encode()

@property
def content(self):
return dumps({"message": self._error_message}).encode()


class RequestsSession(requests.Session):
def request(self, *args, **kwargs): # pylint:disable=arguments-differ
log.debug("Request: args=%r, kwargs=%r", args, kwargs)

req_url = kwargs.get("url", args[1])

kwargs.setdefault("headers", {"Content-Type": "application/json"})
if has_app_context():
kwargs.setdefault("timeout", current_app.config["REQUESTS_TIMEOUT"])

try:
ret_val = super().request(*args, **kwargs)
except (ConnectTimeout, RetryError) as e:
ret_val = ErrorResponse(504, str(e), req_url)
except (ConnectionError, ProxyError, SSLError) as e:
ret_val = ErrorResponse(502, str(e), req_url)

log.debug("Request finished: %r", ret_val)
return ret_val


def get_requests_session():
"""Get http(s) session for request processing."""

session = RequestsSession()
retry = Retry(
total=3,
read=3,
connect=3,
backoff_factor=1,
status_forcelist=(500, 502, 503, 504),
)
adapter = HTTPAdapter(max_retries=retry)
session.mount("http://", adapter)
session.mount("https://", adapter)
session.headers["User-Agent"] = "resultsdb_frontend"
return session
38 changes: 38 additions & 0 deletions resultsdb_frontend/resultsdb_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from resultsdb_frontend.requests_session import get_requests_session


def _prepare_params(**kwargs):
return {
key: ",".join(str(v) for v in value) if isinstance(value, list) else str(value)
for key, value in kwargs.items()
if value is not None
}


class ResultsDBapi:
def __init__(self, api_url):
self.url = api_url.rstrip("/")
self.session = get_requests_session()

def _get(self, api, **kwargs):
r = self.session.get(f"{self.url}{api}", **kwargs)
r.raise_for_status()
return r.json()

def get_group(self, uuid):
return self._get(f"/groups/{uuid}")

def get_groups(self, **kwargs):
return self._get("/groups", params=_prepare_params(**kwargs))

def get_result(self, id):
return self._get(f"/results/{id}")

def get_results(self, **kwargs):
return self._get("/results", params=_prepare_params(**kwargs))

def get_testcase(self, name):
return self._get(f"/testcases/{name}")

def get_testcases(self, **kwargs):
return self._get("/testcases", params=_prepare_params(**kwargs))

0 comments on commit e82bdd3

Please sign in to comment.