Start / stop external threads from usage.py (button)

Hello Dash community,

I’ve got a problem,

I’m trying to start and stop my threads with Buttons in usage.py
It work if my thread is in the main app (usage.py) but I’d like to externalise the threads.

A button:

html.Button(
      id='nav_power_btn',
      value='navigation',
      n_clicks=0
),

A callback:

@app.callback(
    Output('nav_power_btn', 'children'),
    [Input('nav_power_btn', 'n_clicks')])
def nav_power(n_clicks):
    # on initie le producer
    ip_address = '0.0.0.0'
    port_eth = 13002
    thread_producer = Thread(target=Producer, args=(1, ip_address, port_eth))

    if n_clicks == 0:
        return 'START'

    elif n_clicks % 2 != 0:
        print(n_clicks)
        thread_producer.stop()
        return 'START'

    elif n_clicks % 2 == 0:
        print(n_clicks)
        thread_producer.start()
        return 'STOP'

A Thread

import datetime
import socket
import sqlite3
import xml.etree.ElementTree as ET
from collections import deque
from threading import Thread

class Producer(Thread):
*get data from UDP device / While=True*

Currently I got exception
Exception in thread Thread-1772:

Traceback (most recent call last):
  File "C:\Users\aphilipp\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 926, in _bootstrap_inner
    self.run()
  File "C:\Users\aphilipp\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
TypeError: 'module' object is not callable

My question is:
Is it possible to externalise the Threads in independents files ? Must I use some tools like Celery / Redis to do it ?

Thanks for your time

It is generally a bad pattern to kill a thread abruptly, in Python, and in any language. Think of the following cases:

  • the thread is holding a critical resource that must be closed properly
  • the thread has created several other threads that must be killed as well.

If you REALLY need to use a Thread, there is no way to kill thread directly. What you can do, however, is to use a “daemon thread”. In fact, in Python, a Thread can be flagged as daemon:

If you do NOT really need to have a Thread , what you can do, instead of using the threading package , is to use the multiprocessing package . Here, to kill a process, you can simply call the method:

yourProcess.terminate()

Python will kill your process (on Unix through the SIGTERM signal, while on Windows through the TerminateProcess() call). Pay attention to use it while using a Queue or a Pipe! (it may corrupt the data in the Queue/Pipe)