Skip to content

Commit

Permalink
Facilitate reporting NIH requested metric.
Browse files Browse the repository at this point in the history
  Max users per day in a month satisfies usage inquiry.
  • Loading branch information
grosscol committed Dec 21, 2023
1 parent 21e7642 commit ac0af03
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 8 deletions.
40 changes: 39 additions & 1 deletion bravo_api/blueprints/status/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ def usage_stats(db: pymongo.database.Database) -> dict:
"""
result = {"active": active_user_count(db.auth_log),
"new": new_user_count(db.users),
"total": total_user_count(db.users)}
"total": total_user_count(db.users),
"max_user_per_day": max_users_per_day(db.auth_log)}
return result


Expand Down Expand Up @@ -141,3 +142,40 @@ def active_user_count(collection: pymongo.collection.Collection) -> dict:

cursor = collection.aggregate(pipeline)
return([item for item in cursor])


def max_users_per_day(collection: pymongo.collection.Collection) -> dict:
"""
Given pymongo collection for the auth log, query for count of max users in a day per month.
Return array of dicts one per month. E.g.
[{'month': 10, 'max_daily_users': 10, 'year': 2023},
{'month': 9, 'max_daily_users': 20, 'year': 2023},
{'month': 8, 'max_daily_users': 25, 'year': 2023}]
"""
pipeline = [
{"$project": {
"year": {"$year": "$timestamp"},
"month": {"$month": "$timestamp"},
"day": {"$dayOfMonth": "$timestamp"},
"user_id": "$user_id"}},
{"$group": {"_id": {"day": "$day", "month": "$month", "year": "$year"},
"users": {"$addToSet": "$user_id"}}},
{"$project": {
"_id": 0,
"year": "$_id.year",
"month": "$_id.month",
"day": "$_id.day",
"active_users": {"$size": "$users"}}},
{"$group": {"_id": {"month": "$month", "year": "$year"},
"max_user_per_day": {"$max": "$active_users"}}},
{"$project": {
"_id": 0,
"year": "$_id.year",
"month": "$_id.month",
"max_user_per_day": 1}},
{"$sort": {"year": -1, "month": -1}}
]

cursor = collection.aggregate(pipeline)
return([item for item in cursor])
40 changes: 40 additions & 0 deletions tests/mongo_fixtures/auth_log.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,45 @@
{ "_id": { "$oid": "65258e0e61cb53bdab0bec7f" },
"user_id": "carol@example.com",
"timestamp": { "$date": 1696945614857 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000000" },
"user_id": "dan@example.com",
"timestamp": { "$date": 1698797400000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000001" },
"user_id": "ellis@example.com",
"timestamp": { "$date": 1698798000000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000002" },
"user_id": "fred@example.com",
"timestamp": { "$date": 1698798600000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000003" },
"user_id": "gigi@example.com",
"timestamp": { "$date": 1698799200000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000004" },
"user_id": "han@example.com",
"timestamp": { "$date": 1698799800000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000005" },
"user_id": "ivan@example.com",
"timestamp": { "$date": 1698800400000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000006" },
"user_id": "joan@example.com",
"timestamp": { "$date": 1698883800000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000007" },
"user_id": "kelly@example.com",
"timestamp": { "$date": 1698884400000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000008" },
"user_id": "liam@example.com",
"timestamp": { "$date": 1698885000000 }
},
{ "_id": { "$oid": "c0ffeec0ffeec0ffee000009" },
"user_id": "noah@example.com",
"timestamp": { "$date": 1698885600000 }
}
]
26 changes: 19 additions & 7 deletions tests/status/test_usage_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@
app = Flask('dummy')
app.register_blueprint(status.bp)

# Expected results from the mongodb fixtures in tests/mongo_fixtures/
ACTIVE_USERS_EXPECTED = [{'month': 10, 'active_users': 1, 'year': 2023},
# Expected results of mongo querying functions when using
# the mongodb fixtures in tests/mongo_fixtures/
ACTIVE_USERS_EXPECTED = [{'month': 11, 'active_users': 10, 'year': 2023},
{'month': 10, 'active_users': 1, 'year': 2023},
{'month': 9, 'active_users': 2, 'year': 2023},
{'month': 8, 'active_users': 3, 'year': 2023}]

MAX_DAILY_EXPECTED = [{'max_user_per_day': 6, 'month': 11, 'year': 2023},
{'max_user_per_day': 1, 'month': 10, 'year': 2023},
{'max_user_per_day': 1, 'month': 9, 'year': 2023},
{'max_user_per_day': 1, 'month': 8, 'year': 2023}]

NEW_USERS_EXPECTED = [{'month': 10, 'new_users': 1, 'year': 2023},
{'month': 9, 'new_users': 2, 'year': 2023},
{'month': 8, 'new_users': 1, 'year': 2023}]


TOTAL_USERS_EXPECTED = 4


Expand Down Expand Up @@ -46,8 +54,6 @@ def test_returns_version_when_defined():

def test_active_user_query(mongodb):
result = status.active_user_count(mongodb.auth_log)

assert len(result) == 3
assert(result == ACTIVE_USERS_EXPECTED)


Expand All @@ -66,10 +72,10 @@ def test_total_user_query(mongodb):
def test_usage_statistic(mongodb):
expected = {"active": ACTIVE_USERS_EXPECTED,
"new": NEW_USERS_EXPECTED,
"total": TOTAL_USERS_EXPECTED}
"total": TOTAL_USERS_EXPECTED,
"max_user_per_day": MAX_DAILY_EXPECTED}

result = status.usage_stats(mongodb)
assert(len(result.keys()) == 3)
assert(result == expected)


Expand All @@ -86,9 +92,15 @@ def test_usage_endpoint(mocker, mongodb):

expected = {"active": ACTIVE_USERS_EXPECTED,
"new": NEW_USERS_EXPECTED,
"total": TOTAL_USERS_EXPECTED}
"total": TOTAL_USERS_EXPECTED,
"max_user_per_day": MAX_DAILY_EXPECTED}

with app.test_client() as client:
resp = client.get('/usage')
content = resp.get_json()
assert(content == expected)


def test_max_users_per_day(mocker, mongodb):
result = status.max_users_per_day(mongodb.auth_log)
assert(result == MAX_DAILY_EXPECTED)

0 comments on commit ac0af03

Please sign in to comment.