Compare commits

..

3 Commits

Author SHA1 Message Date
Alex Janousek
bcb3526fb5 Merge branch 'main' into fix-security-vulnerabilities 2026-01-21 09:25:02 -05:00
Alex Janousek
ab51cfb75e Fixing errors 2026-01-20 15:17:41 -05:00
Alex Janousek
5102d3c036 Should fix dependency errors 2026-01-20 15:17:20 -05:00
6 changed files with 1558 additions and 1533 deletions

View File

@@ -197,19 +197,15 @@ class AwsCloudwatchClient(Client):
def _get_receipts(self, log_group_name, start, end):
event_set = set()
try:
all_events = self._get_log(log_group_name, start, end)
for event in all_events:
try:
actual_event = self.event_to_db_format(event["message"])
event_set.add(json.dumps(actual_event))
except Exception:
current_app.logger.exception(
f"Could not format delivery receipt {event} for db insert"
)
except Exception as e:
current_app.logger.error(f"Could not find log group {log_group_name}")
raise e
all_events = self._get_log(log_group_name, start, end)
for event in all_events:
try:
actual_event = self.event_to_db_format(event["message"])
event_set.add(json.dumps(actual_event))
except Exception:
current_app.logger.exception(
f"Could not format delivery receipt {event} for db insert"
)
return event_set
def _aws_value_or_default(self, event, top_level, second_level):

View File

