Python Forum

Full Version: Access a variable of a daemon
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,
Hope you are doing well.

I have the following code

#!/usr/bin/env python3
# encoding: utf-8

import daemon
import sys
import time

class Loader:
    token_length = 0
    @staticmethod
    def get():
    	return token_length

    @staticmethod
    def start():
        with daemon.DaemonContext(stdout=sys.stdout):
                print("Daemon Started!!")
                token_length = 1000
                while True:
                	pass


if __name__ == '__main__':
    if 'start' == sys.argv[1]:
        Loader.start()
    elif 'get' == sys.argv[1]:
    	print(Loader.get())
    else:
        print("Invalid option")
When I do ./daemon_demo.py start, according to me it should start and assign a value to token_length. Now when I try to access this value using ./daemon_demo.py get, I get an error "NameError: name 'token_length' is not defined".
Please help me with this.

In general, what I am trying to do is have a daemon load all the static files(which includes a few text files and a huge machine learning model) and use this loaded information repeatedly in a main script.

Thank you for the help
Stay safe
A static method can neither modify object state nor class state. https://realpython.com/instance-class-an...ic-methods

Additionally, in your __main__ code, it looks like you want to call from the command line. However, your Loader object is not global to your machine. You may start your Loader in one window and let the loop run, but when you try Loader.get in another window it will not access the started Loader. It does not know it even exists.
You want to access the class attribute, then use a classmethod.
A staticmethod has no reference to the instance nor the class.

@classmethod
def get(cls):
    return cls.token_length
It could be used with staticmethod, but it feels wrong:
class Loader:
    token_length = 0
    @staticmethod
    def get():
        return Loader.token_length
Thank you for taking out time to reply.

@BrendanD: I will be adding this to the path variable so that the daemon can be accessed from all terminal instances. The link was helpful

@DeaD_EyE: I have made the changes but I am not able to get the updated value of token

#!/usr/bin/env python3
# encoding: utf-8
 
import daemon
import sys
import time
 
class Loader:
    token_length = 0
    
    @classmethod
    def get(cls):
        return cls.token_length
    
    def start(self):
        token_length = 1000
        with daemon.DaemonContext(stdout=sys.stdout):
                print("Daemon Started!!")
                while True:
                    pass
 
 
if __name__ == '__main__':
    l = Loader()
    if 'start' == sys.argv[1]:
        l.start()
    elif 'get' == sys.argv[1]:
        print(Loader.get())
    else:
        print("Invalid option")
When I do "daemon_demo.py get", I get the value 0 but it should be 1000. I have also tried making start a class method. Still the value returned on "daemon_demo.py get" was 0. Can you please tell me why?

Thank You
Hmm. Can't find docs for python-daemon but I did a quick search of its code and found nothing called token_length. Have you written classes in python before? If you are accessing a daemon from a different python instance you must somehow "hook" into the existing daemon, possibly by its pid or by some other method that daemon provides. Python allows you to assign a property to a class (token_length in your code) but your daemon context has no clue as to the state of your Loader class, any other python instances will have no clue either.
Yes, I have written classes before. "token_length" is an attribute that I have defined. The aim is to set the value of a few variables when the daemon starts and get the values whenever I need it. Is there any way I can do that using such an approach? Can you suggest any alternative approaches?
From a little google-fu, I think you might be better off using Pyro4. I haven't used it, but it looks more like what you want i.e. inter-process communication.
Not an option. I cannot open a port on the client machine where I will be deploying the solution.
Oh, the joys of the corporate firewall...
You must be on linux if you are using daemon.
You might want to start here:
Networking and Interprocess Communication

If you don't have sockets, then you are left with files. The crap solution will be writing the value of token_length to a file. Without asyncio, you will be stuck with file-locking. Maybe some of this machinery is exposed through daemon?
There are python modules for file locking that would make this simpler. Let me know if you want a description of how I think file locking could be used.