Django can't start multiple Threads

Hi, I’m trying to build a Django application that requires to spawn multiple threads other than the main one of the Django server itself.

However, I’m encountering this weird behaviour: Django is able to start one of the two threads that my application requires to use but when i add the other two therads in both apps.py and settings.py, I’m greeted with the following error code in the django console:

django.core.exceptions.ImproperlyConfigured: Cannot import ‘grafico’. Check that ‘pages.apps.InizializzaThreadGrafico.name’ is correct

I also tried to check for typos in the code but I didn’t find any typos in the code so far.

I also can’t use extrnal multitherading libraries such as celery due to project contraints

I put the code for both my apps.py (Thread declaration) and settings.py

I also put the stackoverflow limks that i have used to implement the multithread part with django

[Link 1] (python - How to start a background thread when django server is up? - Stack Overflow)

[Link 2] (python - How to avoid AppConfig.ready() method running twice in Django - Stack Overflow)

Thank you in advance for the support

apps.py

import os
from threading import Thread
from django.apps import AppConfig

# pages application declaration
class PagesConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'pages'

# filtra_dati_unico application declaration
class InizializzaThreadFiltraDati(AppConfig):
    name = 'filtra_dati_unico'
    
    def ready(self):
        FiltraDatiThread.daemon = True
        run_once = os.environ.get('CMDLINERUNNER_RUN_ONCE') 
        if run_once is not None:
            return
        os.environ['CMDLINERUNNER_RUN_ONCE'] = 'True'
        FiltraDatiThread().start()

# Application declaration grafico_impianto
class InizializzaThreadGrafico(AppConfig):
    name = 'grafico_impianto'
    
    def ready(self):
        GraficoThread.daemon = True
        run_once = os.environ.get('CMDLINERUNNER_RUN_ONCE') 
        if run_once is not None:
            return
        os.environ['CMDLINERUNNER_RUN_ONCE'] = 'True'
        GraficoThread().start()

# Thread FiltraDati declaration
class FiltraDatiThread(Thread):
    def run(self):
        print('Thread FiltraDati initialized')

# Thread GraficoThread Initialization
class GraficoThread(Thread):
    def run(self):
        print('Thread GraficoThread initialized')

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'bootstrap5',
    'pages.apps.PagesConfig',
    # Custom app definition (Threads)
    'pages.apps.InizializzaThreadFiltraDati', 
    'pages.apps.InizializzaThreadGrafico',
]

Don’t try to do this.

This is an excuse, not a reason.

Always keep in mind that “you” do not have control over the process itself in which Django runs. Your Django code runs within some type of wsgi container such as gunicorn or uwsgi. As a result, you have no control over when this process is started or stopped.

If you need a task to run longer than the life of an individual request, use Celery or some other kind of worker job queue.

Hi,

thank yor for the feedback! I appriciate it.

Since it’s my first Django, project, I will need some time to understand how to do things in the best way possibile.

I will try to use Celery in my projecy like you suggested.

Thank you again for the feedback

From your code it appears that you’re trying to run several different services from the same application code base but each in different threads?

Consider creating a different wsgi app with your other applications. Look into the generated Django files. You’ll essentially then contain your applications in the same codebase.

You can execute each application separately. Threads might not be the right call to isolate your services because you ideally want each service to work run with as many threads as possible.

———

Why not? It’ll be more productive to explain to OP why their approach is unusual and suboptimal rather than issuing what sounds like an edict.

I do not understand why you think a developer that configures and executes their application in production doesn’t have control over the process where the application executes.

Both of these are highly configurable providing the developer with a high degree of control.

You can run uwsgi and disable threading.

There is a spectrum of options available to the developer to run their jobs everywhere from within a sliver of a request, to over or after several requests. The environment and specifics of how their request and app works are all configurable and Django is just a Python app.

It doesn’t make sense why you would post a blanket statement like this. Django is not a serverless framework. Should cache operations end after a request is completed? Should the database be reinitialized for each request?

I’m sorry but I was confused by your response when I stumbled across this thread for a completely unrelated reason.

Note that the word “you” is in quotes. This is a reference to your Django code running within the Django framework. Your code - your views and models - have no control over the process in which it is running.

But not from within your Django code.

You need to understand my response from within the context of the question from a person writing code in a view to start and stop threads.

Yes, taken out of context, my answer would be misleading.

However, given that the question is asking about running threads from within the app, I stand by my answer as written. Starting background threads within your app is a bad idea.