PyRO 4 - lookup fails when I try to find a registered object
Question: I'm fighting against this problem for about a week, and I don't know anymore
where to look to find a solution.

As the title says, as soon as I successfully register a pyro object, I try to
find it on the NS, in order to operate with it, but the lookup fails.

I post a simplified version of my code, to make the situation more clear:

Server is the class in which the PyRO NS starts:

    
    
    import threading, socket, sys
    import Pyro4
    
    
    class Server():
    
        def __init__(self):
            self.start_ns_loop()
    
        def start_ns(self):
    
            print("Starting the Name Server...")
    
            try:
    
                Pyro4.naming.startNSloop()
    
            except socket.error:
    
                print("Name Server already running.")
                sys.exit(0)
    
        def start_ns_loop(self):
    
            ns_thread = threading.Thread(target=self.start_ns, args=[])
            ns_thread.daemon = True
            ns_thread.start()
    

TextAnalyzer class is the class that I use to do some statistics about a file:

    
    
        import nltk, argparse, Pyro4, socket
        class TextAnalyzer():
    
    
        def __init__(self):
            #init function in which I do all my things...
    
        '''after the init, I've some methods. I don't list them
        because they are not important in this discussion'''
    
        def get_ip_addr(self):
    
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect(("8.8.8.8", 80))
            ns_ip = str(s.getsockname()[0])
            s.close()
    
            return ns_ip
    
    
    def main():
    
        global nsip, PYRO_OBJ_NAME
        text_analyzer_name = "Text_Analyzer_"
    
        # Parser configuration for the input values
        parser = argparse.ArgumentParser(description="Values: ")
        parser.add_argument("-id", help="Sets the text analyzer ip.")
        parser.add_argument("-nsip", help="Sets the Name Server ip.")
        args = parser.parse_args()
    
        if args.id is not None:
            identifier = str(args.id)
        else:
            identifier = ""
    
        if args.nsip is not None:
            name_server_ip = str(args.nsip)
        else:
            name_server_ip = ""
    
        a = TextAnalyzer()
    
        try:
    
            if name_server_ip != "":
                nsip = Pyro4.naming.locateNS(name_server_ip)
            else:
                nsip = Pyro4.naming.locateNS()
    
            PYRO_OBJ_NAME = text_analyzer_name + str(identifier)
            print("PyRO Object name: " + PYRO_OBJ_NAME)
            daemon = Pyro4.Daemon(a.get_ip_addr())
    
            uri_text_analyzer = daemon.register(a)
            nsip.register(PYRO_OBJ_NAME, uri_text_analyzer, safe=True)
    
            print("URI " + PYRO_OBJ_NAME + ": " + str(uri_text_analyzer))
    
            daemon.requestLoop()
    
        except Pyro4.naming.NamingError as e:
    
            print(str(e))
    
    if __name__ == "__main__":
    
        main()
    

