Skip to content

Commit

Permalink
Localize notification_utils to the API
Browse files Browse the repository at this point in the history
This changeset pulls in all of the notification_utils code directly into the API and removes it as an external dependency.  We are doing this to cut down on operational maintenance of the project and will begin removing parts of it no longer needed for the API.

Signed-off-by: Carlo Costino <carlo.costino@gsa.gov>
  • Loading branch information
ccostino committed May 16, 2024
1 parent 4cdf8b2 commit 99edc88
Show file tree
Hide file tree
Showing 129 changed files with 49,913 additions and 263 deletions.
9 changes: 1 addition & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ test: ## Run tests and create coverage report
poetry run black .
poetry run flake8 .
poetry run isort --check-only ./app ./tests
poetry run coverage run --omit=*/notifications_utils/* -m pytest --maxfail=10
poetry run coverage run -m pytest --maxfail=10
poetry run coverage report -m --fail-under=95
poetry run coverage html -d .coverage_cache

Expand All @@ -90,13 +90,6 @@ py-lock: ## Syncs dependencies and updates lock file without performing recursiv
poetry lock --no-update
poetry install --sync

.PHONY: update-utils
update-utils: ## Forces Poetry to pull the latest changes from the notifications-utils repo; requires that you commit the changes to poetry.lock!
poetry update notifications-utils
@echo
@echo !!! PLEASE MAKE SURE TO COMMIT AND PUSH THE UPDATED poetry.lock FILE !!!
@echo

.PHONY: freeze-requirements
freeze-requirements: ## Pin all requirements including sub dependencies into requirements.txt
poetry export --without-hashes --format=requirements.txt > requirements.txt
Expand Down
17 changes: 0 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,23 +431,6 @@ In either situation, once you are finished and have verified the dependency
changes are working, please be sure to commit both the `pyproject.toml` and
`poetry.lock` files.

### Keeping the notification-utils Dependency Up-to-Date

The `notifications-utils` dependency references the other repository we have at
https://github.com/GSA/notifications-utils - this dependency requires a bit of
extra legwork to ensure it stays up-to-date.

Whenever a PR is merged in the `notifications-utils` repository, we need to make
sure the changes are pulled in here and committed to this repository as well.
You can do this by going through these steps:

- Make sure your local `main` branch is up-to-date
- Create a new branch to work in
- Run `make update-utils`
- Commit the updated `poetry.lock` file and push the changes
- Make a new PR with the change
- Have the PR get reviewed and merged

## Known Installation Issues

### Python Installation Errors
Expand Down
8 changes: 4 additions & 4 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
from flask_marshmallow import Marshmallow
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
from notifications_utils import logging, request_helper
from notifications_utils.clients.encryption.encryption_client import Encryption
from notifications_utils.clients.redis.redis_client import RedisClient
from notifications_utils.clients.zendesk.zendesk_client import ZendeskClient
from sqlalchemy import event
from werkzeug.exceptions import HTTPException as WerkzeugHTTPException
from werkzeug.local import LocalProxy
Expand All @@ -26,6 +22,10 @@
from app.clients.email.aws_ses import AwsSesClient
from app.clients.email.aws_ses_stub import AwsSesStubClient
from app.clients.sms.aws_sns import AwsSnsClient
from notifications_utils import logging, request_helper
from notifications_utils.clients.encryption.encryption_client import Encryption
from notifications_utils.clients.redis.redis_client import RedisClient
from notifications_utils.clients.zendesk.zendesk_client import ZendeskClient


class NotifyCelery(Celery):
Expand Down
2 changes: 1 addition & 1 deletion app/authentication/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
TokenExpiredError,
TokenIssuerError,
)
from notifications_utils import request_helper
from sqlalchemy.orm.exc import NoResultFound

from app.serialised_models import SerialisedService
from notifications_utils import request_helper

# stvnrlly - this is silly, but bandit has a multiline string bug (https://github.com/PyCQA/bandit/issues/658)
# and flake8 wants a multiline quote here. TODO: check on bug status and restore sanity once possible
Expand Down
2 changes: 1 addition & 1 deletion app/celery/scheduled_tasks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from datetime import datetime, timedelta

from flask import current_app
from notifications_utils.clients.zendesk.zendesk_client import NotifySupportTicket
from sqlalchemy import between
from sqlalchemy.exc import SQLAlchemyError

Expand Down Expand Up @@ -32,6 +31,7 @@
from app.enums import JobStatus, NotificationType
from app.models import Job
from app.notifications.process_notifications import send_notification_to_queue
from notifications_utils.clients.zendesk.zendesk_client import NotifySupportTicket

MAX_NOTIFICATION_FAILS = 10000

Expand Down
2 changes: 1 addition & 1 deletion app/celery/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from datetime import datetime

from flask import current_app
from notifications_utils.recipients import RecipientCSV
from requests import HTTPError, RequestException, request
from sqlalchemy.exc import IntegrityError, SQLAlchemyError

Expand All @@ -27,6 +26,7 @@
from app.service.utils import service_allowed_to_send_to
from app.utils import DATETIME_FORMAT
from app.v2.errors import TotalRequestsError
from notifications_utils.recipients import RecipientCSV


@notify_celery.task(name="process-job")
Expand Down
4 changes: 2 additions & 2 deletions app/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
from faker import Faker
from flask import current_app, json
from notifications_python_client.authentication import create_jwt_token
from notifications_utils.recipients import RecipientCSV
from notifications_utils.template import SMSMessageTemplate
from sqlalchemy import and_, text
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound
Expand Down Expand Up @@ -64,6 +62,8 @@
User,
)
from app.utils import get_midnight_in_utc
from notifications_utils.recipients import RecipientCSV
from notifications_utils.template import SMSMessageTemplate
from tests.app.db import (
create_job,
create_notification,
Expand Down
2 changes: 1 addition & 1 deletion app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from datetime import timedelta
from os import getenv, path

import notifications_utils
from celery.schedules import crontab
from kombu import Exchange, Queue

import notifications_utils
from app.cloudfoundry_config import cloud_config


Expand Down
12 changes: 6 additions & 6 deletions app/dao/notifications_dao.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
from datetime import datetime, timedelta

from flask import current_app
from notifications_utils.international_billing_rates import INTERNATIONAL_BILLING_RATES
from notifications_utils.recipients import (
InvalidEmailError,
try_validate_and_format_phone_number,
validate_and_format_email_address,
)
from sqlalchemy import asc, desc, or_, select, text, union
from sqlalchemy.orm import joinedload
from sqlalchemy.orm.exc import NoResultFound
Expand All @@ -23,6 +17,12 @@
get_midnight_in_utc,
midnight_n_days_ago,
)
from notifications_utils.international_billing_rates import INTERNATIONAL_BILLING_RATES
from notifications_utils.recipients import (
InvalidEmailError,
try_validate_and_format_phone_number,
validate_and_format_email_address,
)


def dao_get_last_date_template_was_used(template_id, service_id):
Expand Down
10 changes: 5 additions & 5 deletions app/delivery/send_to_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@

from cachetools import TTLCache, cached
from flask import current_app
from notifications_utils.template import (
HTMLEmailTemplate,
PlainTextEmailTemplate,
SMSMessageTemplate,
)

from app import create_uuid, db, notification_provider_clients, redis_store
from app.aws.s3 import get_personalisation_from_s3, get_phone_number_from_s3
Expand All @@ -19,6 +14,11 @@
from app.enums import BrandType, KeyType, NotificationStatus, NotificationType
from app.exceptions import NotificationTechnicalFailureException
from app.serialised_models import SerialisedService, SerialisedTemplate
from notifications_utils.template import (
HTMLEmailTemplate,
PlainTextEmailTemplate,
SMSMessageTemplate,
)


def send_sms_to_provider(notification):
Expand Down
2 changes: 1 addition & 1 deletion app/errors.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from flask import current_app, json, jsonify
from jsonschema import ValidationError as JsonSchemaValidationError
from marshmallow import ValidationError
from notifications_utils.recipients import InvalidEmailError
from sqlalchemy.exc import DataError
from sqlalchemy.orm.exc import NoResultFound

from app.authentication.auth import AuthError
from app.exceptions import ArchiveValidationError
from notifications_utils.recipients import InvalidEmailError


class VirusScanError(Exception):
Expand Down
18 changes: 9 additions & 9 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@
import uuid

from flask import current_app, url_for
from notifications_utils.clients.encryption.encryption_client import EncryptionError
from notifications_utils.recipients import (
InvalidEmailError,
InvalidPhoneError,
try_validate_and_format_phone_number,
validate_email_address,
validate_phone_number,
)
from notifications_utils.template import PlainTextEmailTemplate, SMSMessageTemplate
from sqlalchemy import CheckConstraint, Index, UniqueConstraint
from sqlalchemy.dialects.postgresql import JSON, JSONB, UUID
from sqlalchemy.ext.associationproxy import association_proxy
Expand Down Expand Up @@ -46,6 +37,15 @@
DATETIME_FORMAT_NO_TIMEZONE,
get_dt_string_or_none,
)
from notifications_utils.clients.encryption.encryption_client import EncryptionError
from notifications_utils.recipients import (
InvalidEmailError,
InvalidPhoneError,
try_validate_and_format_phone_number,
validate_email_address,
validate_phone_number,
)
from notifications_utils.template import PlainTextEmailTemplate, SMSMessageTemplate


def filter_null_value_fields(obj):
Expand Down
12 changes: 6 additions & 6 deletions app/notifications/process_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@
from datetime import datetime

from flask import current_app
from notifications_utils.recipients import (
format_email_address,
get_international_phone_info,
validate_and_format_phone_number,
)
from notifications_utils.template import PlainTextEmailTemplate, SMSMessageTemplate

from app import redis_store
from app.celery import provider_tasks
Expand All @@ -19,6 +13,12 @@
from app.enums import KeyType, NotificationStatus, NotificationType
from app.models import Notification
from app.v2.errors import BadRequestError
from notifications_utils.recipients import (
format_email_address,
get_international_phone_info,
validate_and_format_phone_number,
)
from notifications_utils.template import PlainTextEmailTemplate, SMSMessageTemplate


def create_content_for_notification(template, personalisation):
Expand Down
2 changes: 1 addition & 1 deletion app/notifications/receive_notifications.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from flask import Blueprint, current_app, json, jsonify, request
from notifications_utils.recipients import try_validate_and_format_phone_number

from app.celery import tasks
from app.config import QueueNames
Expand All @@ -9,6 +8,7 @@
from app.errors import InvalidRequest, register_errors
from app.models import InboundSms
from app.notifications.sns_handlers import sns_notification_handler
from notifications_utils.recipients import try_validate_and_format_phone_number

receive_notifications_blueprint = Blueprint("receive_notifications", __name__)
register_errors(receive_notifications_blueprint)
Expand Down
2 changes: 1 addition & 1 deletion app/notifications/rest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from flask import Blueprint, current_app, jsonify, request
from notifications_utils import SMS_CHAR_COUNT_LIMIT

from app import api_user, authenticated_service
from app.aws.s3 import get_personalisation_from_s3, get_phone_number_from_s3
Expand All @@ -26,6 +25,7 @@
)
from app.service.utils import service_allowed_to_send_to
from app.utils import get_public_notify_type_text, pagination_links
from notifications_utils import SMS_CHAR_COUNT_LIMIT

notifications = Blueprint("notifications", __name__)

Expand Down
20 changes: 10 additions & 10 deletions app/notifications/validators.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
from flask import current_app
from notifications_utils import SMS_CHAR_COUNT_LIMIT
from notifications_utils.clients.redis import (
rate_limit_cache_key,
total_limit_cache_key,
)
from notifications_utils.recipients import (
get_international_phone_info,
validate_and_format_email_address,
validate_and_format_phone_number,
)
from sqlalchemy.orm.exc import NoResultFound

from app import redis_store
Expand All @@ -22,6 +12,16 @@
from app.service.utils import service_allowed_to_send_to
from app.utils import get_public_notify_type_text
from app.v2.errors import BadRequestError, RateLimitError, TotalRequestsError
from notifications_utils import SMS_CHAR_COUNT_LIMIT
from notifications_utils.clients.redis import (
rate_limit_cache_key,
total_limit_cache_key,
)
from notifications_utils.recipients import (
get_international_phone_info,
validate_and_format_email_address,
validate_and_format_phone_number,
)


def check_service_over_api_rate_limit(service, api_key):
Expand Down
2 changes: 1 addition & 1 deletion app/organization/invite_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from flask import Blueprint, current_app, jsonify, request
from itsdangerous import BadData, SignatureExpired
from notifications_utils.url_safe_token import check_token, generate_token

from app import redis_store
from app.config import QueueNames
Expand All @@ -28,6 +27,7 @@
post_update_invited_org_user_status_schema,
)
from app.schema_validation import validate
from notifications_utils.url_safe_token import check_token, generate_token

organization_invite_blueprint = Blueprint("organization_invite", __name__)

Expand Down
1 change: 1 addition & 0 deletions app/schema_validation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from iso8601 import ParseError, iso8601
from jsonschema import Draft7Validator, FormatChecker, ValidationError

from notifications_utils.recipients import (
InvalidEmailError,
InvalidPhoneError,
Expand Down
12 changes: 6 additions & 6 deletions app/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
validates_schema,
)
from marshmallow_sqlalchemy import auto_field, field_for

from app import ma, models
from app.dao.permissions_dao import permission_dao
from app.enums import ServicePermissionType, TemplateType
from app.models import ServicePermission
from app.utils import DATETIME_FORMAT_NO_TIMEZONE, get_template_instance
from notifications_utils.recipients import (
InvalidEmailError,
InvalidPhoneError,
Expand All @@ -22,12 +28,6 @@
validate_phone_number,
)

from app import ma, models
from app.dao.permissions_dao import permission_dao
from app.enums import ServicePermissionType, TemplateType
from app.models import ServicePermission
from app.utils import DATETIME_FORMAT_NO_TIMEZONE, get_template_instance


def _validate_positive_number(value, msg="Not a positive integer"):
try:
Expand Down
10 changes: 5 additions & 5 deletions app/serialised_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

import cachetools
from flask import current_app
from notifications_utils.clients.redis import RequestCache
from notifications_utils.serialised_model import (
SerialisedModel,
SerialisedModelCollection,
)
from werkzeug.utils import cached_property

from app import db, redis_store
from app.dao.api_key_dao import get_model_api_keys
from app.dao.services_dao import dao_fetch_service_by_id
from notifications_utils.clients.redis import RequestCache
from notifications_utils.serialised_model import (
SerialisedModel,
SerialisedModelCollection,
)

caches = defaultdict(partial(cachetools.TTLCache, maxsize=1024, ttl=2))
locks = defaultdict(RLock)
Expand Down

0 comments on commit 99edc88

Please sign in to comment.