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

Refactor API request functions with improved URL filtering and region… #232

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
81 changes: 48 additions & 33 deletions src/users.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import os
import pandas as pd
import streamlit as st
from datetime import datetime, timedelta
import os

from nowcasting_datamodel.connection import DatabaseConnection
from pvsite_datamodel.connection import DatabaseConnection as SitesDatabaseConnection

from nowcasting_datamodel.read.read_user import (
get_all_last_api_request,
get_api_requests_for_one_user,
)
from pvsite_datamodel.connection import DatabaseConnection as SitesDatabaseConnection
from pvsite_datamodel.read.user import get_all_last_api_request as get_all_last_api_request_sites
from pvsite_datamodel.read.user import (
get_api_requests_for_one_user as get_api_requests_for_one_user_sites,
Expand All @@ -17,26 +19,29 @@

region = os.getenv("REGION", "uk")

if region == "uk":
get_all_last_api_request_dict = {
# Simplified dictionary for API request functions based on region
get_all_last_api_request_dict = {
"uk": {
"National": get_all_last_api_request,
"Sites": get_all_last_api_request_sites,
}
else:
get_all_last_api_request_dict = {
"Sites": get_all_last_api_request_sites,
"Sites": get_all_last_api_request_sites
},
"default": {
"Sites": get_all_last_api_request_sites
}

}[region] if region == 'uk' else get_all_last_api_request_dict["default"]

def user_page():

"""
Streamlit page to display API user statistics and request details
"""
st.markdown(
f'<h1 style="color:#63BCAF;font-size:48px;">{"API Users Page"}</h1>',
unsafe_allow_html=True,
)

st.text("See which users have been using the API")

# Date range selection with reasonable defaults
start_time = st.sidebar.date_input(
"Start Date",
min_value=datetime.today() - timedelta(days=365),
Expand All @@ -50,71 +55,81 @@ def user_page():
value=datetime.today() + timedelta(days=1),
)

# get last call from the database
# Database connection setup
db_url = os.getenv("DB_URL", None)
db_url_sites = os.getenv("SITES_DB_URL", None)

# if both databases are available, let the user choose which one to use
# if none, show error
# Database selection logic
if region == 'uk':
national_or_sites = st.sidebar.selectbox("Select", ["National", "Sites"], index=0)
else:
national_or_sites = "Sites"

# depending on which database has been selected, we choose the
# 1. connection function
# 2. get_all_last_api_request function
# 3. get_api_requests_for_one_user function
if national_or_sites == "National":
connection = DatabaseConnection(url=db_url, echo=True)
get_api_requests_for_one_user_func = get_api_requests_for_one_user
else:
connection = SitesDatabaseConnection(url=db_url_sites, echo=True)
get_api_requests_for_one_user_func = get_api_requests_for_one_user_sites
# Choose appropriate connection and request functions
connection = (
DatabaseConnection(url=db_url, echo=True) if national_or_sites == "National"
else SitesDatabaseConnection(url=db_url_sites, echo=True)
)
get_api_requests_for_one_user_func = (
get_api_requests_for_one_user if national_or_sites == "National"
else get_api_requests_for_one_user_sites
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mind putting it back how it was, I find it easier to read?


# Get last API requests
last_request = get_last_request_by_user(_connection=connection, national_or_sites=national_or_sites)

# Process and display last requests
last_request = pd.DataFrame(last_request, columns=["email", "last API request"])
last_request = last_request.sort_values(by="last API request", ascending=False)
last_request.set_index("email", inplace=True)

st.write(last_request)

# add selectbox for users
email_selected = st.sidebar.selectbox("Select", last_request.index.tolist(), index=0)
# User selection
email_selected = st.sidebar.selectbox("Select User", last_request.index.tolist(), index=0)

# get all calls for selected user
# Fetch API requests for selected user
with connection.get_session() as session:
api_requests_sql = get_api_requests_for_one_user_func(
session=session, email=email_selected, start_datetime=start_time, end_datetime=end_time
session=session,
email=email_selected,
start_datetime=start_time,
end_datetime=end_time
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cant see any extra filtering in here? Perhaps this is in the other PR?

)

# Transform SQL requests to DataFrame
api_requests = [
(api_request_sql.created_utc, api_request_sql.url)
for api_request_sql in api_requests_sql
]

api_requests = pd.DataFrame(api_requests, columns=["created_utc", "url"])

# Plot individual API requests
fig = make_api_requests_plot(api_requests, email_selected, end_time, start_time)
st.plotly_chart(fig, theme="streamlit")

# add plot that shows amount of api calls per day
# Plot API request frequency
api_requests["created_utc"] = pd.to_datetime(api_requests["created_utc"])
api_requests["date"] = api_requests["created_utc"].dt.date
api_requests_days = api_requests[["date", "url"]].groupby("date").count()
api_requests_days.reset_index(inplace=True)

print(api_requests_days)

fig = make_api_frequency_requests_plot(api_requests_days, email_selected, end_time, start_time)
st.plotly_chart(fig, theme="streamlit")


@st.cache_data(ttl=60)
def get_last_request_by_user(_connection, national_or_sites:str):
"""Get the last request by user
"""
Get the last request by user with 1-minute cache

Args:
_connection: Database connection
national_or_sites: Source of API requests ('National' or 'Sites')

Note data is cached for one minute
Returns:
List of tuples with user email and last request timestamp
"""
_get_all_last_api_request_func = get_all_last_api_request_dict[national_or_sites]

Expand Down