Connection class provides all methods useful to find the object on the NS,
sftp and ssh connection, finds the PID of the objects running, etc...

    
    
    import Pyro4, paramiko, socket, time
    from PyQt4 import QtCore, QtGui
    
    
    class Connection(QtGui.QMainWindow):
    
    def __init__(self):
    
        super(Connection, self).__init__()
    
        self.text_analyzer_name = "Text_Analyzer_"
        self.identifier = None
        self.address = None
        self.password = None
        self.object_pid = None
        self.authentication_ok = False
    
    def get_ip_addr(self):
    
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ns_ip = str(s.getsockname()[0])
        s.close()
        print(ns_ip)
        return ns_ip
    
    # This method finds the object on the NS
    def find_obj(self, identifier, a, p):
    
        self.identifier = identifier
        self.address = a
        self.password = p
    
        self.open_server_connection()
    
        time.sleep(5)
    
        if self.authentication_ok is True:
    
            try:
                ns = Pyro4.naming.locateNS()
                print("Return del locateNS(): " + str(ns))
                uri_text_analyzer = ns.lookup(self.text_analyzer_name + str(self.identifier))
                self.text_analyzer = Pyro4.Proxy(uri_text_analyzer)
                return True
    
            except Pyro4.errors.NamingError as e:
                print(str(e))
                self.ssh_connection_close_and_cleanup()
                return False
    
    def open_server_connection(self):
    
        print("Object ID: " + str(self.identifier))
    
        ssh_connection = paramiko.SSHClient()
    
        ssh_connection.load_system_host_keys()
    
        ssh_connection.set_missing_host_key_policy(paramiko.AutoAddPolicy)
    
        try:
            if str(self.address).__contains__('@'):
                (username, hostname) = self.address.split('@')
                print("User: " + username + ", Host: " + hostname)
                print("Tento la connessione.")
                ssh_connection.connect(str(hostname), username=username, password=str(self.password), timeout=5, allow_agent=False)
    
            else:
                ssh_connection.connect(str(self.address), password=str(self.password), timeout=5, allow_agent=False)
    
            self.authentication_ok = True
    
            ns_ip = self.get_ip_addr()
            sftp_connection = ssh_connection.open_sftp()
            print("Sftp connection open.")
            print("Transferring " + self.text_analyzer_name + str(self.identifier) + "...")
            sftp_connection.put("text_analyzer.py", "./text_analyzer.py")
            print("Transferring Pyro4...")
            sftp_connection.put("Pyro4.zip", "./Pyro4.zip")
            print("Unpacking...")
            stdin, stdout, stderr = ssh_connection.exec_command("tar -xzvf Pyro4.zip")
            time.sleep(3)
            print("Executing " + self.text_analyzer_name + str(self.identifier) + ":")
            stdin, stdout, stderr = ssh_connection.exec_command("echo $$; exec python3 text_analyzer.py -id {} -nsip {}".format(self.identifier, ns_ip))
    
            # Object PID saving
            self.object_pid = int(stdout.readline())
            print("PID del " + self.text_analyzer_name + str(self.identifier) + ": " + str(self.object_pid))
            # Connections close
            ssh_connection.close()
            sftp_connection.close()
    
        except (paramiko.AuthenticationException, socket.error) as e:
            self.authentication_ok = False
            ssh_connection.close()
            print("Connection failed, error: " + str(e))
    
    def ssh_connection_close_and_cleanup(self):
    
        ssh_connection = paramiko.SSHClient()
    
        ssh_connection.load_system_host_keys()
    
        ssh_connection.set_missing_host_key_policy(paramiko.AutoAddPolicy)
    
        try:
            if str(self.address).__contains__('@'):
                (username, hostname) = self.address.split('@')
                ssh_connection.connect(str(hostname), username=username, password=str(self.password), timeout=5, allow_agent=False)
            else:
                ssh_connection.connect(str(self.address), password=str(self.password), timeout=5, allow_agent=False)
    
            self.host = hostname
            print("Killing PID: " + str(self.object_pid))
            ssh_connection.exec_command("/bin/kill -KILL {}".format(self.object_pid))
            ssh_connection.exec_command("rm -r Pyro4")
            ssh_connection.exec_command("rm -r Pyro4.zip")
            ssh_connection.exec_command("rm text_analyzer.py")
            time.sleep(5)
    
            ssh_connection.close()
    
        except(paramiko.AuthenticationException, socket.error) as e:
            ssh_connection.close()
            print("Connection failed")
            print(str(e))
    

So, basically, this is what I'm doing.

The problem is that the lookup fails while trying to find the remote object on
the NS, inside the find_obj() method (contained within Connection class), but
I know for sure that the remote object was registered successfully.

The error given is "unknown name" from Pyro4.errors.NamingError.

I have really no clue why it isn't working...

Further specs: I'm running it on Mac OS X Mavericks, with PyRO 4 and Python
3.4.

Thanks in advance for your replies.


Answer: You can use the nsc tool to look in the name server's database. Make sure you
connect to the correct name server. You will see that the object you request
is really not in there. (Otherwise Pyro will hand you the uri).

Another tip might be to check that the name you're requesting is exactly the
same as what you registered with. Also check if you have multiple name servers
running perhaps, and is your code getting them mixed up maybe?

