Raekkeri/django-requestlogs

TypeError: 'str' object is not callable

Opened this issue · 5 comments

I used custom MyEntrySerializer by extending BaseEntrySerializer bcz I was getting issue before (AttributeError: Got AttributeError when attempting to get a value for field user on serializer BaseEntrySerializer.
The serializer field might be named incorrectly and not match any attribute or key on the RequestLogEntry instance.
Original exception text was: 'User' object has no attribute 'username'.), but now getting different issue "TypeError: 'str' object is not callable" , Details are below.
Traceback (most recent call last):
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/middleware.py", line 20, in call
get_requestlog_entry(request).finalize(response)
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/entries.py", line 96, in finalize
self.store()
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/entries.py", line 100, in store
storage.store(self)
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/storages.py", line 69, in store
logger.info(self.prepare(entry))
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/storages.py", line 64, in prepare
return self.get_serializer_class()(entry).data
TypeError: 'str' object is not callable

please help to solve this one

Hi,
could you post the implementation of your MyEntrySerializer, as well as the REQUESTLOGS = {..} configuration in your settings.py?

settings.py configuration for requestlogs

MIDDLEWARE = [
.........
''requestlogs.middleware.RequestLogsMiddleware','
]

REST_FRAMEWORK = {
.........
'EXCEPTION_HANDLER': 'requestlogs.views.exception_handler',
}

REQUESTLOGS = {
'STORAGE_CLASS': 'requestlogs.storages.LoggingStorage',
'ENTRY_CLASS': 'requestlogs.entries.RequestLogEntry',
'SERIALIZER_CLASS': 'accounts.api.serializers.MyEntrySerializer',
'SECRETS': ['password', 'token'],
'ATTRIBUTE_NAME': '_requestlog',
'METHODS': ('GET', 'PUT', 'PATCH', 'POST', 'DELETE'),
}

and my custom serializers class code is below:-

from requestlogs.storages import BaseEntrySerializer
class UserSerializer(ModelSerializer):

class Meta:
        model = User
        fields = '__all__'

class MyEntrySerializer(BaseEntrySerializer):
user = UserSerializer()

I'm unable to reproduce the problem (couldn't get the exact same error), but seeing that the error is raised in requestlogs/storages.py", line 64, in prepare, there might be something funny going on with importing the entry serializer.

Anyway, I'd recommend for now to not use a ModelSerializer for the UserSerializer, but instead a normal Serializer and specifying the fields explicitly. Let me know if this helps.

Hey @Raekkeri,

first of all, I want to thank you for this package because it is exactly what we are looking for!

I'm having the same issue as the original poster.

Edit: I've placed the serializer in a separate file and the issue is resolved. Previously I placed it next to existing serializers and I think this messes with the imports and settings

REQUESTLOGS = {
    'SERIALIZER_CLASS': 'myapp.serializers.LogEntrySerializer',
}
class LogEntrySerializer(serializers.Serializer):
    class ResponseSerializer(serializers.Serializer):
        status_code = serializers.IntegerField(read_only=True)
        # data = JsonDumpField(read_only=True)  # disabled on purpose because of sensitive data

    class UserSerializer(serializers.Serializer):
        id = serializers.IntegerField()
        username = serializers.CharField()

    action_name = serializers.CharField(read_only=True)
    execution_time = serializers.DurationField(read_only=True)
    timestamp = serializers.DateTimeField(read_only=True)
    ip_address = serializers.CharField(read_only=True)
    request = BaseRequestSerializer(read_only=True)
    response = ResponseSerializer(read_only=True)
    user = UserSerializer()

leads to:

TypeError: 'str' object is not callable

I've investigated a bit and populate_settings in base.py seems to resolve the class correctly. But the get_serializer_class function in BaseStorage seems to return only a string.

Hey @Raekkeri,

first of all, I want to thank you for this package because it is exactly what we are looking for!

I'm having the same issue as the original poster.

Hi, thanks for looking into this issue. After a quick glance I still wasn't able to reproduce this issue in unit tests. So I'll leave this unresolved and get back to it later.