Skip to content
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

Feat: metadata endpoint #512

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
12 changes: 12 additions & 0 deletions eligibility_server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from flask_restful import Api

from eligibility_server import __version__, db, sentry
from eligibility_server.db.models import Metadata
from eligibility_server.keypair import get_server_public_key
from eligibility_server.settings import Configuration
from eligibility_server.verify import Verify
Expand Down Expand Up @@ -53,6 +54,17 @@ def healthcheck():
return TextResponse("Healthy")


@app.route("/metadata")
def metadata():
app.logger.info("Request metadata")

md = Metadata.query.first()
return {
"app": {"version": __version__},
"db": {"timestamp": md.timestamp, "users": md.users, "eligibility": md.eligibility},
}


@app.route("/publickey")
def publickey():
app.logger.info("Request public key")
Expand Down
10 changes: 10 additions & 0 deletions eligibility_server/db/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
from eligibility_server.db import db


class Metadata(db.Model):
id = db.Column(db.Integer, primary_key=True)
timestamp = db.Column(db.String, unique=True, nullable=False)
users = db.Column(db.Integer, nullable=False)
eligibility = db.Column(db.PickleType, nullable=False)

def __repr__(self):
return f"<Metadata [{self.timestamp}]: {self.users} users, {len(self.eligibility)} type{'s' if len(self.eligibility) > 1 else ''}>" # noqa: E501


user_eligibility = db.Table(
"user_eligibility",
db.Column("user_id", db.Integer, db.ForeignKey("user.id"), primary_key=True),
Expand Down
22 changes: 19 additions & 3 deletions eligibility_server/db/setup.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import csv
from datetime import datetime, timezone
from tempfile import NamedTemporaryFile

import click
from flask import current_app
from sqlalchemy import inspect
from sqlalchemy import column, inspect
import requests

from eligibility_server.db import db
from eligibility_server.db.models import User, Eligibility
from eligibility_server.db.models import User, Eligibility, Metadata
from eligibility_server.settings import Configuration


Expand All @@ -29,9 +30,10 @@ def init_db_command():
click.echo("Creating table...")
db.create_all()
click.echo("Table created.")

import_users()

update_metadata()


def import_users():
"""
Expand Down Expand Up @@ -135,3 +137,17 @@ def drop_db_command():
click.echo("Database dropped.")
else:
click.echo("Database does not exist.")


def update_metadata():
Metadata.query.delete()

ts = datetime.now(tz=timezone.utc).isoformat(timespec="seconds")
users = User.query.count()
eligibility = [e.name for e in Eligibility.query.add_column(column("name"))]

metadata = Metadata(timestamp=ts, users=users, eligibility=eligibility)
db.session.add(metadata)
db.session.commit()

click.echo("Database metadata updated.")
6 changes: 5 additions & 1 deletion terraform/front_door.tf
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ resource "azurerm_cdn_frontdoor_firewall_policy" "main" {
match_condition {
match_variable = "RequestUri"
operator = "BeginsWith"
match_values = ["https://${azurerm_cdn_frontdoor_endpoint.main.host_name}:443/healthcheck", "https://${azurerm_cdn_frontdoor_endpoint.main.host_name}:443/static/"]
match_values = [
"https://${azurerm_cdn_frontdoor_endpoint.main.host_name}:443/healthcheck",
"https://${azurerm_cdn_frontdoor_endpoint.main.host_name}:443/metadata",
"https://${azurerm_cdn_frontdoor_endpoint.main.host_name}:443/static/"
]
}
}

Expand Down
11 changes: 10 additions & 1 deletion tests/db/test_setup.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
from datetime import datetime, timedelta, timezone

import pytest
from sqlalchemy import inspect

from eligibility_server.db import db
from eligibility_server.db.models import Eligibility, User
from eligibility_server.db.models import Eligibility, Metadata, User


@pytest.mark.usefixtures("flask")
def test_init_db_command(runner):
"""Assumes that IMPORT_FILE_PATH is data/server.csv."""
runner.invoke(args="drop-db")

start_time = datetime.now(tz=timezone.utc)
result = runner.invoke(args="init-db")

assert result.exit_code == 0

assert User.query.count() == 26
assert Eligibility.query.count() == 1
assert Metadata.query.count() == 1

metadata = Metadata.query.first()
assert metadata.users == User.query.count()
assert datetime.fromisoformat(metadata.timestamp) - start_time < timedelta(seconds=1)
assert metadata.eligibility == ["agency_card"]

user_with_one_eligibility = User.query.filter_by(sub="32587", name="Gonzales").first()
agency_card_type = Eligibility.query.filter_by(name="agency_card").first()
Expand Down
18 changes: 18 additions & 0 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import re

from eligibility_server import __version__
from eligibility_server.settings import APP_NAME
from eligibility_server.keypair import get_server_public_key

Expand All @@ -20,6 +21,23 @@ def test_healthcheck(client):
assert "Strict-Transport-Security" in response.headers


def test_metadata(client):
response = client.get("metadata")
assert response.status_code == 200
assert response.mimetype == "application/json"
assert "Strict-Transport-Security" in response.headers

data = response.json

assert "app" in data
assert data["app"]["version"] == __version__
assert "db" in data
assert isinstance(data["db"]["timestamp"], str)
assert isinstance(data["db"]["users"], int)
assert isinstance(data["db"]["eligibility"], list)
assert len(data["db"]["eligibility"]) > 0


def test_404(client):
response = client.get("/random")

Expand Down
Loading