Updating database data from websocket - django

I would like to update database data from a websocket. Specifically, when a user connects to a websocket, I would like to update a field in one of my models with the timestamp of when the user connected.
However, with the logic I have implemented, I am getting this error:
Exception inside application: __init__() takes 1 positional argument but 2 were given
Traceback (most recent call last):
File "C:\Users\15512\anaconda3\lib\site-packages\channels\staticfiles.py", line 44, in __call__
return await self.application(scope, receive, send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\routing.py", line 71, in __call__
return await application(scope, receive, send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\security\websocket.py", line 37, in __call__
return await self.application(scope, receive, send)
File "C:\Users\15512\Desktop\django-project\peerplatform\signup\middleware.py", line 47, in __call__
return await super().__call__(scope, receive, send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\middleware.py", line 26, in __call__
return await self.inner(scope, receive, send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\sessions.py", line 47, in __call__
return await self.inner(dict(scope, cookies=cookies), receive, send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\sessions.py", line 263, in __call__
return await self.inner(wrapper.scope, receive, wrapper.send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\auth.py", line 185, in __call__
return await super().__call__(scope, receive, send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\middleware.py", line 26, in __call__
return await self.inner(scope, receive, send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\routing.py", line 150, in __call__
return await application(
File "C:\Users\15512\anaconda3\lib\site-packages\channels\consumer.py", line 94, in app
return await consumer(scope, receive, send)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\consumer.py", line 58, in __call__
await await_many_dispatch(
File "C:\Users\15512\anaconda3\lib\site-packages\channels\utils.py", line 51, in await_many_dispatch
await dispatch(result)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\consumer.py", line 73, in dispatch
await handler(message)
File "C:\Users\15512\Desktop\django-project\peerplatform\signup\consumers.py", line 34, in websocket_connect
result = (await self.update_timestamp(group_name))
File "C:\Users\15512\anaconda3\lib\site-packages\asgiref\sync.py", line 414, in __call__
ret = await asyncio.wait_for(future, timeout=None)
File "C:\Users\15512\anaconda3\lib\asyncio\tasks.py", line 455, in wait_for
return await fut
File "C:\Users\15512\anaconda3\lib\concurrent\futures\thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "C:\Users\15512\anaconda3\lib\site-packages\channels\db.py", line 13, in thread_handler
return super().thread_handler(loop, *args, **kwargs)
File "C:\Users\15512\anaconda3\lib\site-packages\asgiref\sync.py", line 455, in thread_handler
return func(*args, **kwargs)
File "C:\Users\15512\Desktop\django-project\peerplatform\signup\consumers.py", line 108, in update_timestamp
serializer_class = UpdateProfileView(request)
TypeError: __init__() takes 1 positional argument but 2 were given
This is what I have tried, this is in my consumers.py and is the function called when a user connects to the websocket:
class PracticeConsumer(AsyncWebsocketConsumer):
async def websocket_connect(self, event):
...
group_name = username_id
result = (await self.update_timestamp(group_name))
await self.channel_layer.group_add(
'{}'.format(group_name),
self.channel_name
)
await self.accept()
...
#database_sync_to_async
def update_timestamp(self, user_id):
time = timezone.now().isoformat()
request = dict({'method': 'PUT', 'connected_timestamp': time, 'user.id': self.user_id})
serializer_class = UpdateProfileView(request)
return User.objects.filter(user__id=user_id).values()
This is how my UpdateProfileView is written out:
class UpdateProfileView(generics.UpdateAPIView):
queryset = User.objects.all()
serializer_class = UpdateUserSerializer
def profile(request):
if request.method == 'PUT':
try:
user = User.objects.get(id=request.user.id)
serializer_user = UpdateUserSerializer(user, many=True)
if serializer_user.is_valid():
serializer_user.save()
return Response(serializer_user)
except User.DoesNotExist:
return Response(data='no such user!', status=status.HTTP_400_BAD_REQUEST)

The error is because you need a self in the UpdateProfileView's profile function, like: def profile(self, request):
But! from what I'm seeing they usually use the function update and not profile
Example
Also I updated to use filter().first(), it will return None if it doesn't find one. Try/Catch is sorta gross imo
class UpdateProfileView(generics.UpdateAPIView):
queryset = User.objects.all()
serializer_class = UpdateUserSerializer
def update(self, request, *args, **kwargs):
if request.method == 'PUT':
user = User.objects.filter(id=request.user.id).first()
# # but `request.user` is a User Object!- You don't need to filter for it!
# user = request.user
if user:
serializer_user = UpdateUserSerializer(user, many=True)
if serializer_user.is_valid():
serializer_user.save()
return Response(serializer_user)
else:
return Response(data='no such user!', status=status.HTTP_400_BAD_REQUEST)python

Related

django channel image serializing error says You cannot call this from an async context - use a thread or sync_to_async

i have a Invoice serializer which include a image serilaizer as a invoice has relation one to many with image
i got this error when i enable many=True in images field in invoice serializer
Exception inside application: You cannot call this from an async context - use a thread or sync_to_async.
Traceback (most recent call last):
File "D:\projects\TaxiTR\env\lib\site-packages\django\contrib\staticfiles\handlers.py", line 101, in __call__
return await self.application(scope, receive, send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\routing.py", line 62, in __call__
return await application(scope, receive, send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\security\websocket.py", line 37, in __call__
return await self.application(scope, receive, send)
File "D:\projects\TaxiTR\core\middleware.py", line 57, in __call__
return await super().__call__(scope, receive, send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\middleware.py", line 24, in __call__
return await self.inner(scope, receive, send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\sessions.py", line 47, in __call__
return await self.inner(dict(scope, cookies=cookies), receive, send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\sessions.py", line 263, in __call__
return await self.inner(wrapper.scope, receive, wrapper.send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\auth.py", line 185, in __call__
return await super().__call__(scope, receive, send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\middleware.py", line 24, in __call__
return await self.inner(scope, receive, send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\routing.py", line 116, in __call__
return await application(
File "D:\projects\TaxiTR\env\lib\site-packages\channels\consumer.py", line 94, in app
return await consumer(scope, receive, send)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\consumer.py", line 58, in __call__
await await_many_dispatch(
File "D:\projects\TaxiTR\env\lib\site-packages\channels\utils.py", line 50, in await_many_dispatch
await dispatch(result)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\consumer.py", line 73, in dispatch
await handler(message)
File "D:\projects\TaxiTR\env\lib\site-packages\channels\generic\websocket.py", line 173, in websocket_connect
await self.connect()
File "D:\projects\TaxiTR\ride\consumers.py", line 62, in connect
shift = await self.get_active_shift()
File "D:\projects\TaxiTR\ride\consumers.py", line 179, in get_active_shift
shift_data = ShiftDetailSerializer(shift).data
File "D:\projects\TaxiTR\env\lib\site-packages\rest_framework\serializers.py", line 555, in data
ret = super().data
File "D:\projects\TaxiTR\env\lib\site-packages\rest_framework\serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "D:\projects\TaxiTR\env\lib\site-packages\rest_framework\serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "D:\projects\TaxiTR\env\lib\site-packages\rest_framework\serializers.py", line 686, in to_representation
return [
File "D:\projects\TaxiTR\env\lib\site-packages\rest_framework\serializers.py", line 687, in <listcomp>
self.child.to_representation(item) for item in iterable
File "D:\projects\TaxiTR\env\lib\site-packages\rest_framework\serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "D:\projects\TaxiTR\env\lib\site-packages\rest_framework\serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "D:\projects\TaxiTR\env\lib\site-packages\rest_framework\relations.py", line 542, in to_representation
return [
File "D:\projects\TaxiTR\env\lib\site-packages\django\db\models\query.py", line 394, in __iter__
self._fetch_all()
File "D:\projects\TaxiTR\env\lib\site-packages\django\db\models\query.py", line 1866, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "D:\projects\TaxiTR\env\lib\site-packages\django\db\models\query.py", line 87, in __iter__
results = compiler.execute_sql(
File "D:\projects\TaxiTR\env\lib\site-packages\django\db\models\sql\compiler.py", line 1393, in execute_sql
cursor = self.connection.cursor()
File "D:\projects\TaxiTR\env\lib\site-packages\django\utils\asyncio.py", line 24, in inner
raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
but it works fine if many=False
My models:
`class Invoice(models.Model):
class PaymentMethod(models.TextChoices):
CASH = "CASH", _("Cash")
CREDIT = "CREDIT", _("Credit")
CONTRACT = "CONTRACT", _("Contract")
tips = models.FloatField(default=0, blank=True, null=True)
price = models.FloatField(default=0, blank=True, null=True)
expected_price = models.FloatField(default=0, blank=True, null=True)
passenger = models.CharField(max_length=100, blank=True, null=True)
client = models.IntegerField(blank=True, null=True)
payment_method = models.CharField(
max_length=50, choices=PaymentMethod.choices)
`
`
class Image(models.Model):
invoice = models.ForeignKey(
"invoices.Invoice", on_delete=models.CASCADE, related_name="images")
image = models.ImageField(upload_to=documents_path)
`
Serializers:
`class ImageSerializer(serializers.ModelSerializer):
image = serializers.ImageField(required=False)
class Meta:
model = Image
fields = ['image']
class InvoiceSerializer(serializers.ModelSerializer):
total_earnings = serializers.ReadOnlyField()
net = serializers.ReadOnlyField()
qst = serializers.ReadOnlyField()
gst = serializers.ReadOnlyField()
revendence = serializers.ReadOnlyField()
images = ImageSerializer(many=True, required=False)
class Meta:
model = Invoice
fields = [
"tips",
"price",
"passenger",
"client",
"total_earnings",
"net",
"qst",
"gst",
"revendence",
"images",
"id",
]
read_only_fields = ['id', ]
def create(self, validated_data):
images_data = self.context.get('request').FILES.getlist('images', None)
validated_data.pop('images', None)
invoice = Invoice.objects.create(**validated_data)
for image in images_data:
Image.objects.create(image=image, invoice=invoice)
return invoice
def update(self, instance, validated_data):
images_data = self.context.get('request').FILES.getlist('images', None)
if images_data:
instance.images.all().delete()
invoice_docs = [
Image(invoice=instance, image=image) for image in images_data
]
Image.objects.bulk_create(
invoice_docs
)
return super().update(instance, validated_data)
`
in my app i have many serializer have a field refer to another serializer with many=True and works fine but in this one it give me this error , i searched with the error but doesn't find any question like mine so i hope someone can help
the problem was because of when acessing invoice.images that run a new database query which is a sync so i edited my invoice manager to prefetch images when fetch any invoice
class InvoiceManager(Manager):
def get_queryset(self):
return super().get_queryset().prefetch_related('images')

When trying to send a post request, a ZeroReturnError occurs

I use:
Python 2.7.6
ssl.OPENSSL_VERSION: 'OpenSSL 1.0.1f 6 Jan 2014'
I am communicating with a third party service which has TLSProtocol TLSV1.2.
I manage to successfully request an access token from the service.
It is also possible to send files to this service and pick up the names of these files assigned by the service.
Next, I generate data in json format and send it to this service. Here at this step I get ZeroReturnError.
It would be desirable to understand why connection is closed.
My guess is that this is because pyopenssl doesn't support TLS1.2 in python2.7.6.
But I doubt this guess, because the first request for a token and the second request for sending files pass.
My code:
def __init__(self):
self._logger = logging.getLogger("XXXXXXXX")
self._hostname = r'https://xxxxxx'
self._api = r'xxxxx'
self._client_id = 'xxxxxx'
self._secret = 'xxxxxx'
self._session = requests.session()
def get_token(self):
api_method = 'access_token'
url_get = r'{}/{}/{}/'.format(self._hostname, self._api, api_method)
payload = {'client_id': self._client_id, 'secret': self._secret}
response = self._session.get(url_get, params=payload, timeout=90, verify='/etc/cacert.pem')
self._logger.info('Request received successfully')
return response.json().get('token')
def send_files(self, owner_token=None, files=None):
api_method = 'file_upload'
url_post = r'{}/{}/{}/?token={}'.format(self._hostname, self._api, api_method, owner_token)
response = self._session.post(url_post, files=files, timeout=90, verify='/etc/cacert.pem')
self._logger.info('Files received successfully')
return response.json()
def send_data(self, owner_token=None, data=None):
api_method = 'submit_declaration'
url_post_data = r'{}/{}/{}/?token={}'.format(self._hostname, self._api, api_method, owner_token)
pattern = r'\{.*?\}'
response = self._session.post(url_post_data, data=data, timeout=90, verify='/etc/cacert.pem')
self._logger.info('Data received successfully')
result = re.findall(pattern, response.text)
if result:
return json.loads(result[0])
return
This is log:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 105, in get_response
response = middleware_method(request, callback, callback_args, callback_kwargs)
File "/var/www/*/common/timeit.py", line 13, in process_view
response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py", line 48, in view
return self.dispatch(request, *args, **kwargs)
File "/var/www/*/common/mixins.py", line 727, in dispatch
return super(UserToSchoolMixin, self).dispatch(request, *args, **kwargs)
File "/var/www/*/common/mixins.py", line 201, in dispatch
return super(SelectedObjectWithProtection, self).dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py", line 69, in dispatch
return handler(request, *args, **kwargs)
File "/var/www/*/views.py", line 1089, in post
response = staff_request.send_data(owner_token=owner_token, data=json_data)
File "/var/www/*/helpers_reqeust.py", line 56, in send_data
response = self._session.post(url_post_data, data=data, timeout=90, verify='/etc/cacert.pem')
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 509, in post
return self.request('POST', url, data=data, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 467, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 570, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 394, in send
r.content
File "/usr/lib/python2.7/dist-packages/requests/models.py", line 679, in content
self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
File "/usr/lib/python2.7/dist-packages/requests/models.py", line 616, in generate
decode_content=True):
File "/usr/lib/python2.7/dist-packages/urllib3/response.py", line 225, in stream
data = self.read(amt=amt, decode_content=decode_content)
File "/usr/lib/python2.7/dist-packages/urllib3/response.py", line 174, in read
data = self._fp.read(amt)
File "/usr/lib/python2.7/httplib.py", line 602, in read
s = self.fp.read(amt)
File "/usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.py", line 152, in read
data = self._sock.recv(left)
ZeroReturnError

Django jwt channels cannot verify

I use djangorestframework-simplejwt.
I have two Django Projects sharing the same database.
One is django-restframework
One is django-channels
django-restframework login will get JWT
I cannot verify successfully in django-channels
I wrote the test function
restframework verify ok
class Test(APIView):
def get(self, request):
try:
token = UntypedToken(
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.???.Z22plhyGEZW9IBZLzICu2mWTkuMrblYQhvUGoUtpKd0')
print(token, 'token') # output: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.???.Z22plhyGEZW9IBZLzICu2mWTkuMrblYQhvUGoUtpKd0
except (InvalidToken, TokenError):
print('InvalidToken, TokenError')
return Response(status=status.HTTP_200_OK)
channels verify error
#database_sync_to_async
def test_get_user():
try:
token = UntypedToken(
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.???.Z22plhyGEZW9IBZLzICu2mWTkuMrblYQhvUGoUtpKd0')
print(token, 'token')
except (InvalidToken, TokenError) as e:
print('InvalidToken, TokenError', e) # output InvalidToken, TokenError Token is invalid or expired
Can't verify JWT like this?
traceback
Exception inside application: Token is invalid or expired
Traceback (most recent call last):
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/rest_framework_simplejwt/backends.py", line 99, in decode
'verify_signature': verify,
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/jwt/api_jwt.py", line 119, in decode
decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/jwt/api_jwt.py", line 95, in decode_complete
**kwargs,
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/jwt/api_jws.py", line 152, in decode_complete
self._verify_signature(signing_input, header, signature, key, algorithms)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/jwt/api_jws.py", line 239, in _verify_signature
raise InvalidSignatureError("Signature verification failed")
jwt.exceptions.InvalidSignatureError: Signature verification failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/rest_framework_simplejwt/tokens.py", line 43, in __init__
self.payload = token_backend.decode(token, verify=verify)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/rest_framework_simplejwt/backends.py", line 105, in decode
raise TokenBackendError(_('Token is invalid or expired'))
rest_framework_simplejwt.exceptions.TokenBackendError: Token is invalid or expired
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/staticfiles.py", line 44, in __call__
return await self.application(scope, receive, send)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/routing.py", line 71, in __call__
return await application(scope, receive, send)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/sessions.py", line 47, in __call__
return await self.inner(dict(scope, cookies=cookies), receive, send)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/sessions.py", line 263, in __call__
return await self.inner(wrapper.scope, receive, wrapper.send)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/auth.py", line 185, in __call__
return await super().__call__(scope, receive, send)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/middleware.py", line 26, in __call__
return await self.inner(scope, receive, send)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/routing.py", line 160, in __call__
send,
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/consumer.py", line 94, in app
return await consumer(scope, receive, send)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/consumer.py", line 59, in __call__
[receive, self.channel_receive], self.dispatch
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/utils.py", line 51, in await_many_dispatch
await dispatch(result)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/consumer.py", line 73, in dispatch
await handler(message)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/generic/websocket.py", line 173, in websocket_connect
await self.connect()
File "/home/user/Daniel/Python/GitLab/django-signalserver/WebSocket/consumers.py", line 147, in connect
await test_get_user()
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/asgiref/sync.py", line 444, in __call__
ret = await asyncio.wait_for(future, timeout=None)
File "/usr/lib/python3.7/asyncio/tasks.py", line 414, in wait_for
return await fut
File "/usr/lib/python3.7/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/db.py", line 13, in thread_handler
return super().thread_handler(loop, *args, **kwargs)
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/asgiref/sync.py", line 486, in thread_handler
return func(*args, **kwargs)
File "/home/user/Daniel/Python/GitLab/django-signalserver/WebSocket/consumers.py", line 127, in test_get_user
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.???.Z22plhyGEZW9IBZLzICu2mWTkuMrblYQhvUGoUtpKd0')
File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/rest_framework_simplejwt/tokens.py", line 45, in __init__
raise TokenError(_('Token is invalid or expired'))
rest_framework_simplejwt.exceptions.TokenError: Token is invalid or expired
Because i don't know how jwt verifies
Now I found that the verification method is SECRET_KEY in settings.py
As long as different projects use the same SECRET_KEY.
There is no problem with JWT authentication.

django-rest-auth: register an active user for my tests

I'm trying to write some tests with django-rest-auth and the following code:
def create_user(username='john', email='johndoe#test.com', password='doe'):
user = get_user_model().objects.create(
username=username,
email=email,
is_active=False)
if password:
user.set_password(password)
else:
user.set_unusable_password()
user.save()
return user
def test_jwt_auth():
username = 'user'
email = 'user#foo.com'
password = 'pass'
create_user(username=username, email=email, password=password)
resp = client.post(REST_LOGIN_URL, {'email': email, 'password': password})
assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
The client.post work fine as long as I don't change/create the user with is_active=True. When I do I get the following error:
Error
Traceback (most recent call last):
File "C:\Users\Ekami\Documents\workspace\NomadSpeed-Web\users\tests.py", line 64, in test_jwt_auth
resp = self.client.post(REST_LOGIN_URL, {'email': email, 'password': password})
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\test.py", line 300, in post
path, data=data, format=format, content_type=content_type, **extra)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\test.py", line 213, in post
return self.generic('POST', path, data, content_type, **extra)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\test.py", line 238, in generic
method, path, data, content_type, secure, **extra)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\test\client.py", line 422, in generic
return self.request(**r)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\test.py", line 289, in request
return super(APIClient, self).request(**kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\test.py", line 241, in request
request = super(APIRequestFactory, self).request(**kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\test\client.py", line 503, in request
raise exc_value
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\utils\decorators.py", line 45, in _wrapper
return bound_method(*args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\views\decorators\debug.py", line 76, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_auth\views.py", line 49, in dispatch
return super(LoginView, self).dispatch(*args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_auth\views.py", line 103, in post
self.serializer.is_valid(raise_exception=True)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\serializers.py", line 236, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_framework\serializers.py", line 437, in run_validation
value = self.validate(value)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\rest_auth\serializers.py", line 108, in validate
email_address = user.emailaddress_set.get(email=user.email)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\nomad\lib\site-packages\django\db\models\query.py", line 408, in get
self.model._meta.object_name
allauth.account.models.EmailAddress.DoesNotExist: EmailAddress matching query does not exist.
I have no idea how to bypass this error. I need my user to be active with a validated email to continue my test. Any idea? Thank you.
create_user is looking to me as a BaseUserManager so perhaps you should be change it to look like this
def create_user(self, username=None, email=None, password=None):
if not username:
raise ValueError('Users must have an Username')
if not email:
raise ValueError('Users must have an email address')
try:
user = self.get(email=self.normalize_email(email))
except self.model.DoesNotExist:
user = self.model(username=username, email=self.normalize_email(email))
password_validation.validate_password(password)
user.set_password(password)
return user
now you can pass user params and test.

Attribute error for list of objects from collection?

We're using Flask-Restful for implementing an API. As database we use MongoDB and MongoEngine as ODM. To get MongoEngine to work with Restful, we followed this blog article. For getting the correct json-format we using the builtin marsheling-methods. This works perfectly for single objects (e.g. one item of a collection), but when marsheling a list of objects (e.g. all items of a collection), an AttributeError is raised (although we use the same syntax as for single objects). This is how our model and our views look like (I don't paste the routes, as they are in a separate file and work).
model:
class Task(db.Document):
name = db.StringField()
description_mini = db.StringField()
views:
parser = reqparse.RequestParser()
parser.add_argument('task_id', type=str)
task_format = {
"name": fields.String,
"description_mini": fields.String
}
class TasksView(Resource):
#marshal_with(task_format)
def get(self):
tasks = Task.objects().all()
return tasks, 200
class TaskDetailView(Resource):
#marshal_with(task_format)
def get(self):
args = parser.parse_args()
startup_id = args['task_id']
task = Task.objects(id=task_id).first()
return task, 200
full stacktrace:
AttributeError
Traceback (most recent call last)
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 257, in error_router
return self.handle_error(e)
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 257, in error_router
return self.handle_error(e)
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/project/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 397, in wrapper
resp = resource(*args, **kwargs)
File "/project/venv/lib/python2.7/site-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 487, in dispatch_request
resp = meth(*args, **kwargs)
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 562, in wrapper
return marshal(data, self.fields), code, headers
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 533, in marshal
return OrderedDict(items)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/collections.py", line 52, in __init__
self.__update(*args, **kwds)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_abcoll.py", line 547, in update
for key, value in other:
File "/project/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 532, in <genexpr>
for k, v in fields.items())
File "/project/venv/lib/python2.7/site-packages/flask_restful/fields.py", line 104, in output
value = get_value(key if self.attribute is None else self.attribute, obj)
File "/project/venv/lib/python2.7/site-packages/flask_restful/fields.py", line 37, in get_value
return _get_value_for_keys(key.split('.'), obj, default)
File "/project/venv/lib/python2.7/site-packages/flask_restful/fields.py", line 42, in _get_value_for_keys
return _get_value_for_key(keys[0], obj, default)
File "/project/venv/lib/python2.7/site-packages/flask_restful/fields.py", line 51, in _get_value_for_key
return obj[key]
File "/project/venv/lib/python2.7/site-packages/mongoengine/queryset/base.py", line 152, in __getitem__
raise AttributeError
AttributeError
When you want to marshal a list you have to define the fields as a list as well.
I think this will work:
task_list_format = {
'tasks': fields.List(fields.Nested(task_format))
}
class TasksView(Resource):
#marshal_with(task_list_format)
def get(self):
tasks = Task.objects().all()
return { 'tasks': tasks }, 200
I believe it is not possible to return a plain list using the marshaling support in Flask-RESTful, it always expects a dictionary. For that reason I put the list under a "tasks" key.
I hope this helps.
From what I understand, the problem is that mongoengine's Queryset object lazily queries the database and that Flask-restful/restplus marshalling expects a list.
I could make it work with
task_format = {
"name": fields.String,
"description_mini": fields.String
}
class TasksView(Resource):
#marshal_with(task_format)
def get(self):
tasks = Task.objects().all()
return list(tasks)
try flask_restful.marshal_with_fields:
>>> from flask_restful import marshal_with_field, fields
>>> #marshal_with_field(fields.List(fields.Integer))
... def get():
... return ['1', 2, 3.0]
...
>>> get()
[1, 2, 3]