liminspace / django-mjml

The simplest way to use MJML in Django templates.
MIT License
262 stars 32 forks source link

Remove settings type check in authentication tuple to prevent from failing in LazySettings #101

Closed fronbasal closed 4 years ago

fronbasal commented 4 years ago

Currently, django-mjml checks for the proper type (str) in the auth tuple in HTTP_SERVERS. Sadly this does not work in a LazySettings environment (django-configurations). This PR removes the assertion of type for the authentication tuple to make this package compatible with django-configurations.

Example:

MJML_BACKEND_MODE = 'httpserver'
MJML_APPLICATION_ID = values.SecretValue()
MJML_SECRET_KEY = values.SecretValue()
MJML_HTTPSERVERS = [
        {
            'URL': 'https://api.mjml.io/v1/render',  # official MJML API
            'HTTP_AUTH': (MJML_APPLICATION_ID, MJML_SECRET_KEY), # won't evaluate to type str directly
        },
]
liminspace commented 4 years ago

@fronbasal why can't you just use (str(MJML_APPLICATION_ID), str(MJML_SECRET_KEY)) in your case?

fronbasal commented 4 years ago

@liminspace That sadly does not work due to the evaluation time of the variable, which is done at access time (when evaluation settings.MJML_APPLICATION_ID, for example). Therefore it won't evaluate to str/is not castable to str.

liminspace commented 4 years ago

@fronbasal can you show the fill example of your using django-configurations in your project?

fronbasal commented 4 years ago

Sure, no problem.

class Common(Configuration):
    MJML_BACKEND_MODE = "cmd"
    MJML_APPLICATION_ID = values.SecretValue()
    MJML_SECRET_KEY = values.SecretValue()
    MJML_HTTPSERVERS = [
        {
            "URL": "https://api.mjml.io/v1/render",  # official MJML API
            "HTTP_AUTH": (MJML_APPLICATION_ID, MJML_SECRET_KEY),
        },
    ]

The .env file then specifies both SecretValue() variables. At runtime the value won't hold any value, because it is lazily evaluated thus only when accessing the setting (getattr(settings, "MJML_SECRET_KEY")) it will evaluate to the actual secret key. By checking the type() at runtime it will break with django-configurations, though.

liminspace commented 4 years ago

@fronbasal try to use property (https://django-configurations.readthedocs.io/en/stable/patterns/#property-settings):

class Common(Configuration):
    MJML_BACKEND_MODE = "cmd"
    MJML_APPLICATION_ID = values.SecretValue()
    MJML_SECRET_KEY = values.SecretValue()

    @property
    def MJML_HTTPSERVERS(self):
        return [
            {
                "URL": "https://api.mjml.io/v1/render",  # official MJML API
                "HTTP_AUTH": (self.MJML_APPLICATION_ID, self.MJML_SECRET_KEY),
            },
        ]
fronbasal commented 4 years ago

Oh - didn't catch that! Thank you, nice hint. Thank you for the good work.