From 6398f8e427a6035e040a93983ed24d116eaccee2 Mon Sep 17 00:00:00 2001 From: Rachel Tipton Date: Thu, 7 Sep 2023 14:18:43 +0200 Subject: [PATCH 1/5] add sites toolbox page add get user details function and styling --- src/main.py | 2 ++ src/sites_toolbox.py | 66 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/sites_toolbox.py diff --git a/src/main.py b/src/main.py index 12bd7af..42fb2a6 100644 --- a/src/main.py +++ b/src/main.py @@ -18,6 +18,7 @@ from status import status_page from forecast import forecast_page from pvsite_forecast import pvsite_forecast_page +from sites_toolbox import sites_toolbox_page st.get_option("theme.primaryColor") @@ -488,6 +489,7 @@ def metric_page(): "Status": status_page, "Forecast": forecast_page, "PV Site Forecast": pvsite_forecast_page, + "Sites Toolbox": sites_toolbox_page, } demo_name = st.sidebar.selectbox("Choose a page", page_names_to_funcs.keys()) diff --git a/src/sites_toolbox.py b/src/sites_toolbox.py new file mode 100644 index 0000000..b2d7715 --- /dev/null +++ b/src/sites_toolbox.py @@ -0,0 +1,66 @@ +import os +import streamlit as st +from datetime import datetime, timedelta, time, timezone +from pvsite_datamodel.connection import DatabaseConnection +from pvsite_datamodel.read import ( + get_all_sites, + get_user_by_email, +) +from get_data import ( + get_all_users, + get_all_site_groups, + update_user_site_group, + ) + + +import plotly.graph_objects as go + + +# get_user_details(): select user and show details for that user: Say how many sites the user has up the top +# Add company name (also to db) +# Allow users to view and search on the sites’ user ID (I.e. what the users call the site) + +def get_user_details(session, email): + """Get the user details from the database""" + user_details = get_user_by_email(session=session, + email=email) + user_site_group = user_details.site_group.site_group_name + user_site_count = len(user_details.site_group.sites) + user_sites = [str(site.site_uuid) for site in user_details.site_group.sites] + user_site_names = [str(site.client_site_id) for site in user_details.site_group.sites] + return user_sites, user_site_group, user_site_count, user_site_names + +def sites_toolbox_page(): + st.markdown( + f'

{"OCF Dashboard"}

', + unsafe_allow_html=True, + ) + st.markdown( + f'

{"Sites Toolbox"}

', + unsafe_allow_html=True, + ) + + url = "postgresql://main:7o5geKryjWVnVVfu@localhost:5434/pvsitedevelopment" + connection = DatabaseConnection(url=url, echo=True) + with connection.get_session() as session: + # get the user details + users = get_all_users(session=session) + user_list = [user.email for user in users] + sites = get_all_sites(session=session) + sites = [str(site.site_uuid)for site in sites] + site_groups = get_all_site_groups(session=session) + site_groups = [site_groups.site_group_name for site_groups in site_groups] + + st.markdown( + f'

{"Get User Details"}

