diff --git a/app/commands.py b/app/commands.py index e36657812..6f195a84b 100644 --- a/app/commands.py +++ b/app/commands.py @@ -238,7 +238,8 @@ def rebuild_ft_billing_for_day(service_id, day): "-a", "--auth_type", required=False, - help="The authentication type for the user, AuthType.SMS or AuthType.EMAIL. Defaults to AuthType.SMS if not provided", + help="The authentication type for the user, AuthType.SMS or AuthType.EMAIL. " + "Defaults to AuthType.SMS if not provided", ) @click.option( "-p", "--permissions", required=True, help="Comma separated list of permissions." diff --git a/app/enums.py b/app/enums.py index 74d6a2100..3dbb594f0 100644 --- a/app/enums.py +++ b/app/enums.py @@ -1,42 +1,42 @@ -from enum import Enum +from strenum import StrEnum -class TemplateType(Enum): +class TemplateType(StrEnum): SMS = "sms" EMAIL = "email" LETTER = "letter" -class NotificationType(Enum): +class NotificationType(StrEnum): SMS = "sms" EMAIL = "email" LETTER = "letter" -class TemplateProcessType(Enum): +class TemplateProcessType(StrEnum): # TODO: Should Template.process_type be changed to use this? NORMAL = "normal" PRIORITY = "priority" -class AuthType(Enum): +class AuthType(StrEnum): SMS = "sms_auth" EMAIL = "email_auth" WEBAUTHN = "webauthn_auth" -class CallbackType(Enum): +class CallbackType(StrEnum): DELIVERY_STATUS = "delivery_status" COMPLAINT = "complaint" -class OrganizationType(Enum): +class OrganizationType(StrEnum): FEDERAL = "federal" STATE = "state" OTHER = "other" -class NotificationStatus(Enum): +class NotificationStatus(StrEnum): CANCELLED = "cancelled" CREATED = "created" SENDING = "sending" @@ -52,7 +52,7 @@ class NotificationStatus(Enum): VIRUS_SCAN_FAILED = "virus-scan-failed" @classmethod - def failed_types(cls) -> tuple["NotificationStatus", ...]: + def failed_types(cls) -> tuple[str, ...]: return ( cls.TECHNICAL_FAILURE, cls.TEMPORARY_FAILURE, @@ -62,7 +62,7 @@ class NotificationStatus(Enum): ) @classmethod - def completed_types(cls) -> tuple["NotificationStatus", ...]: + def completed_types(cls) -> tuple[str, ...]: return ( cls.SENT, cls.DELIVERED, @@ -74,11 +74,11 @@ class NotificationStatus(Enum): ) @classmethod - def success_types(cls) -> tuple["NotificationStatus", ...]: + def success_types(cls) -> tuple[str, ...]: return (cls.SENT, cls.DELIVERED) @classmethod - def billable_types(cls) -> tuple["NotificationStatus", ...]: + def billable_types(cls) -> tuple[str, ...]: return ( cls.SENDING, cls.SENT, @@ -90,7 +90,7 @@ class NotificationStatus(Enum): ) @classmethod - def billable_sms_types(cls) -> tuple["NotificationStatus", ...]: + def billable_sms_types(cls) -> tuple[str, ...]: return ( cls.SENDING, cls.SENT, # internationally @@ -101,7 +101,7 @@ class NotificationStatus(Enum): ) @classmethod - def sent_email_types(cls) -> tuple["NotificationStatus", ...]: + def sent_email_types(cls) -> tuple[str, ...]: return ( cls.SENDING, cls.DELIVERED, @@ -110,11 +110,11 @@ class NotificationStatus(Enum): ) @classmethod - def non_billable_types(cls) -> tuple["NotificationStatus", ...]: - return tuple({i for i in cls} - set(cls.billable_types())) + def non_billable_types(cls) -> tuple[str, ...]: + return tuple(set(cls) - set(cls.billable_types())) -class PermissionType(Enum): +class PermissionType(StrEnum): MANAGE_USERS = "manage_users" MANAGE_TEMPLATES = "manage_templates" MANAGE_SETTINGS = "manage_settings" @@ -125,7 +125,7 @@ class PermissionType(Enum): VIEW_ACTIVITY = "view_activity" @classmethod - def defaults(cls) -> tuple["PermissionType", ...]: + def defaults(cls) -> tuple[str, ...]: return ( cls.MANAGE_USERS, cls.MANAGE_TEMPLATES, @@ -137,7 +137,7 @@ class PermissionType(Enum): ) -class ServicePermissionType(Enum): +class ServicePermissionType(StrEnum): EMAIL = "email" SMS = "sms" INTERNATIONAL_SMS = "international_sms" @@ -147,9 +147,8 @@ class ServicePermissionType(Enum): UPLOAD_DOCUMENT = "upload_document" EDIT_FOLDER_PERMISSIONS = "edit_folder_permissions" - @property - def defaults(self) -> tuple["ServicePermissionType", ...]: - cls = type(self) + @classmethod + def defaults(cls) -> tuple[str, ...]: return ( cls.SMS, cls.EMAIL, @@ -157,18 +156,18 @@ class ServicePermissionType(Enum): ) -class RecipientType(Enum): +class RecipientType(StrEnum): MOBILE = "mobile" EMAIL = "email" -class KeyType(Enum): +class KeyType(StrEnum): NORMAL = "normal" TEAM = "team" TEST = "test" -class JobStatus(Enum): +class JobStatus(StrEnum): PENDING = "pending" IN_PROGRESS = "in progress" FINISHED = "finished" @@ -180,29 +179,29 @@ class JobStatus(Enum): ERROR = "error" -class InvitedUserStatus(Enum): +class InvitedUserStatus(StrEnum): PENDING = "pending" ACCEPTED = "accepted" CANCELLED = "cancelled" EXPIRED = "expired" -class BrandType(Enum): +class BrandType(StrEnum): ORG = "org" BOTH = "both" ORG_BANNER = "org_banner" -class CodeType(Enum): +class CodeType(StrEnum): EMAIL = "email" SMS = "sms" -class AgreementType(Enum): +class AgreementType(StrEnum): MOU = "MOU" IAA = "IAA" -class AgreementStatus(Enum): +class AgreementStatus(StrEnum): ACTIVE = "active" EXPIRED = "expired" diff --git a/app/models.py b/app/models.py index 8144bc873..6f7dec296 100644 --- a/app/models.py +++ b/app/models.py @@ -76,9 +76,9 @@ _enum_column_names = { def enum_column(enum_type, **kwargs): return db.Column( db.Enum( - *[i.value for i in enum_type], + *[i for i in enum_type], name=_enum_column_names[enum_type], - values_callable=(lambda x: [i.value for i in x]), + values_callable=(lambda x: [i for i in x]), ), **kwargs, ) @@ -137,7 +137,7 @@ class User(db.Model): state = db.Column(db.String, nullable=False, default="pending") platform_admin = db.Column(db.Boolean, nullable=False, default=False) current_session_id = db.Column(UUID(as_uuid=True), nullable=True) - auth_type = enum_column(AuthType, index=True, nullable=False, default=AuthType.SMS.value) + auth_type = enum_column(AuthType, index=True, nullable=False, default=AuthType.SMS) email_access_validated_at = db.Column( db.DateTime, index=False, @@ -310,7 +310,7 @@ class EmailBranding(db.Model): BrandType, index=True, nullable=False, - default=BrandType.ORG.value, + default=BrandType.ORG, ) def serialize(self): @@ -1130,7 +1130,7 @@ class TemplateBase(db.Model): TemplateProcessType, index=True, nullable=False, - default=TemplateProcessType.NORMAL.value, + default=TemplateProcessType.NORMAL, ) redact_personalisation = association_proxy( @@ -1385,7 +1385,7 @@ class Job(db.Model): JobStatus, index=True, nullable=False, - default=JobStatus.PENDING.value, + default=JobStatus.PENDING, ) archived = db.Column(db.Boolean, nullable=False, default=False) @@ -1453,7 +1453,7 @@ class NotificationAllTimeView(db.Model): NotificationStatus, name="notification_status", nullable=True, - default=NotificationStatus.CREATED.value, + default=NotificationStatus.CREATED, key="status", ) reference = db.Column(db.String) @@ -1511,7 +1511,7 @@ class Notification(db.Model): NotificationStatus, name="notification_status", nullable=True, - default=NotificationStatus.CREATED.value, + default=NotificationStatus.CREATED, key="status", ) reference = db.Column(db.String, nullable=True, index=True) @@ -1788,7 +1788,7 @@ class NotificationHistory(db.Model, HistoryModel): NotificationStatus, name="notification_status", nullable=True, - default=NotificationStatus.CREATED.value, + default=NotificationStatus.CREATED, key="status", ) reference = db.Column(db.String, nullable=True, index=True) @@ -1856,10 +1856,10 @@ class InvitedUser(db.Model): status = enum_column( InvitedUserStatus, nullable=False, - default=InvitedUserStatus.PENDING.value, + default=InvitedUserStatus.PENDING, ) permissions = db.Column(db.String, nullable=False) - auth_type = enum_column(AuthType, index=True, nullable=False, default=AuthType.SMS.value) + auth_type = enum_column(AuthType, index=True, nullable=False, default=AuthType.SMS) folder_permissions = db.Column(JSONB(none_as_null=True), nullable=False, default=list) # would like to have used properties for this but haven't found a way to make them @@ -1894,7 +1894,7 @@ class InvitedOrganizationUser(db.Model): status = enum_column( InvitedUserStatus, nullable=False, - default=InvitedUserStatus.PENDING.value, + default=InvitedUserStatus.PENDING, ) def serialize(self): diff --git a/poetry.lock b/poetry.lock index 6a1c8af62..be7abff41 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4231,6 +4231,22 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" +[[package]] +name = "strenum" +version = "0.4.15" +description = "An Enum that inherits from str." +optional = false +python-versions = "*" +files = [ + {file = "StrEnum-0.4.15-py3-none-any.whl", hash = "sha256:a30cda4af7cc6b5bf52c8055bc4bf4b2b6b14a93b574626da33df53cf7740659"}, + {file = "StrEnum-0.4.15.tar.gz", hash = "sha256:878fb5ab705442070e4dd1929bb5e2249511c0bcf2b0eeacf3bcd80875c82eff"}, +] + +[package.extras] +docs = ["myst-parser[linkify]", "sphinx", "sphinx-rtd-theme"] +release = ["twine"] +test = ["pylint", "pytest", "pytest-black", "pytest-cov", "pytest-pylint"] + [[package]] name = "toml" version = "0.10.2" diff --git a/pyproject.toml b/pyproject.toml index 205d5a8db..970059f5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,6 +49,7 @@ pyjwt = "==2.8.0" python-dotenv = "==1.0.0" sqlalchemy = "==1.4.40" werkzeug = "^3.0.1" +strenum = "^0.4.15" [tool.poetry.group.dev.dependencies] diff --git a/tests/app/test_commands.py b/tests/app/test_commands.py index 2f5a3fb4b..586faaee7 100644 --- a/tests/app/test_commands.py +++ b/tests/app/test_commands.py @@ -20,7 +20,14 @@ from app.commands import ( ) from app.dao.inbound_numbers_dao import dao_get_available_inbound_numbers from app.dao.users_dao import get_user_by_email -from app.enums import KeyType, NotificationStatus, NotificationType, OrganizationType, TemplateType +from app.enums import ( + AuthType, + KeyType, + NotificationStatus, + NotificationType, + OrganizationType, + TemplateType, +) from app.models import ( AnnualBilling, Job,