@@ -8,8 +8,7 @@ from os import getenv
import click
import flask
# from click_datetime import Datetime as click_dt
from click_datetime import Datetime as click_dt
from faker import Faker
from flask import current_app, json
from sqlalchemy import and_, select, text, update
@@ -60,8 +59,7 @@ from app.models import (
TemplateHistory,
User,
)
# from app.utils import utc_now
from app.utils import utc_now
from notifications_python_client.authentication import create_jwt_token
from notifications_utils.recipients import RecipientCSV
from notifications_utils.template import SMSMessageTemplate
@@ -262,55 +260,50 @@ def bulk_invite_user_to_service(file_name, service_id, user_id, auth_type, permi
file.close()
# TODO this is commented out because there is a conflict between
# the version of wheel we need to be on (0.46.2 or greater) and
# the click-datetime dependency, which insists wheel be 0.45.0 or lower.
# So need to rewrite this command to not use click-datetime, or see
# if the owners of click-datetime updated it (not as of 1/22/2026).
# @notify_command(name="archive-jobs-created-between-dates")
# @click.option(
# "-s",
# "--start_date",
# required=True,
# help="start date inclusive",
# type=click_dt(format="%Y-%m-%d"),
# )
# @click.option(
# "-e",
# "--end_date",
# required=True,
# help="end date inclusive",
# type=click_dt(format="%Y-%m-%d"),
# )
# def update_jobs_archived_flag(start_date, end_date):
# current_app.logger.info(
# f"Archiving jobs created between {start_date} to {end_date}"
# )
@notify_command(name="archive-jobs-created-between-dates")
@click.option(
"-s",
"--start_date",
required=True,
help="start date inclusive",
type=click_dt(format="%Y-%m-%d"),
)
@click.option(
"-e",
"--end_date",
required=True,
help="end date inclusive",
type=click_dt(format="%Y-%m-%d"),
)
def update_jobs_archived_flag(start_date, end_date):
current_app.logger.info(
f"Archiving jobs created between {start_date} to {end_date}"
)
# process_date = start_date
# total_updated = 0
process_date = start_date
total_updated = 0
# while process_date < end_date:
# start_time = utc_now()
# sql = """update
# jobs set archived = true
# where
# created_at >= (date :start + time '00:00:00')
# and created_at < (date :end + time '00:00:00')
# """
# result = db.session.execute(
# text(sql), {"start": process_date, "end": process_date + timedelta(days=1)}
# )
# db.session.commit()
# current_app.logger.info(
# f"jobs: --- Completed took {datetime.now() - start_time}ms. Archived "
# f"{result.rowcount} jobs for {process_date}"
# )
while process_date < end_date:
start_time = utc_now()
sql = """update
jobs set archived = true
where
created_at >= (date :start + time '00:00:00')
and created_at < (date :end + time '00:00:00')
"""
result = db.session.execute(
text(sql), {"start": process_date, "end": process_date + timedelta(days=1)}
)
db.session.commit()
current_app.logger.info(
f"jobs: --- Completed took {datetime.now() - start_time}ms. Archived "
f"{result.rowcount} jobs for {process_date}"
)
# process_date += timedelta(days=1)
process_date += timedelta(days=1)
# total_updated += result.rowcount
# current_app.logger.info(f"Total archived jobs = {total_updated}")
total_updated += result.rowcount
current_app.logger.info(f"Total archived jobs = {total_updated}")
@notify_command(name="populate-organizations-from-file")

View File

@@ -308,8 +308,8 @@ def dao_get_notification_count_for_service(*, service_id):
def dao_get_notification_count_for_service_message_ratio(service_id, current_year):
start_date = datetime(current_year - 1, 6, 16)
end_date = datetime(current_year, 6, 16)
start_date = datetime(current_year, 6, 16)
end_date = datetime(current_year + 1, 6, 16)
stmt1 = (
select(func.count())
.select_from(Notification)

2890
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,7 @@ certifi = ">=2022.12.7"
cffi = "==2.0.0"
charset-normalizer = "^3.4.4"
click = "==8.3.1"
click-datetime = "==0.4.0"
click-didyoumean = "==0.3.1"
click-plugins = "==1.1.1.2"
click-repl = "==0.3.0"
@@ -31,38 +32,38 @@ flask-bcrypt = "==1.0.1"
flask-migrate = "==4.1.0"
flask-redis = "==0.4.0"
flask-sqlalchemy = "^3.1.1"
gunicorn = {version = "==24.1.1", extras = ["gevent"]}
gunicorn = {version = "==23.0.0", extras = ["gevent"]}
iso8601 = "==2.1.0"
jsonschema = {version = "==4.26.0", extras = ["format"]}
lxml = "==6.0.2"
marshmallow = "^4.2.1"
marshmallow = "^4.2.0"
marshmallow-sqlalchemy = "^1.4.2"
newrelic = "^11.3.0"
packaging = "==26.0"
newrelic = "^11.2.0"
packaging = "==25.0"
poetry-dotenv-plugin = "==0.2.0"
psycopg2-binary = "==2.9.11"
pyjwt = "==2.10.1"
python-dotenv = "==1.2.1"
sqlalchemy = "==2.0.46"
sqlalchemy = "==2.0.45"
werkzeug = "^3.1.5"
faker = "^40.1.0"
async-timeout = "^5.0.1"
bleach = "^6.3.0"
geojson = "^3.2.0"
numpy = "^2.4.1"
numpy = "^2.4.0"
ordered-set = "^4.1.0"
phonenumbers = "^9.0.22"
python-json-logger = "^4.0.0"
regex = "^2026.1.15"
regex = "^2025.11.3"
shapely = "^2.1.2"
smartypants = "^2.0.1"
mistune = "^3.2.0"
blinker = "^1.9.0"
cryptography = "^46.0.3"
idna = "^3.11"
jmespath = "^1.1.0"
jmespath = "^1.0.1"
markupsafe = "^3.0.3"
pycparser = "^3.0"
pycparser = "^2.23"
python-dateutil = "^2.9.0.post0"
pyyaml = "^6.0.3"
s3transfer = "^0.13.1"
@@ -81,8 +82,6 @@ aiohttp = "^3.13.3"
pytest = "^9.0.2"
filelock = ">=3.20.3"
pyasn1 = ">=0.6.2"
jaraco-context = ">=6.1.0"
wheel = ">=0.46.2"
[tool.poetry.group.dev.dependencies]
@@ -94,11 +93,11 @@ exceptiongroup = "==1.3.1"
flake8 = "^7.3.0"
flake8-bugbear = "^25.11.29"
freezegun = "^1.5.5"
hypothesis = "^6.151.2"
hypothesis = "^6.150.2"
honcho = "*"
isort = "^7.0.0"
jinja2-cli = {version = "==1.0.0", extras = ["yaml"]}
moto = "==5.1.20"
moto = "==5.1.19"
pip-audit = "*"
pre-commit = "^4.5.1"
pytest = "^9.0.2"

View File

@@ -7,7 +7,7 @@ import pytest
from sqlalchemy import func, select
from app import db
from app.commands import ( # update_jobs_archived_flag,
from app.commands import (
_clear_templates_from_cache,
_update_template,
associate_services_to_organizations,
@@ -32,6 +32,7 @@ from app.commands import ( # update_jobs_archived_flag,
promote_user_to_platform_admin,
purge_csv_bucket,
purge_functional_test_data,
update_jobs_archived_flag,
update_templates,
)
from app.dao.inbound_numbers_dao import dao_get_available_inbound_numbers
@@ -45,19 +46,23 @@ from app.enums import (
TemplateType,
UserState,
)
from app.models import ( # Job,
from app.models import (
AnnualBilling,
Job,
Notification,
Organization,
Service,
Template,
User,
)
from tests.app.db import ( # create_job,; create_template,
from app.utils import utc_now
from tests.app.db import (
create_annual_billing,
create_job,
create_notification,
create_organization,
create_service,
create_template,
)
@@ -115,35 +120,35 @@ def test_purge_functional_test_data_bad_mobile(notify_db_session, notify_api):
assert user_count == 0
# def test_update_jobs_archived_flag(notify_db_session, notify_api):
# service = create_service()
def test_update_jobs_archived_flag(notify_db_session, notify_api):
service = create_service()
# sms_template = create_template(service=service, template_type=TemplateType.SMS)
# create_job(sms_template)
sms_template = create_template(service=service, template_type=TemplateType.SMS)
create_job(sms_template)
# right_now = utc_now()
# tomorrow = right_now + timedelta(days=1)
right_now = utc_now()
tomorrow = right_now + timedelta(days=1)
# right_now = right_now.strftime("%Y-%m-%d")
# tomorrow = tomorrow.strftime("%Y-%m-%d")
right_now = right_now.strftime("%Y-%m-%d")
tomorrow = tomorrow.strftime("%Y-%m-%d")
# stmt = select(Job).where(Job.archived is True)
# archived_jobs = db.session.execute(stmt).scalar() or 0
# assert archived_jobs == 0
stmt = select(Job).where(Job.archived is True)
archived_jobs = db.session.execute(stmt).scalar() or 0
assert archived_jobs == 0
# notify_api.test_cli_runner().invoke(
# update_jobs_archived_flag,
# [
# "-e",
# tomorrow,
# "-s",
# right_now,
# ],
# )
# jobs = db.session.execute(select(Job)).scalars().all()
# assert len(jobs) == 1
# for job in jobs:
# assert job.archived is True
notify_api.test_cli_runner().invoke(
update_jobs_archived_flag,
[
"-e",
tomorrow,
"-s",
right_now,
],
)
jobs = db.session.execute(select(Job)).scalars().all()
assert len(jobs) == 1
for job in jobs:
assert job.archived is True
def _get_organization_query_count():