- Adds rule N804 (invalid-first-argument-name-for-class-method) to linter config
- Remove hangul filler character from rendered emails
- bump all libs in requirements_for_test_common.in
- Don’t copy config when bumping utils version
- Fix validating supported international country codes for phone numbers without a leading "+" that look a bit like UK numbers
- Adds public utility method to check if a phonenumber is international (with correct handling for OFCOM TV numbers)
- Updates PhoneNumber.get_international_phone_info to return the correct info for OFCOM TV numbers
- BREAKING CHANGE: All standalone functions for validating, normalising and formatting phone numbers has been removed from notifications_utils/recipient_validation/phone_number.py, and are replaced and encapsualated entirely with a single
PhoneNumber
class. All code that relies on validation, normalisation or fomratting of a phone number must be re-written to use instances ofPhoneNumber
instead.
- Allow leading empty columns in CSV files
- Change second argument of
formatters.strip_all_whitespace
(this argument is not used in other apps)
- Use github API rather than fetching from their CDN in version_tools
- Change version_tools to a package that uses importlib to grab common reqs/config, rather than fetching common files from github. This repo's usage of those common files are now symlinks to the sources of truth found within notification_utils/version_tools/
- Raise an exception if we cant fetch remote github files in version_tools.py
requirements_for_test_common.txt
is nowrequirements_for_test_common.in
. Apps should freeze this into a local requirements file for fully reproducible dependencies
- Bug fix: applies minor version bump of PhoneNumbers to v8.13.48 to apply a fix to the UG metadata which was causing validation to fail in error
- logging: slightly redesign filters behaviour to allow log-call-supplied request_id, span_id, user_id, service_id to be used if they are not available by normal means. Supply these manually for the streaming-response-closed log message.
- logging: don't use current_app in _log_response_closed
- Removes
template.EmailPreviewTemplate
(only used in admin app)
- logging: don't calculate_content_length() for after_request logs of streaming responses - this caused attempted streaming responses to be eagerly consumed, negating the point of streaming responses. Instead emit the after_request log when status code and header is returned and a separate log message when a streaming response is closed.
- Reintroduce changes to
AntivirusClient
andZendeskClient
from 83.0.0
- Adds
asset_fingerprinter.AssetFingerprinter
to replace the versions duplicated across our frontend apps
- Add
EventletTimeoutMiddleware
- BREAKING CHANGE: The
Phonenumber
class now accepts a flagallow_landline
, which defaults to False. This changes the previous default behaviour, allowing landlines.
- Removes
SerialisedModel.ALLOWED_PROPERTIES
in favour of annotations syntax
- Reverts 84.1.0
- The Zendesk client takes a new optional argument,
user_created_at
which populates a new field on the Notify Zendesk form if provided.
- Remove GIR 0AA from valid postcodes
- Bump versions of common test dependencies (run
make bootstrap
to copy these into your app)
AntivirusClient
andZendeskClient
have returned to their behaviour as of 82.x.x to allow the 83.0.1 fix to go out to apps without the required changes.
- Updates phone_numbers to 8.13.45 to apply a fix to the metadata for phone numbers that was discovered causing a subset of valid Jersey numbers to be incorrectly invalidated
AntivirusClient
andZendeskClient
are no longer thread-safe because they now use persistent requests sessions. Thread-local instances should be used in place of any global instances in any situations where threading is liable to be usedAntivirusClient
andZendeskClient
have had theirinit_app(...)
methods removed as this is an awkward pattern to use for initializing thread-local instances. It is recommended to useLazyLocalGetter
to construct new instances on-demand, passing configuration parameters via the constructor arguments in afactory
function.
- Add
expected_type
mechanism toLazyLocalGetter
- Adds validation check to
PhoneNumber
so that it returns the expected error messageTOO_SHORT
if an empty string is passed. This has caused issues with users of the v2 API getting inconsistent error messages
- Add
LazyLocalGetter
class for lazily-initialized context-local resources
- Add support for validation of UK landlines for services with sms_to_uk_landlines enabled using CSV flow
- Add support for sending SMS to more international numbers. Sending to Eritrea, Wallis and Futuna, Niue, Kiribati, and Tokelau is now supported.
- Extends the validation logic for the
PhoneNumber
class to disallow premium rate numbers
- Add fix to recipient_validation/phone_number.py to raise correct error if a service tries to send to an international number without that permission
- Add
unsubscribe_link
argument to email templates
- Write updated version number to
requirements.txt
if norequirements.in
file found
- Fix the way we log the request_size. Accessing the data at this point can trigger a validation error early and cause a 500 error
- Adds new logging fields to request logging. Namely environment_name, request_size and response_size
- Change
PostalAddress
to addhas_no_fixed_abode_address
method. No fixed abode addresses are now considered invalid.
- Adds condition to validation to allow TV Numbers (https://www.ofcom.org.uk/phones-and-broadband/phone-numbers/numbers-for-drama/) for UK mobiles
- introduce new validation class -
PhoneNumber
, that we will use for services that want to send sms to landline (and in the future this new code can be extended for all phone number validation) - in this new class, we use
phonenumbers
library for validating phone numbers, instead of our custom valdiation code
- BREAKING CHANGE: The constructor for
notification_utils.recipient_validation.errors.InvalidPhoneError
- When raising InvalidPhoneError, instead of supplying a custom message, you must create an error by supplying a code from the
InvalidPhoneError.Codes
enum
- When raising InvalidPhoneError, instead of supplying a custom message, you must create an error by supplying a code from the
InvalidPhoneError.code
will contain this machine-readable code for an exception if you need to examine it laterInvalidPhoneError.get_legacy_v2_api_error_message
returns a historical error message for use on the public v2 api
- Reduces minimum required Gunicorn version for compatibility
- Copies additional config files from utils into repos
- Renames
version_tools.copy_pyproject_yaml
toversion_tools.copy_config
- Update the
send_ticket_to_zendesk
method of the ZendeskClient to return the ID of the ticket that was created.
- Switches on Pyupgrade and a bunch of other more opinionated linting rules
- Bumped minimum versions of select subdependencies
- Restrict postcodes to valid UK postcode zones
- BREAKING CHANGE: recipient validation code has all been moved into separate files in a shared folder. Functionality is unchanged.
- Email address validation can be found in
notifications_utils.recipient_validation.email_address
- Phone number validation can be found in
notifications_utils.recipient_validation.phone_number
- Postal address validation can be found in
notifications_utils.recipient_validation.postal_address
- Email address validation can be found in
- BREAKING CHANGE: InvalidPhoneError and InvalidAddressError no longer extend InvalidEmailError.
- if you wish to handle all recipient validation errors, please use
notifications_utils.recipient_validation.errors.InvalidRecipientError
- if you wish to handle all recipient validation errors, please use
- Change redis delete behaviour to error, rather than end up with stale data, if Redis is unavailable.
NotifyTask
: include pid and other structured fields in completion log messages
- Fix how
version_tools.copy_pyproject_toml
discovers the current version of notifications-utils
- Add
version_tools.copy_pyproject_toml
to share linter config between apps
- Breaking change to the Zendesk Client. The
ticket_categories
argument has been replaced with anotify_task_type
argument, and it now populates a different Zendesk form.
- Remove
check_proxy_header_before_request
from request_helper.py since this was only used when apps were deployed on the PaaS.
- linting changes
- Reject Gibraltar’s postcode (`GX11 1AA) when validating postal addresses
- Remove use of
NOTIFY_RUNTIME_PLATFORM
andNOTIFY_LOG_PATH
flask config parameters, which no longer did anything. Technically this only affects users if the consumed the paramter themselves and relied on utils code setting default values for them.
- Add
InsensitiveSet
class (behaves like a normal set, but with uniqueness determined by normalised values)
- Don't set
statsd_host
inset_gunicorn_defaults
- not all apps have statsd.
- Split
logging.formatting
submodule out oflogging
module. All components should remain accessible via thelogging
module, so this shouldn't affect existing code. - Introduce
gunicorn_defaults
module.
- BREAKING CHANGE: notifications_utils/clients/encryption/encryption_client has been removed. It has been replaced with notifications_utils/clients/signing/signing_client. This is because the encyrption_client was not using encryption. It was just signing the contents of the string.
- Add structured time_taken log to celery logs
- Fix use of hyphen in phone number validation error
- email template: use the new crown and associated styling
- Remove celery.* structured logging for now. It can return when we have more certainty over what values it will log or can rule out that it is ever given sensitive values.
- Add option to ignore list of web paths from request logging. Defaults to /_status and /metrics.
- Add new fields to web request log messages (user_agent, host, path)
- logging: set celery.worker.strategy logging to WARNING to prevent sensitive information being logged
- logging: also attach handlers etc. to celery.worker and celery.redirected
- Always hide barcodes when printing a letter - not only when adding a NOTIFY tag
- NotifyRequest: generate own span_id if none provided in headers
- Include onwards request headers in AntivirusClient requests
- Include parent_span_id in request logs
- Include span_id in all logs when available
- Include remote_addr in request logs
- NotifyRequest: handle trace ids when not handed X-B3-TraceId by paas
- Reverts the 'single session' change from 74.1.0, which may be causing us some connection errors.
- Add
decrby
method to the RedisClient
- Change logging's date formatting to include microseconds
- remove the geojson dependency (another emergency alerts module)
- reuse a single session for all antivirus/zendesk requests to get http keepalive advantages
Removes Emergency-Alerts-related code
- the
polygons
module has been removed template.BroadcastPreviewTemplate
andtemplate.BroadcastMessageTemplate
have been removed
- Fix utils packaging to allow access to subpackages again.
- Adds a
include_notify_tag
parameter toLetterPrintTemplate
so that bilingual letters can disable the NOTIFY tag on the English pages of a letter.
- Add compatibility with Python 3.11 and 3.12
- Change how utils is packaged to exclude tests.
- SKIPPED VERSION - NO RELEASE.
- Adds request logging to flask apps.
- Adds
RestrictedAny
family of testing utilities to newtesting.comparisons
submodule.
- Removes
LetterImageTemplate
. This has been moved to admin, as that is the only app using it.
- Render Welsh language templated letter, with page numbers footer and name of the month in Welsh
- Recognise placeholders from letter_welsh_content and letter_welsh_subject fields
- Change the email template to use a HTML5 doctype and add a 'hidden' attribute to the preheader
- Remove the deprecated
from_address
param from EmailPreviewTemplate (it's been unused for six years)
- Remove support for Markdown-style links in letters
[label](https://example.url)
- Fix QR code rendering for old-style syntax
[QR]()
- Ensure UUIDs in Redis cache keys are always lowercase
- Update the commit message auto-generated by
make bump-utils
(in app repos) to be copy/pastable via eg vim commit message editing.
- Remove empty table cell from 'branding only' branding HTML to fix bug with JAWS screen reader
- Update sanitising of SMS content to include more obscure whitespace
- InvalidPhoneError messages have been updated. The new error messages are more user friendly.
- Remove old syntax for QR codes in letters (only
QR: http://example.com
will work now)
- Fix a bug with some HTML getting injected into QR codes
- Update return value of
BaseLetterTemplate.has_qr_code_with_too_much_data
frombool
toOptional[QrCodeTooLong]
.
- Add
has_qr_code_with_too_much_data
property to letter templates. - Update RecipientCSV to detect and throw errors when rows generate QR codes with too much data in them. Anything using RecipientCSV to process letters will need to check for and report on the row-level property
qr_code_too_long
.
- Add a simpler syntax for QR codes in letters (QR: http://example.com)
- Style the QR code placeholder so it looks better when the placeholder text is long
- Use HTML-encoded parenthesis (
(
and)
) when rendering template content with placeholders. - Bump
phonenumbers
to>= 8.13.8
.
- Switch from PyPDF2 to pypdf, and bump to version 3.9.0. This addresses an infinite loop vulnerability in PDF processing (https://nvd.nist.gov/vuln/detail/CVE-2023-36464).
- Update international billing rates for text messages to latest values from MMG.
- Add a few more mappings to the list of countries for postage
- Remove automatic formatting from JSONFormatter. Any log messages using
{}
to inject strings should be converted to "old-style" log messages using %s and passing variables as arguments to the log function. Do not eagerly interpolate the string (eg "log: {}" % ("string") - let Python's logging module do this itself. This is to provide compatability with Sentry. Add the "G" rule to Ruff's checks to enforce this. - Removes
CustomLogFormatter
altogether, as its only purpose was the auto-formatting as above.
LetterImageTemplate
now adds a hidden element marking the first page of any attachment
RequestCache
now stores items in Redis for 28 days by default (2419200 seconds instead of 7 days or 604800 seconds)
- Remove the
postage
argument fromLetterImageTemplate
in favour of gettingpostage
from thetemplate
dict
(can still be overridden by settingtemplate_instance.postage
) - The
page_count
argument ofLetterImageTemplate
is now optional until the template is rendered (callingstr(template)
)
- Allow subheadings via markdown for emails using
##
.
- Only log a warning and no longer raise an error if creating a Zendesk ticket fails because the user is suspended.
LetterImageTemplate.page_count
is now a property which can be overriden by subclasses- New attributes and properties on
BaseLetterTemplate
(and its subclasses):max_page_count
max_sheet_count
too_many_pages
(requires subclasses to implementpage_count
)
- argument
image_url
toLetterImageTemplate
is now optional unless callingstr(LetterImageTemplate(…))
- Remove the
technical_ticket
parameter from NotifySupportTicket; replace with an optionalnotify_ticket_type
that takes a NotifyTicketType enum value. If provided, this will maintain the existing behaviour where tickets are tagged as technical/non-technical on creation. If omitted, then tickets will have no ticket type, which may help us have a clearer process around triaging tickets.
- Add
class="page--first"
andclass="page--last"
to the first and last pages (respectively) of letters rendered withLetterImageTemplate
- Change
logger.exception
tologger.warning
for log formatting error.
- Adds support for Chinese character sets in letters
- Injects the celery task ID into logging output if no requestId is present.
- Add odd/even class to letter pages
- Allow extra logging filters to be passed into
notifications_utils.logging.init_app
. - Add a
UserIdFilter
to automatically inject the user_id to flask request logs.
- Include the country for normalised BFPO lines.
- Updated PostalAddress to parse BFPO addresses. Any validation done on PostalAddresses should be update to report on the new error property
has_invalid_country_for_bfpo_address
.
- Adds
redis_client.get_lock
which returns a redis lock object (or a stub lock if redis is not enabled). See https://redis-py.readthedocs.io/en/v4.4.2/lock.html for functionality.
- Adds a method to the ZendeskClient to add a comment to a pre-existing ticket, including adding attachments.
- Provide our own cache file for bank holidays data, which will help us keep it up-to-date. This is a breaking change as any apps pulling in utils should now use notifications_utils.bank_holidays.BankHolidays rather than govuk_bank_holidays.bank_holidays.BankHolidays directly.
- Add
letter_timings.is_dvla_working_day
- Add
letter_timings.is_royal_mail_working_day
- Add
letter_timings.get_dvla_working_day_offset_by
- Add
letter_timings.get_previous_dvla_working_day
- Add
letter_timings.get_royal_mail_working_day_offset_by
- Add
letter_timings.get_previous_royal_mail_working_day
- Bump pyproj to be version 3.4.1 or greater. This changes the ESPG codes to be upper case, which affects the how
Polygons
class transforms data.
- Add tooling to bump utils version in apps
- Add support for creating redis cache keys for a specific notification type.
- Add synonyms for sending letters to the Canary Islands
- Remove
Template.encoding
(very unlikely to be used anywhere)
- add a
message_as_html
parameter toNotifySupportTicket
to enable creating tickets containing HTML (eg links).
- replace
brand_name
withbrand_alt_text
in HTMLEmailTemplate to more accurately reflect its purpose
- Do not log to file when
NOTIFY_RUNTIME_PLATFORM
is set toecs
-
Breaking changes to
field.Field
:- The
html
argument must now beescape
orpassthrough
.strip
is no longer valid - The default value of the
html
argument is nowescape
notstrip
- The
-
Removal of
formatters.strip_html
:
-
Breaking: upgrade PyPDF2 to version 2.0.0. You will need to:
- Change error class imports from
pypdf2.utils
topypdf2.errors
. - Run the tests and make changes based on the deprecation warnings.
- Change error class imports from
- Links in previews of text messages and emergency alerts now have the correct CSS classes added automatically
- URLs in previews of text messages and emergency alerts will now become links even
if they don’t have
http://
orhttps://
at the start
- Move some functions and variable from the
notifications_utils.formatters
module to thenotifications_utils.markdown
andnotifications_utils
modules. None of our apps are directly importing the functions and variables which have moved.
- Downgrade min version of boto3 due to incompatibility with awscli-cwlogs dependency.
- Unpin most dependencies and remove redundant ones (no action required).
- Bump shapely to 1.8.0 to support Mac M1 installation of geos.
- Added "delete_by_pattern" wrapper to RequestCache decorator group.
- Shortened "delete_cache_keys_by_pattern" to "delete_by_pattern".
- "delete_by_pattern" has a new "raise_exception" parameter (default False).
- Add should_validate flag to
notifications_utils.recipients.RecipientCSV
. Defaults toTrue
.
- remove the
column
argument from recipients.validate_phone_number,
recipients.validate_uk_phone_number,
recipients.try_validate_and_format_phone_numberand
recipients.validate_email_address` (no consuming code uses this argument) - remove
recipients.validate_recipient
(consuming code already usesrecipients.validate_phone_number
,recipients.validate_email_address
orpostal_address.PostalAddress(…).valid
instead)
notifications_utils.columns.Columns
has moved tonotifications_utils.insensitive_dict.InsensitiveDict
notifications_utils.columns.Rows
has moved tonotifications_utils.recipients.Rows
notifications_utils.columns.Cell
has moved tonotifications_utils.recipients.Cell
- Deprecate the following unused
redis_client
functions:redis_client.increment_hash_value
redis_client.decrement_hash_value
redis_client.get_all_from_hash
redis_client.set_hash_and_expire
redis_client.expire
- Bump govuk-bank-holidays to cache holidays for next year.
- Log exception and stacktrace when Celery tasks fail.
- Revert 51.2.0.
- Timeout processing CSVs to avoid timing out downstream requests
This only affects the Admin app, which should ideally rescue the exception, but just letting it propagate is also acceptable as it's similar to the current behaviour where we timeout in CloudFront.
- Make processing of spreadsheets with many empty columns more efficient
- Initial argument to
RecipientCSV
renamed fromwhitelist
toguestlist
, in other words consuming code should callRecipientCSV(guestlist=['[email protected]'])
RecipientCSV.whitelist
property renamed toRecipientCSV.guestlist
- Make icon in
broadcast_preview_template.jinja2
an inline SVG (requires changes to the CSS of consumer code)
- Add
ttl_in_seconds
argument toRequestCache.set
to let users specify a custom TTL
Polygons
must now be called with eithershapely.Polygon
objects and a valid Coordinate Reference System code forutm_crs
or a list of lists of coordinates in degrees
- Enable Celery argument checking for apply_async.
- Remove redundant "kwargs" handling code for Celery Request ID tracing.
- Add new NotifyCelery base class as a drop in replacement to DRY-up the "app/celery/celery.py" file we have in many apps.
- Rename
normalise_lines
toget_lines_with_normalised_whitespace
- Rename
strip_whitespace
tostrip_all_whitespace
- Remove
OBSCURE_WHITESPACE
variable (appears unused in other apps) - Remove
multiple_spaces_in_a_row
variable (appears unused in other apps) - Remove
normalise_line
function (appears unused in other apps)
- Breaking: remove
create_ticket
method from ZendeskClient
- Extract ticket formatting from ZendeskClient into NotifySupportTicket
- Revert 45.0.0 (pyproj dependency won't install on PaaS)
- Use cartesian coordinate system for polygon geometry
- Split out separate too_late_to_cancel_letter function to allow reuse
- Add
intersects
method to Polygons
- Detect optional placeholders with brackets in their text
- Allow Zendesk tickets to be create with internal notes
- Round coordinates to 5 decimal places
- Add methods to get the bounds and overlap of polygons
- Normalise international numbers when formatting
Changelog not recorded - please see pull requests on github.