well i have same view same setting for celery in another app, when i launch another one, he is work, absolutely work, but when i launch this, nothing, i installed everthyng like in another one, but nothing, pls help me!
if you have some ideas how to fix please let me know)
This is full traceback
Traceback (most recent call last):
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\utils\__init__.py", line 423, in __call__
return self.__value__
AttributeError: 'ChannelPromise' object has no attribute '__value__'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 449, in _ensured
return fun(*args, **kwargs)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\messaging.py", line 177, in _publish
channel = self.channel
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\messaging.py", line 194, in _get_channel
channel = self._channel = channel()
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\utils\__init__.py", line 425, in __call__
value = self.__value__ = self.__contract__()
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\messaging.py", line 209, in <lambda>
channel = ChannelPromise(lambda: connection.default_channel)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 771, in default_channel
self.connection
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 756, in connection
self._connection = self._establish_connection()
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 711, in _establish_connection
conn = self.transport.establish_connection()
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\transport\pyamqp.py", line 116, in establish_connection
conn = self.Connection(**opts)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\amqp\connection.py", line 165, in __init__
self.transport = self.Transport(host, connect_timeout, ssl)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\amqp\connection.py", line 186, in Transport
return create_transport(host, connect_timeout, ssl)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\amqp\transport.py", line 299, in create_transport
return TCPTransport(host, connect_timeout)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\amqp\transport.py", line 95, in __init__
raise socket.error(last_err)
OSError: [WinError 10061]The connection is not established, because the destination computer rejected the connection request
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\django\utils\decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\src\accounts\decorators.py", line 25, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\src\accounts\views.py", line 41, in signup
register_task.delay(username, password, email, get_secret_key)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\celery\app\task.py", line 453, in delay
return self.apply_async(args, kwargs)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\celery\app\task.py", line 559, in apply_async
**dict(self._get_exec_options(), **options)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\celery\app\base.py", line 353, in send_task
reply_to=reply_to or self.oid, **options
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\celery\app\amqp.py", line 305, in publish_task
**kwargs
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\messaging.py", line 172, in publish
routing_key, mandatory, immediate, exchange, declare)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 470, in _ensured
interval_max)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 382, in ensure_connection
interval_start, interval_step, interval_max, callback)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\utils\__init__.py", line 246, in retry_over_time
return fun(*args, **kwargs)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 250, in connect
return self.connection
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 756, in connection
self._connection = self._establish_connection()
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\connection.py", line 711, in _establish_connection
conn = self.transport.establish_connection()
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\kombu\transport\pyamqp.py", line 116, in establish_connection
conn = self.Connection(**opts)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\amqp\connection.py", line 165, in __init__
self.transport = self.Transport(host, connect_timeout, ssl)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\amqp\connection.py", line 186, in Transport
return create_transport(host, connect_timeout, ssl)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\amqp\transport.py", line 299, in create_transport
return TCPTransport(host, connect_timeout)
File "C:\Users\P.A.N.D.E.M.I.C\Desktop\shop\lib\site-packages\amqp\transport.py", line 95, in __init__
raise socket.error(last_err)
OSError: [WinError 10061] `The connection is not established, because the destination computer rejected the connection request`
this is celery
from __future__ import absolute_import
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'src.settings')
from django.conf import settings
from celery import Celery
app = Celery('src')
# This reads, e.g., CELERY_ACCEPT_CONTENT = ['json'] from settings.py:
app.config_from_object('django.conf:settings')
# For autodiscover_tasks to work, you must define your tasks in a file called 'tasks.py'.
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
#app.task(bind=True)
def debug_task(self):
print("Request: {0!r}".format(self.request))
this is settings
# CELERY STUFF
BROKER_URL = 'redis://127.0.0.1:6379'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = TIME_ZONE
this is view
#csrf_protect
#check_recaptcha
def signup(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
print(form)
if form.is_valid() and request.recaptcha_is_valid:
print(form.cleaned_data)
email = form.cleaned_data['email']
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
get_secret_key = activation_key_generator(username)
link = "127.0.0.1:8000/accounts/activate/{0}".format(get_secret_key)
html_message = '<h3>Your username: <b>{0}</b> <br> <b>Your password: <b>{1}</b></h3><br><h1>That to get full access to our services, go through link below!</h1> <br> Activate need raw link? <br> {2}'.format(username, password, link)
register_task.delay(username, password, email, get_secret_key)
send_some_email_task.delay(email, username, html_message)
return redirect('/accounts/register/verification')
form = RegistrationForm(request.POST or None)
context = {'form':form}
return render(request, 'accounts/registration/signup.html', context)
You said in the comments you are using Redis but the configuration you have is for RabbitMQ. Check Using Redis page for more info on configuration. More specifically, your broker URL should be something like redis://:password#hostname:port/db_number, not amqp.
Related
I want to send reset password email using Celery. I try to override the reset_password method of the class djoser.views.UserViewSet:
class CustomUserViewSet(UserViewSet):
#action(["post"], detail=False)
def reset_password(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.get_user()
if user:
send_reset_password_email.delay(
self.request,
{'user': user},
[get_user_email(user)]
)
return Response(status=status.HTTP_200_OK)
But I get an error:
Traceback (most recent call last):
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 39, in _reraise_errors
yield
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 210, in dumps
payload = encoder(data)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\utils\json.py", line 68, in dumps
return _dumps(s, cls=cls or _default_encoder,
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\utils\json.py", line 58, in default
return super().default(o)
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Request is not JSON serializable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Dev\rich-peach\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Dev\rich-peach\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Dev\rich-peach\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Dev\rich-peach\backend\api\views.py", line 51, in reset_password
send_reset_password_email.delay(
File "C:\Dev\rich-peach\venv\lib\site-packages\celery\app\task.py", line 425, in delay
return self.apply_async(args, kwargs)
File "C:\Dev\rich-peach\venv\lib\site-packages\celery\app\task.py", line 575, in apply_async
return app.send_task(
File "C:\Dev\rich-peach\venv\lib\site-packages\celery\app\base.py", line 788, in send_task
amqp.send_task_message(P, name, message, **options)
File "C:\Dev\rich-peach\venv\lib\site-packages\celery\app\amqp.py", line 510, in send_task_message
ret = producer.publish(
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\messaging.py", line 166, in publish
body, content_type, content_encoding = self._prepare(
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\messaging.py", line 254, in _prepare
body) = dumps(body, serializer=serializer)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 209, in dumps
with _reraise_errors(EncodeError):
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 153, in __exit__
self.gen.throw(typ, value, traceback)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 43, in _reraise_errors
reraise(wrapper, wrapper(exc), sys.exc_info()[2])
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\exceptions.py", line 21, in reraise
raise value.with_traceback(tb)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 39, in _reraise_errors
yield
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 210, in dumps
payload = encoder(data)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\utils\json.py", line 68, in dumps
return _dumps(s, cls=cls or _default_encoder,
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\utils\json.py", line 58, in default
return super().default(o)
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
kombu.exceptions.EncodeError: Object of type Request is not JSON serializable
Celery task:
#app.task(bind=True, default_retry_delay=5 * 60)
def send_reset_password_email(self, request, context, email):
try:
PasswordResetEmail(request, context).send(email)
except Exception as exc:
raise self.retry(exc=exc, countdown=60)
What I've already tried:
I tried to change the serializer for the task to 'pickle':
#app.task(bind=True, default_retry_delay=5 * 60, serializer='pickle')
But I get a new error:
Traceback (most recent call last):
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 39, in _reraise_errors
yield
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 210, in dumps
payload = encoder(data)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 334, in pickle_dumps
return dumper(obj, protocol=pickle_protocol)
TypeError: cannot pickle '_io.BufferedReader' object
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Dev\rich-peach\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Dev\rich-peach\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Dev\rich-peach\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Dev\rich-peach\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Dev\rich-peach\backend\api\views.py", line 51, in reset_password
send_reset_password_email.delay(
File "C:\Dev\rich-peach\venv\lib\site-packages\celery\app\task.py", line 425, in delay
return self.apply_async(args, kwargs)
File "C:\Dev\rich-peach\venv\lib\site-packages\celery\app\task.py", line 575, in apply_async
return app.send_task(
File "C:\Dev\rich-peach\venv\lib\site-packages\celery\app\base.py", line 788, in send_task
amqp.send_task_message(P, name, message, **options)
File "C:\Dev\rich-peach\venv\lib\site-packages\celery\app\amqp.py", line 510, in send_task_message
ret = producer.publish(
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\messaging.py", line 166, in publish
body, content_type, content_encoding = self._prepare(
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\messaging.py", line 254, in _prepare
body) = dumps(body, serializer=serializer)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 209, in dumps
with _reraise_errors(EncodeError):
File "C:\Users\lev_k\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 153, in __exit__
self.gen.throw(typ, value, traceback)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 43, in _reraise_errors
reraise(wrapper, wrapper(exc), sys.exc_info()[2])
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\exceptions.py", line 21, in reraise
raise value.with_traceback(tb)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 39, in _reraise_errors
yield
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 210, in dumps
payload = encoder(data)
File "C:\Dev\rich-peach\venv\lib\site-packages\kombu\serialization.py", line 334, in pickle_dumps
return dumper(obj, protocol=pickle_protocol)
kombu.exceptions.EncodeError: cannot pickle '_io.BufferedReader' object
How can I solve this problem?
Or how else can I do it?
Problem solved!
Instead of request, I pass the necessary fields to context, and instead of user - user.id:
#action(['post'], detail=False)
def reset_password(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.get_user()
if user:
send_reset_password_email.delay(
{
'user_id': user.id,
'domain': request.get_host(),
'protocol': 'https' if request.is_secure() else 'http',
'site_name': request.get_host()
},
[get_user_email(user)]
)
return Response(status=status.HTTP_200_OK)
This works because if you don't send a request to Password Reset E-mail, Djoser searches for the necessary fields in context:
class BaseEmailMessage(mail.EmailMultiAlternatives, ContextMixin):
def get_context_data(self, **kwargs):
ctx = super(BaseEmailMessage, self).get_context_data(**kwargs)
context = dict(ctx, **self.context)
if self.request:
site = get_current_site(self.request)
domain = context.get('domain') or (
getattr(settings, 'DOMAIN', '') or site.domain
)
protocol = context.get('protocol') or (
'https' if self.request.is_secure() else 'http'
)
site_name = context.get('site_name') or (
getattr(settings, 'SITE_NAME', '') or site.name
)
user = context.get('user') or self.request.user
else:
domain = context.get('domain') or getattr(settings, 'DOMAIN', '')
protocol = context.get('protocol') or 'http'
site_name = context.get('site_name') or getattr(
settings, 'SITE_NAME', ''
)
user = context.get('user')
context.update({
'domain': domain,
'protocol': protocol,
'site_name': site_name,
'user': user
})
return context
And in the task, I get the user by id, which I passed to context:
#app.task(bind=True, default_retry_delay=5 * 60)
def send_reset_password_email(self, context, email):
try:
context['user'] = CustomUser.objects.get(id=context.get('user_id'))
PasswordResetEmail(context=context).send(email)
except Exception as exc:
raise self.retry(exc=exc, countdown=60)
I want to perform a redirect in one of my view, and I'm facing an error with not many details.
My urls.py:
urlpatterns = [
url(
regex=r'^(?P<pk>[0-9]+)/$',
view=views.SheetDetailView.as_view(),
name='detail'
),
url(
regex=r'^(?P<pk>[0-9]+)/branch/(?P<branch_slug>[a-zA-Z0-9-]+)/$',
view=views.SheetDetailView.as_view(),
name='detail'
),
]
My view
class SheetDetailView(LoginRequiredMixin, UserIsLinkedToSheetMixin, UserPassesTestMixin, DetailView):
model = Sheet
def get_context_data(self, **kwargs):
context = super(SheetDetailView, self).get_context_data(**kwargs)
#if no branch is requested, show the master
if 'branch_slug' in self.kwargs:
branch = self.get_object().get_branch(self.kwargs['branch_slug'])
context['branch']=branch
return context
else:
# redirect to master
sheet_id = self.get_object().pk
branch_slug = self.get_object().get_master().slug
return redirect(reverse('sheets:detail', kwargs={'pk':sheet_id, 'branch_slug':branch_slug}), permanent=False)
And my error message:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
return self.application(environ, start_response)
File "/usr/local/lib/python3.5/site-packages/django/core/handlers/wsgi.py", line 177, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 230, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 289, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/usr/local/lib/python3.5/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.5/site-packages/six.py", line 686, in reraise
raise value
File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 174, in get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 172, in get_response
response = response.render()
File "/usr/local/lib/python3.5/site-packages/django/template/response.py", line 160, in render
self.content = self.rendered_content
File "/usr/local/lib/python3.5/site-packages/django/template/response.py", line 137, in rendered_content
content = template.render(context, self._request)
File "/usr/local/lib/python3.5/site-packages/django/template/backends/django.py", line 92, in render
context = make_context(context, request)
File "/usr/local/lib/python3.5/site-packages/django/template/context.py", line 291, in make_context
context.push(original_context)
File "/usr/local/lib/python3.5/site-packages/django/template/context.py", line 61, in push
return ContextDict(self, *dicts, **kwargs)
File "/usr/local/lib/python3.5/site-packages/django/template/context.py", line 20, in __init__
super(ContextDict, self).__init__(*args, **kwargs)
ValueError: dictionary update sequence element #0 has length 0; 2 is required
When I print out the reverse() result and paste it into my browser, everything is OK.
You're trying to return a redirect from get_context_data. But that method is supposed to return a context for rendering a template, as the name implies. You probably need to put that particular piece of logic in get or dispatch instead.
I am starting a brand new project that involves Flask + SQLAlchemy with pymysql. Currently, creation of tables based on model fails with the following:
The lines in my code (main.py) leading up to the error are:
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://myapp:myapp#localhost/myapp'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
guid = db.Column(db.String(255), unique=True)
def __init__(self):
self.guid = str(uuid.uuid1())
db.create_all()
# Note: We don't need to call run() since our application is embedded within
# the App Engine WSGI application server.
#app.route('/')
def hello():
"""Return a friendly HTTP greeting."""
return 'Hello World!'
#app.errorhandler(404)
def page_not_found(e):
"""Return a custom 404 error."""
return 'Sorry, nothing at this URL.', 404
Traceback (most recent call last):
File "/Users/myuserid/Documents/Development/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/Users/myuserid/Documents/Development/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
handler, path, err = LoadObject(self._handler)
File "/Users/myuserid/Documents/Development/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject
obj = __import__(path[0])
File "/Users/myuserid/Documents/Development/myapp-server/main.py", line 9, in <module>
db.create_all()
File "/Users/myuserid/Documents/Development/myapp-server/lib/flask_sqlalchemy/__init__.py", line 895, in create_all
self._execute_for_all_tables(app, bind, 'create_all')
File "/Users/myuserid/Documents/Development/myapp-server/lib/flask_sqlalchemy/__init__.py", line 887, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/sql/schema.py", line 3614, in create_all
tables=tables)
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/engine/base.py", line 1850, in _run_visitor
with self._optional_conn_ctx_manager(connection) as conn:
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/engine/base.py", line 1843, in _optional_conn_ctx_manager
with self.contextual_connect() as conn:
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/engine/base.py", line 2034, in contextual_connect
self._wrap_pool_connect(self.pool.connect, None),
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/engine/base.py", line 2069, in _wrap_pool_connect
return fn()
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/pool.py", line 376, in connect
return _ConnectionFairy._checkout(self)
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/pool.py", line 708, in _checkout
fairy = _ConnectionRecord.checkout(pool)
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/pool.py", line 480, in checkout
rec = pool._do_get()
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/pool.py", line 1049, in _do_get
self._dec_overflow()
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/util/langhelpers.py", line 60, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/pool.py", line 1046, in _do_get
return self._create_connection()
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/pool.py", line 323, in _create_connection
return _ConnectionRecord(self)
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/pool.py", line 449, in __init__
self.connection = self.__connect()
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/pool.py", line 602, in __connect
connection = self.__pool._invoke_creator(self)
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/engine/strategies.py", line 97, in connect
return dialect.connect(*cargs, **cparams)
File "/Users/myuserid/Documents/Development/myapp-server/lib/sqlalchemy/engine/default.py", line 377, in connect
return self.dbapi.connect(*cargs, **cparams)
File "/Users/myuserid/Documents/Development/myapp-server/lib/pymysql/__init__.py", line 88, in Connect
return Connection(*args, **kwargs)
File "/Users/myuserid/Documents/Development/myapp-server/lib/pymysql/connections.py", line 644, in __init__
self._connect()
File "/Users/myuserid/Documents/Development/myapp-server/lib/pymysql/connections.py", line 837, in _connect
self._get_server_information()
File "/Users/myuserid/Documents/Development/myapp-server/lib/pymysql/connections.py", line 1048, in _get_server_information
packet = self._read_packet()
File "/Users/myuserid/Documents/Development/myapp-server/lib/pymysql/connections.py", line 882, in _read_packet
packet_header = self._read_bytes(4)
File "/Users/myuserid/Documents/Development/myapp-server/lib/pymysql/connections.py", line 899, in _read_bytes
data = self._rfile.read(num_bytes)
File "/Users/myuserid/Documents/Development/myapp-server/lib/pymysql/_socketio.py", line 64, in readinto
n = e.args[0]
IndexError: tuple index out of range
INFO 2015-05-05 23:30:40,803 module.py:788] default: "GET / HTTP/1.1" 500 -
I have a Django + Celery setup working correctly in production with RabbitMQ.
AFAIK, it should be sufficient to set CELERY_ALWAYS_EAGER to True in django settings locally, to avoid setting up RabbitMQ for development. I have done this but when calling .delay() on a task I get:
Traceback (most recent call last):
File "lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "lib/python2.7/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "lib/python2.7/site-packages/django/views/generic/base.py", line 89, in dispatch
return handler(request, *args, **kwargs)
File "lib/python2.7/site-packages/django/views/generic/edit.py", line 215, in post
return self.form_valid(form)
File "app/web/views.py", line 188, in form_valid
form.send_email()
File "app/web/forms.py", line 17, in send_email
send_email.delay(mail, recipients, 'Contact %s' % name, comment)
File "lib/python2.7/site-packages/celery/app/task.py", line 453, in delay
return self.apply_async(args, kwargs)
File "lib/python2.7/site-packages/celery/app/task.py", line 559, in apply_async
**dict(self._get_exec_options(), **options)
File "lib/python2.7/site-packages/celery/app/base.py", line 353, in send_task
reply_to=reply_to or self.oid, **options
File "lib/python2.7/site-packages/celery/app/amqp.py", line 305, in publish_task
**kwargs
File "lib/python2.7/site-packages/kombu/messaging.py", line 172, in publish
routing_key, mandatory, immediate, exchange, declare)
File "lib/python2.7/site-packages/kombu/connection.py", line 457, in _ensured
interval_max)
File "lib/python2.7/site-packages/kombu/connection.py", line 369, in ensure_connection
interval_start, interval_step, interval_max, callback)
File "lib/python2.7/site-packages/kombu/utils/__init__.py", line 243, in retry_over_time
return fun(*args, **kwargs)
File "lib/python2.7/site-packages/kombu/connection.py", line 237, in connect
return self.connection
File "lib/python2.7/site-packages/kombu/connection.py", line 741, in connection
self._connection = self._establish_connection()
File "lib/python2.7/site-packages/kombu/connection.py", line 696, in _establish_connection
conn = self.transport.establish_connection()
File "lib/python2.7/site-packages/kombu/transport/librabbitmq.py", line 123, in establish_connection
conn = self.Connection(**opts)
File "lib/python2.7/site-packages/librabbitmq/__init__.py", line 199, in __init__
self.connect()
ConnectionError: Error opening socket: a socket error occurred
For the record, since celery 4.0 this setting has been renamed to task_always_eager:
# setting renamed on celery 4.0
CELERY_ALWAYS_EAGER --> task_always_eager
To help the migration to this version, Celery provides the following util to update automatically your settings:
# --django allows to keep uppercase settings and CELERY_ prefix
$ celery upgrade settings proj/settings.py --django
So I have found the problem. Basically I was missing:
from .celery import app as celery_app
in proj/proj/__init__.py
For some misterious reason this seems to fail only when running runserver and not when running wsgi.py via uWSGI. Not sure why, but with the import it works on runserver too.
I have Flask application and implemented RPC in it.
engine.py
import pickle
import pika
from databasyfacade.rpc import api
__author__ = 'Marboni'
def on_request(ch, method, props, body):
request = pickle.loads(body)
func = getattr(api, request['func'])
try:
result = func(*request['args'])
except Exception, e:
response = {
'status': 'ERROR',
'error': e
}
else:
response = {
'status': 'OK',
'result': result
}
ch.basic_publish(exchange='',
routing_key=props.reply_to,
properties=pika.BasicProperties(
correlation_id=props.correlation_id
),
body=pickle.dumps(response)
)
ch.basic_ack(delivery_tag=method.delivery_tag)
def init(host):
connection = pika.BlockingConnection(pika.ConnectionParameters(host))
channel = connection.channel()
channel.queue_declare(queue='facade_rpc')
channel.basic_qos(prefetch_count=1)
channel.basic_consume(on_request, queue='facade_rpc')
api.py
from databasyfacade.services import profiles_service
__author__ = 'Marboni'
def profile(user_id):
return profiles_service.profile(user_id)
When Flask application initializes, it runs method init(host).
Now I need to test how my application responses to RPC calls. So I wrote following RPC client:
client.py
import pickle
import uuid
import pika
__author__ = 'Marboni'
class RpcClient(object):
def __init__(self, host):
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=host))
self.channel = self.connection.channel()
result = self.channel.queue_declare(exclusive=True)
self.callback_queue = result.method.queue
self.channel.basic_consume(self.on_response, no_ack=True, queue=self.callback_queue)
def on_response(self, ch, method, props, body):
if self.corr_id == props.correlation_id:
self.response = body
def call(self, func, *args):
request = {
'func': func,
'args': args
}
self.response = None
self.corr_id = str(uuid.uuid4())
self.channel.basic_publish(exchange='',
routing_key='facade_rpc',
properties=pika.BasicProperties(
reply_to = self.callback_queue,
correlation_id = self.corr_id,
),
body=pickle.dumps(request))
while self.response is None:
self.connection.process_data_events()
response = pickle.loads(self.response)
if response['status'] == 'ERROR':
e = response['error']
raise e
else:
return response['result']
Then I wrote test based on Flask-Testing framework. It initializes Flask application between each test method, so we can interact with it.
tests.py
from databasyfacade.rpc import RpcClient
from databasyfacade.testing import DatabasyTest, fixtures
from databasyfacade.testing.testdata import UserData, ProfileData
__author__ = 'Marboni'
class RpcTest(DatabasyTest):
#fixtures(UserData, ProfileData)
def test_profile(self, data):
rpc = RpcClient(self.app.config['RABBITMQ_HOST'])
profile = rpc.call('profile', ProfileData.hero.user_id)
self.assertIsNotNone(profile)
self.assertEqual(ProfileData.hero.email, profile.email)
This test hangs when makes call. It iterates infinitely here:
From client.py
while self.response is None:
self.connection.process_data_events()
It means that on_response() method on client never called.
If I interrupt my tests with CTRL-C, I will see following stacktrace:
Traceback (most recent call last):
File "../env/bin/nosetests", line 8, in <module>
load_entry_point('nose==1.3.0', 'console_scripts', 'nosetests')()
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/core.py", line 118, in __init__
**extra_args)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/main.py", line 95, in __init__
self.runTests()
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/core.py", line 197, in runTests
result = self.testRunner.run(self.test)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/core.py", line 61, in run
test(result)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 176, in __call__
return self.run(*arg, **kw)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 223, in run
test(orig)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/suite.py", line 65, in __call__
return self.run(*args, **kwds)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 74, in run
test(result)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 176, in __call__
return self.run(*arg, **kw)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 223, in run
test(orig)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 176, in __call__
return self.run(*arg, **kw)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 223, in run
test(orig)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 176, in __call__
return self.run(*arg, **kw)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 223, in run
test(orig)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 176, in __call__
return self.run(*arg, **kw)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 223, in run
test(orig)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 176, in __call__
return self.run(*arg, **kw)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/suite.py", line 223, in run
test(orig)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/case.py", line 45, in __call__
return self.run(*arg, **kwarg)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/case.py", line 133, in run
self.runTest(result)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/nose/case.py", line 151, in runTest
test(result)
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/flask_testing.py", line 72, in __call__
self._pre_setup()
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/flask_testing.py", line 80, in _pre_setup
self.app = self.create_app()
File "/Users/Marboni/Projects/Databasy/databasy-facade/databasyfacade/databasyfacade/testing/__init__.py", line 12, in create_app
return app.create_app()
File "/Users/Marboni/Projects/Databasy/databasy-facade/databasyfacade/databasyfacade/app.py", line 75, in create_app
init_rpc(app)
File "/Users/Marboni/Projects/Databasy/databasy-facade/databasyfacade/databasyfacade/app.py", line 63, in init_rpc
rpc.init(app.config['RABBITMQ_HOST'])
File "/Users/Marboni/Projects/Databasy/databasy-facade/databasyfacade/databasyfacade/rpc/engine.py", line 39, in init
channel.basic_consume(on_request, queue='facade_rpc')
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/pika/channel.py", line 220, in basic_consume
{'consumer_tag': consumer_tag})])
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/pika/adapters/blocking_connection.py", line 1104, in _rpc
self._wait_on_response(method_frame))
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/pika/adapters/blocking_connection.py", line 1124, in _send_method
self.connection.process_data_events()
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/pika/adapters/blocking_connection.py", line 215, in process_data_events
if self._handle_read():
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/pika/adapters/blocking_connection.py", line 327, in _handle_read
if self._read_poller.ready():
File "/Users/Marboni/Projects/Databasy/databasy-facade/env/lib/python2.7/site-packages/pika/adapters/blocking_connection.py", line 66, in ready
self.poll_timeout)
KeyboardInterrupt
I tried to run application and access it from separate script:
#!/usr/bin/env python
from databasyfacade.rpc.client import RpcClient
rpc = RpcClient('localhost')
profile = rpc.call('profile', 4L)
print profile.email
As you can see, code is the same as in test, but in this case it works.
What can be the cause of this issue? May be, it's because Flask-Testing runs both application and client in one process? How to check it / write correct test?
I found the cause, it's not related with MQ. Remove method accessed database using SQLAlchemy with scoped_session. Problem disappeared after I finalized session properly:
Session.remove()