', + unsafe_allow_html=True, + ) + email = st.selectbox("Enter email of user you want to know about.", user_list) + + if st.button("Get user details"): + user_sites, user_site_group, user_site_count, user_site_names = get_user_details(session=session, email=email) + st.write("User site group:", user_site_group) + st.write("User site count:", user_site_count) + st.write("User sites by site_uuid:", user_sites) + if st.button("Close user details"): + st.empty() \ No newline at end of file From 0f30f50a052e4508af3b397cd833f5be9a9d31b0 Mon Sep 17 00:00:00 2001 From: Rachel Tipton Date: Thu, 7 Sep 2023 17:22:32 +0200 Subject: [PATCH 2/5] add client id to site information in user section --- src/sites_toolbox.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/sites_toolbox.py b/src/sites_toolbox.py index b2d7715..14a2054 100644 --- a/src/sites_toolbox.py +++ b/src/sites_toolbox.py @@ -26,9 +26,8 @@ def get_user_details(session, email): email=email) user_site_group = user_details.site_group.site_group_name user_site_count = len(user_details.site_group.sites) - user_sites = [str(site.site_uuid) for site in user_details.site_group.sites] - user_site_names = [str(site.client_site_id) for site in user_details.site_group.sites] - return user_sites, user_site_group, user_site_count, user_site_names + user_sites= [{"site_uuid": str(site.site_uuid), "client_site_id": str(site.client_site_id)} for site in user_details.site_group.sites] + return user_sites, user_site_group, user_site_count def sites_toolbox_page(): st.markdown( @@ -58,9 +57,8 @@ def sites_toolbox_page(): email = st.selectbox("Enter email of user you want to know about.", user_list) if st.button("Get user details"): - user_sites, user_site_group, user_site_count, user_site_names = get_user_details(session=session, email=email) - st.write("User site group:", user_site_group) - st.write("User site count:", user_site_count) - st.write("User sites by site_uuid:", user_sites) + user_sites, user_site_group, user_site_count = get_user_details(session=session, email=email) + st.write("This user is part of the", user_site_group, "site group, which contains", user_site_count, "sites.") + st.write("Here are the site_uuids and client_site_ids for this group:", user_sites) if st.button("Close user details"): st.empty() \ No newline at end of file From ae294da3da2aa75e2b7d104ce2fadaba972935f5 Mon Sep 17 00:00:00 2001 From: Rachel Tipton Date: Thu, 7 Sep 2023 18:13:35 +0200 Subject: [PATCH 3/5] add initial test for get user details with errors --- tests/conftest.py | 43 +++++++++++++++++++++++++++++++++++++++++++ tests/test_data.py | 14 ++++++++++++++ tests/test_toolbox.py | 17 +++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 tests/conftest.py create mode 100644 tests/test_data.py create mode 100644 tests/test_toolbox.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..7d14866 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,43 @@ +import datetime as dt +import uuid +from typing import List + +import pytest +from sqlalchemy import create_engine +from sqlalchemy.orm import Session +from testcontainers.postgres import PostgresContainer + +from pvsite_datamodel import GenerationSQL, SiteSQL, StatusSQL +from pvsite_datamodel.sqlmodels import Base + +@pytest.fixture(scope="session") +def engine(): + """Database engine fixture.""" + with PostgresContainer("postgres:14.5") as postgres: + # TODO need to setup postgres database with docker + url = postgres.get_connection_url() + engine = create_engine(url) + Base.metadata.create_all(engine) + + yield engine + + +@pytest.fixture() +def db_session(engine): + """Return a sqlalchemy session, which tears down everything properly post-test.""" + connection = engine.connect() + # begin the nested transaction + transaction = connection.begin() + # use the connection with the already started transaction + + with Session(bind=connection) as session: + yield session + + session.close() + # roll back the broader transaction + transaction.rollback() + # put back the connection to the connection pool + connection.close() + session.flush() + + engine.dispose() \ No newline at end of file diff --git a/tests/test_data.py b/tests/test_data.py new file mode 100644 index 0000000..3bd8903 --- /dev/null +++ b/tests/test_data.py @@ -0,0 +1,14 @@ +"""tests for get_data.py""" +from get_data import get_all_users, get_all_site_groups, attach_site_group_to_user, attach_site_to_site_group + +#get all users +def test_get_all_users(db_session): + users = get_all_users(session=db_session) + # assert + assert len(users) == 0 + +# get all site groups + +# get all sites + +# update user site group \ No newline at end of file diff --git a/tests/test_toolbox.py b/tests/test_toolbox.py new file mode 100644 index 0000000..8d89c7c --- /dev/null +++ b/tests/test_toolbox.py @@ -0,0 +1,17 @@ +"""Test the toolbox functions""" +from sites_toolbox import get_user_details +from pvsite_datamodel.write.user_and_site import make_site, make_site_group, make_user + +def test_get_user_details(db_session): + """Test the get user details function""" + site_group = make_site_group(db_session=db_session) + site_1 = make_site(db_session=db_session, ml_id=1) + site_2 = make_site(db_session=db_session, ml_id=2) + site_group.sites.append(site_1) + site_group.sites.append(site_2) + + user = make_user(db_session=db_session, email="test_user@gmail.com", site_group=site_group) + user_sites, user_site_group = get_user_details(session=db_session, email="test_user@gmail.com") + + assert user_sites == [str(site_1.site_uuid), str(site_2.site_uuid)] + assert user_site_group == "test_site_group" From 77b8089c58ddc0b0b439e882bf4d850e2d8c9eea Mon Sep 17 00:00:00 2001 From: Rachel Tipton Date: Fri, 8 Sep 2023 09:20:44 +0200 Subject: [PATCH 4/5] update test to reflect changes in get_user_details() --- tests/test_sites_toolbox.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/test_sites_toolbox.py diff --git a/tests/test_sites_toolbox.py b/tests/test_sites_toolbox.py new file mode 100644 index 0000000..b0d76d8 --- /dev/null +++ b/tests/test_sites_toolbox.py @@ -0,0 +1,19 @@ +"""Test the toolbox functions""" +from sites_toolbox import get_user_details +from pvsite_datamodel.write.user_and_site import make_site, make_site_group, make_user + +def test_get_user_details(db_session): + """Test the get user details function""" + site_group = make_site_group(db_session=db_session) + site_1 = make_site(db_session=db_session, ml_id=1) + site_2 = make_site(db_session=db_session, ml_id=2) + site_group.sites.append(site_1) + site_group.sites.append(site_2) + + user = make_user(db_session=db_session, email="test_user@gmail.com", site_group=site_group) + user_sites, user_site_group, user_site_count = get_user_details(session=db_session, + email="test_user@gmail.com") + + assert user_sites == [{"site_uuid": str(site.site_uuid), "client_site_id": str(site.client_site_id)}for site in user.site_group.sites] + assert user_site_group == "test_site_group" + assert user_site_count == 2 From eb3e4ab7a0842f7372cb7bc8adf3e3d807f55f3d Mon Sep 17 00:00:00 2001 From: Rachel Tipton Date: Fri, 8 Sep 2023 15:30:04 +0200 Subject: [PATCH 5/5] small changes --- src/sites_toolbox.py | 98 +++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/src/sites_toolbox.py b/src/sites_toolbox.py index 14a2054..0160668 100644 --- a/src/sites_toolbox.py +++ b/src/sites_toolbox.py @@ -1,3 +1,4 @@ +"""This module contains the sites toolbox for the OCF dashboard""" import os import streamlit as st from datetime import datetime, timedelta, time, timezone @@ -7,58 +8,71 @@ get_user_by_email, ) from get_data import ( - get_all_users, - get_all_site_groups, - update_user_site_group, - ) + get_all_users, + get_all_site_groups, + update_user_site_group, +) import plotly.graph_objects as go -# get_user_details(): select user and show details for that user: Say how many sites the user has up the top -# Add company name (also to db) -# Allow users to view and search on the sites’ user ID (I.e. what the users call the site) - def get_user_details(session, email): - """Get the user details from the database""" - user_details = get_user_by_email(session=session, - email=email) - user_site_group = user_details.site_group.site_group_name - user_site_count = len(user_details.site_group.sites) - user_sites= [{"site_uuid": str(site.site_uuid), "client_site_id": str(site.client_site_id)} for site in user_details.site_group.sites] - return user_sites, user_site_group, user_site_count + """Get the user details from the database""" + user_details = get_user_by_email(session=session, email=email) + user_site_group = user_details.site_group.site_group_name + user_site_count = len(user_details.site_group.sites) + user_sites = [ + {"site_uuid": str(site.site_uuid), "client_site_id": str(site.client_site_id)} + for site in user_details.site_group.sites + ] + return user_sites, user_site_group, user_site_count + def sites_toolbox_page(): - st.markdown( - f'

