Skip to content

Commit

Permalink
Add statistics on the homepage (#20)
Browse files Browse the repository at this point in the history
cache this part of the homepage for 30s using caching lib.
Be careful to not cache full page, otherwise username will not be updated when login

Bug: T204157
  • Loading branch information
framawiki authored May 27, 2023
1 parent bd08713 commit 2b0a967
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 8 deletions.
10 changes: 9 additions & 1 deletion quarry/default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ worker_concurrency: 24 # Since all tasks are IO bound
task_acks_late: True # Tasks are idempotent!
task_track_started: True
worker_prefetch_multiplier: 1 # Tasks can run for a long time
# Just query the quarry database itself.

# Run queries against a fake wiki database
REPLICA_DOMAIN: ''
REPLICA_HOST: 'mywiki'
REPLICA_DB: 'mywiki_p'
Expand All @@ -29,3 +30,10 @@ QUERY_TIME_LIMIT: 60 # 1 minute
QUERY_RESULTS_PER_PAGE: 50
KILLER_LOG_PATH: 'killer.log'
MAINTENANCE_MSG: 'This is your local development environment.'

# https://flask-caching.readthedocs.io/en/latest/#configuring-flask-caching
CACHE_TYPE: 'RedisCache'
CACHE_DEFAULT_TIMEOUT: 30
CACHE_REDIS_HOST: 'redis'
CACHE_REDIS_PORT: 6379
CACHE_REDIS_DB: 1
11 changes: 10 additions & 1 deletion quarry/web/app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os

from flask import current_app, Flask, render_template, g
from flask_caching import Cache
import yaml

from .connections import Connections
Expand All @@ -15,6 +16,8 @@
from .run import run_blueprint
from .api import api_blueprint
from .webhelpers import templatehelpers
from .models.user import User
from .models.queryrun import QueryRun

__dir__ = os.path.dirname(__file__)

Expand Down Expand Up @@ -68,10 +71,16 @@ def create_app(test_config=None):
app.teardown_request(kill_context)

metrics_init_app(app)
cache = Cache(app) # noqa: F841, this var is used in landing.html template

@app.route("/")
def index():
return render_template("landing.html", user=get_user())
return render_template(
"landing.html",
user=get_user(),
stats_count_users=global_conn.session.query(User).count(),
stats_count_runs=global_conn.session.query(QueryRun).count(),
)

return app

Expand Down
5 changes: 4 additions & 1 deletion quarry/web/templates/landing.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
<div class="jumbotron">
<div class="container">
<h1>Quarry</h1>
<h3>Run SQL queries against Wikipedia &amp; other databases from your browser!</h3>
<p>Run SQL queries against Wikipedia &amp; other databases from your browser!</p>
{% cache 30 %}
<p>{{ stats_count_users }} users have run {{ stats_count_runs }} queries so far</p>
{% endcache %}
<br />
<div>
{% if user %}
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ xlsxwriter==3.0.3
importlib-metadata==4.6.3
zipp==3.5.0
typing-extensions==3.10.0.0
flask_caching==2.0.2
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"DB_NAME": "Quarry",
"QUERY_RESULTS_PER_PAGE": 3,
"OUTPUT_PATH_TEMPLATE": "%s_%s_%s",
"CACHE_TYPE": "SimpleCache",
}


Expand Down
42 changes: 37 additions & 5 deletions tests/test_app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
def test_frontpage(client, redisdb):
rv = client.get("/")
print(rv.__dict__)
assert rv.status_code == 200
assert rv.data
from mock_alchemy.mocking import UnifiedAlchemyMagicMock

from quarry.web.models.query import Query
from quarry.web.models.queryrevision import QueryRevision
from quarry.web.models.queryrun import QueryRun
from quarry.web.models.user import User


class TestApp:
def test_frontpage(self, mocker, client):
self.db_session = UnifiedAlchemyMagicMock()

# Homepage shows statistics
for user_id in range(5):
self.db_session.add(User(id=user_id))
for query_id in range(3):
self.db_session.add(Query(id=query_id, user_id=user_id))
for queryrev_id in range(3):
self.db_session.add(
QueryRevision(id=queryrev_id, query_id=query_id)
)
for queryrun_id in range(3):
self.db_session.add(
QueryRun(id=queryrun_id, query_rev_id=queryrev_id)
)

mocker.patch(
"quarry.web.connections.Connections.session",
new_callable=mocker.PropertyMock(return_value=self.db_session),
)

response = client.get("/")
print(response.__dict__)
assert response.status_code == 200
assert response.data
assert "5 users" in response.data.decode("utf8")
assert f"{5 * 3 * 3 * 3} queries" in response.data.decode("utf8")

0 comments on commit 2b0a967

Please sign in to comment.