Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Enum Keys From Another Enum

I have an enum class with the following code:

# enums.py
class AuthCode(Enum):
    ALREADY_AUTHENTICATED               = 1
    MISSING_EMAIL                       = 2
    MISSING_PASSWORD                    = 3
    MISSING_REGISTRATION_TOKEN_CODE     = 4
    INVALID_EMAIL                       = 5
    REDEEMED_EMAIL                      = 6
    INVALID_PASSWORD                    = 7
    INVALID_REGISTRATION_TOKEN_CODE     = 8
    REDEEMED_REGISTRATION_TOKEN_CODE    = 9
    INVALID_CREDENTIALS                 = 10
    SIGNIN_SUCCESSFUL                   = 11
    REGISTRATION_SUCCESSFUL             = 12

class AuthCodeMessage(Enum):
    AuthCode.ALREADY_AUTHENTICATED              = "User was already logged in"
    AuthCode.MISSING_EMAIL                      = "Email was not specified"
    AuthCode.MISSING_PASSWORD                   = "Password was not specified"
    AuthCode.MISSING_REGISTRATION_TOKEN_CODE    = "Registration token code was not specified"
    AuthCode.INVALID_EMAIL                      = "Email is invalid"
    AuthCode.REDEEMED_EMAIL                     = "An account with this email has been created already"
    AuthCode.INVALID_PASSWORD                   = "Password does not meet minimum password requirements"
    AuthCode.INVALID_REGISTRATION_TOKEN_CODE    = "Registration token code is invalid"
    AuthCode.REDEEMED_REGISTRATION_TOKEN_CODE   = "Registration token code has been redeemed already"
    AuthCode.INVALID_CREDENTIALS                = "Account with these credentials does not exist"
    AuthCode.SIGNIN_SUCCESSFUL                  = "User has been signed in successfully"
    AuthCode.REGISTRATION_SUCCESSFUL            = "User account has been created successfully"

Is it possible to define the second enum (AuthCodeMessage) the way it is defined (i.e., using another enum as a key). How can I retrieve the enum value?

Edit 1: I would like to call my this enumeration from my code using the an approach similar to the following:

from enums import AuthCode, AuthCodeMessage

def authResponse(authCode):
    AuthCode.ALREADY_AUTHENTICATED
    return jsonify({
        "code": authCode,
        "message": AuthCodeMessage.authCode
    })

authResponse(AuthCode.ALREADY_AUTHENTICATED)
like image 251
Sam Avatar asked Apr 29 '26 13:04

Sam


2 Answers

Instead of using two enums, just use one. Using the AutoNumber recipe from the docs (the second one), your code would look like this:

class AuthCode(AutoNumber):
    ALREADY_AUTHENTICATED   = "User was already logged in"
    MISSING_EMAIL           = "Email was not specified"
    MISSING_PASSWORD        = "Password was not specified"
    ...
    
    def __init__(self, description):
        self.description = description

and later on:

def authResponse(authCode):
    return jsonify({
        "code": authCode.value,
        "message": authCode.description,
    })

--

Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

like image 184
Ethan Furman Avatar answered May 01 '26 02:05

Ethan Furman


What you really want is to map AuthCodes to strings. The usual way to do this in Python is with a dictionary, like this:

AUTHCODE_MESSAGES = {
    AuthCode.ALREADY_AUTHENTICATED: "User was already logged in",
# copy the rest of the code/message pairs here
# make sure to replace the = with :
# and add a , on the end of every line
}

You can then use it like so:

# FIXME: enums is not a very clear name for what it does.
from enums import AuthCode, AUTHCODE_MESSAGES

def authResponse(authCode):
    return jsonify({
        "code": authCode,
        "message": AUTHCODE_MESSAGES[authCode]
    })
like image 40
Jasmijn Avatar answered May 01 '26 01:05

Jasmijn