Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Django] Can't have model classes as whitelisted_types in settings.py #126

Open
arthurio opened this issue Aug 17, 2016 · 5 comments
Open

Comments

@arthurio
Copy link

Because the whitelisted_types is expected to be a list of Types, we currently can't have model classes whitelisted in Django. The configuration is in settings.py and at this point it's not possible to import model classes.

My current solution is to list them as strings and have a singleton class that when instantiated will read those strings and convert them to types before calling the rollbar.init function. I instantiate this singleton in the wsgi.py file so that it's done before the rollbar.contrib.django.middleware.RollbarNotifierMiddleware can be called, otherwise the middleware would call rollback.init first without the whitelisted_types list being converted.

settings.py

ROLLBAR = {
    'access_token': ACCESS_TOKEN,
    'environment': ENVIRONMENT,
    'branch': 'master/',
    'root': ROOT_PATH,
    'whitelisted_types': (
        ('application.models', 'AModel'),
        ('application.models', 'AnotherModel'),
    )
}

rollbar_singleton.py

import rollbar
import sys

from django.conf import settings
from importlib import import_module


class Rollbar:
    ''' This is a singleton class meant to instantiate the rollbar service only once.
        To use it, simply use the following:
        from services.rollbar_singleton import Rollbar
        Rollbar.get_instance().report(...)
    '''
    class __Rollbar:
        def __init__(self):
            self.rollbar = rollbar

            # Transform the whitelisted tuples into types
            whitelisted_types_tuples = settings.ROLLBAR['whitelisted_types']

            imported_modules = {}
            whitelisted_types = []
            for module, class_name in whitelisted_types_tuples:
                imported_module = imported_modules.get(module)
                if not imported_module:
                    imported_module = import_module(module)
                    imported_modules[module] = imported_module

                imported_class = getattr(imported_module, class_name, None)
                if not imported_class:
                    continue
                whitelisted_types.append(imported_class)

            extra_configuration = {
                'locals': {
                    'whitelisted_types': whitelisted_types,
                }
            }

            self.rollbar.init(
                settings.ROLLBAR["access_token"],
                settings.ROLLBAR["environment"],
                **extra_configuration
            )

        def report(self, exc_info, request=None, extra_data=None, payload_data=None):
            return self.rollbar.report_exc_info(exc_info, request, extra_data, payload_data)

    __instance = None

    @classmethod
    def get_instance(cls):
        if not Rollbar.__instance:
            Rollbar.__instance = Rollbar.__Rollbar()

        return Rollbar.__instance

wsgi.py

...
# Call get_instance to instantiate rollbar with correct settings.
from services.rollbar_singleton import Rollbar
Rollbar.get_instance()

This solution works fine but I'd rather have something less complicated where SerializableTransform would be the one taking care of transforming strings into types when being instantiated.

class SerializableTransform(Transform):
    def __init__(self, safe_repr=True, whitelist_types=None):
        super(SerializableTransform, self).__init__()
        self.safe_repr = safe_repr
        self.whitelist = set()
        for whitelist_type in whitelist_types:
            if isinstance(whitelist_type, str):
                # The convert_string_to_type needs to be implemented
                whitelist_type = convert_string_to_type(whitelist_type)
            self.whitelist.add(whitelist_types)

I'm open for comments and suggestions if you have a better solution.

@arthurio arthurio changed the title Can't have model classes as whitelisted_types in settings.py [Django] Can't have model classes as whitelisted_types in settings.py Aug 17, 2016
@ezarowny
Copy link
Contributor

Sorry for the delay there. Some of us were at a conference last week. Taking a look a this today.

@ezarowny
Copy link
Contributor

@arthurio, we're going to add supporting type names as a feature request to pyrollbar. I'll be filing a story internally for us to work on this. If you want to take a crack at it yourself though, let me know. Cheers!

@arthurio
Copy link
Author

@ezarowny Thanks for the update! I probably won't have time to work on it in the coming weeks but will let you know if I do. Feel free to reach out if you have questions.
Cheers

@rivkahstandig3636
Copy link
Contributor

Hi there, I’m closing out all issues opened before 2018 that haven’t had any activity on them since the start of this year. If this is still an issue for you, please comment here and we can reopen this. Thanks!

@TimmyTango
Copy link

Hi! Wanted to re-open this issue if there was a chance this could be implemented by Rollbar. Right now I have safe_repr set to False, but I only need a handful of Django models to actually call repr. Passing along a list of strings for whitelisted_types would be quite handy.

@brianr brianr reopened this Jul 23, 2020
@bxsx bxsx removed this from the v0.15.0 milestone Jan 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants