Cookiecutter-django: Celery throwing ImproperlyConfigured error when adding new app

Created on 14 May 2018  路  6Comments  路  Source: pydanny/cookiecutter-django

  • I'm submitting a ...

    • [X] bug report
    • [ ] feature request
    • [ ] support request => Please do not submit support request here, see note at the top of this template.
  • Do you want to request a feature or report a bug?
    Report a bug; I swear

  • What is the current behavior?
    Adding a new app to my celery-enabled cookiecutter-django project results in an exception being thrown and both celerybeat and celeryworker unceremoniously exiting

  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem

I started a fresh Dockerized cookiecutter-django project. In the setup, I chose to use Celery. All of the containers started fine and everything just worked, until I added a bare-bones new app called reviews. The app is only 2 files, apps.py and models.py Both are dead-simple:

# apps.py
from django.apps import AppConfig
class ReviewConfig(AppConfig):
    name = 'reviews'
    verbose_name = 'Reviews'

# models.py
import uuid
from django.db import models
class Review(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

I added my app to base.py like so:

LOCAL_APPS = [
    'my_awesome_project.users.apps.UsersConfig',
    # Your stuff: custom apps go here
    'my_awesome_project.reviews.apps.ReviewConfig',
]

After doing this, both celeryworker and celerybeat throw this exception and exit:

celeryworker_1  | django.core.exceptions.ImproperlyConfigured: Cannot import 'reviews'. Check that 'my_awesome_project.reviews.apps.ReviewConfig.name' is correct.

Note that the django service still runs just fine and recognized the reviews app with no problem.

  • What is the expected behavior?
    The celeryworker and celerybeat services should recognize the new app and work as they did before the app was added

  • Please tell us about your environment:
    I'm using Docker, so I'm not sure what info to provide here

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

Here's the docker-compose output for celerybeat:

celerybeat_1    | PostgreSQL is up - continuing...
celerybeat_1    | + rm -f ./celerybeat.pid
celerybeat_1    | + celery -A my_awesome_project.taskapp beat -l INFO
celerybeat_1    | celery beat v3.1.25 (Cipater) is starting.
myawesomeproject_celeryworker_1 exited with code 1
celerybeat_1    | Traceback (most recent call last):
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/django/apps/config.py", line 143, in create
celerybeat_1    |     app_module = import_module(app_name)
celerybeat_1    |   File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
celerybeat_1    |     return _bootstrap._gcd_import(name[level:], package, level)
celerybeat_1    |   File "<frozen importlib._bootstrap>", line 994, in _gcd_import
celerybeat_1    |   File "<frozen importlib._bootstrap>", line 971, in _find_and_load
celerybeat_1    |   File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
celerybeat_1    | ModuleNotFoundError: No module named 'reviews'
celerybeat_1    |
celerybeat_1    | During handling of the above exception, another exception occurred:
celerybeat_1    |
celerybeat_1    | Traceback (most recent call last):
celerybeat_1    |   File "/usr/local/bin/celery", line 11, in <module>
celerybeat_1    |     sys.exit(main())
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/__main__.py", line 30, in main
celerybeat_1    |     main()
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/celery.py", line 81, in main
celerybeat_1    |     cmd.execute_from_commandline(argv)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/celery.py", line 793, in execute_from_commandline
celerybeat_1    |     super(CeleryCommand, self).execute_from_commandline(argv)))
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/base.py", line 311, in execute_from_commandline
celerybeat_1    |     return self.handle_argv(self.prog_name, argv[1:])
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/celery.py", line 785, in handle_argv
celerybeat_1    |     return self.execute(command, argv)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/celery.py", line 717, in execute
celerybeat_1    |     ).run_from_argv(self.prog_name, argv[1:], command=argv[0])
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/base.py", line 315, in run_from_argv
celerybeat_1    |     sys.argv if argv is None else argv, command)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/base.py", line 377, in handle_argv
celerybeat_1    |     return self(*args, **options)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/base.py", line 274, in __call__
celerybeat_1    |     ret = self.run(*args, **kwargs)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/bin/beat.py", line 79, in run
celerybeat_1    |     return beat().run()
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/apps/beat.py", line 81, in run
celerybeat_1    |     self.init_loader()
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/apps/beat.py", line 121, in init_loader
celerybeat_1    |     self.app.loader.init_worker()
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/loaders/base.py", line 128, in init_worker
celerybeat_1    |     self.import_default_modules()
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/loaders/base.py", line 116, in import_default_modules
celerybeat_1    |     signals.import_modules.send(sender=self.app)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/utils/dispatch/signal.py", line 166, in send
celerybeat_1    |     response = receiver(signal=self, sender=sender, **named)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/fixups/django.py", line 73, in on_import_modules
celerybeat_1    |     self.worker_fixup.validate_models()
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/celery/fixups/django.py", line 158, in validate_models
celerybeat_1    |     django_setup()
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/django/__init__.py", line 24, in setup
celerybeat_1    |     apps.populate(settings.INSTALLED_APPS)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/django/apps/registry.py", line 89, in populate
celerybeat_1    |     app_config = AppConfig.create(entry)
celerybeat_1    |   File "/usr/local/lib/python3.6/site-packages/django/apps/config.py", line 147, in create
celerybeat_1    |     app_name, mod_path, cls_name,
celerybeat_1    | django.core.exceptions.ImproperlyConfigured: Cannot import 'reviews'. Check that 'my_awesome_project.reviews.apps.ReviewConfig.name' is correct.

Most helpful comment

@radius probably the problem occurs, because the reviews app is inside the module my_awesome_project (side by side of users app and taskapp app), but the name parameter of your ReviewConfig should have included the "module_name.app_name", like :

# my_awesome_project/reviews/apps.py
from django.apps import AppConfig
class ReviewConfig(AppConfig):
    name = 'my_awesome_project.reviews'
    verbose_name = 'Reviews'

and NOT app_name like :

# my_awesome_project/reviews/apps.py
from django.apps import AppConfig
class ReviewConfig(AppConfig):
    name = 'reviews'
    verbose_name = 'Reviews'

All 6 comments

@radius probably the problem occurs, because the reviews app is inside the module my_awesome_project (side by side of users app and taskapp app), but the name parameter of your ReviewConfig should have included the "module_name.app_name", like :

# my_awesome_project/reviews/apps.py
from django.apps import AppConfig
class ReviewConfig(AppConfig):
    name = 'my_awesome_project.reviews'
    verbose_name = 'Reviews'

and NOT app_name like :

# my_awesome_project/reviews/apps.py
from django.apps import AppConfig
class ReviewConfig(AppConfig):
    name = 'reviews'
    verbose_name = 'Reviews'

@radius, @luzfcb's suggestion sounds legit -- please, check it out and let us know about the outcome.

Wow, I'm an idiot. That totally solved the problem. Thanks @webyneter and @luzfcb . Closing this issue.

@radius, thanks @luzfcb for the thoughtful response, first and foremost. We're glad the issue's been resolved.

@luzfcb Thanks very much for the very helpful resolution. I appreciate you!
dd

This saved me today!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jayfk picture jayfk  路  4Comments

yunti picture yunti  路  4Comments

jsmedmar picture jsmedmar  路  3Comments

adammsteele picture adammsteele  路  3Comments

sebastian-code picture sebastian-code  路  4Comments