{"OCF Dashboard"}

', - unsafe_allow_html=True, + st.markdown( + f'

{"OCF Dashboard"}

', + unsafe_allow_html=True, ) - st.markdown( - f'

{"Sites Toolbox"}

', - unsafe_allow_html=True, + st.markdown( + f'

{"Sites Toolbox"}

', + unsafe_allow_html=True, ) - url = "postgresql://main:7o5geKryjWVnVVfu@localhost:5434/pvsitedevelopment" - connection = DatabaseConnection(url=url, echo=True) - with connection.get_session() as session: - # get the user details - users = get_all_users(session=session) - user_list = [user.email for user in users] - sites = get_all_sites(session=session) - sites = [str(site.site_uuid)for site in sites] - site_groups = get_all_site_groups(session=session) - site_groups = [site_groups.site_group_name for site_groups in site_groups] + url = os.environ["SITES_DB_URL"] - st.markdown( - f'

{"Get User Details"}

', - unsafe_allow_html=True, + connection = DatabaseConnection( + url=url, + echo=True, ) - email = st.selectbox("Enter email of user you want to know about.", user_list) - - if st.button("Get user details"): - user_sites, user_site_group, user_site_count = get_user_details(session=session, email=email) - st.write("This user is part of the", user_site_group, "site group, which contains", user_site_count, "sites.") - st.write("Here are the site_uuids and client_site_ids for this group:", user_sites) - if st.button("Close user details"): - st.empty() \ No newline at end of file + with connection.get_session() as session: + # get the user details + users = get_all_users(session=session) + user_list = [user.email for user in users] + sites = get_all_sites(session=session) + # site_uuids = [str(site.site_uuid) for site in sites] + site_groups = get_all_site_groups(session=session) + # site_group_name = [site_groups.site_group_name for site_groups in site_groups] + + st.markdown( + f'

{"Get User Details"}

', + unsafe_allow_html=True, + ) + email = st.selectbox("Enter email of user you want to know about.", user_list) + + if st.button("Get user details"): + user_sites, user_site_group, user_site_count = get_user_details( + session=session, email=email + ) + st.write( + "This user is part of the", + user_site_group, + "site group, which contains", + user_site_count, + "sites.", + ) + st.write( + "Here are the site_uuids and client_site_ids for this group:", user_sites + ) + if st.button("Close user details"): + st.empty()