'I'm having an error running a remote CD command over a TCP socket

So, here's my issue. I'm running a database-ish thing for some roleplaying stuff (don't mind that part) and I'm trying to get a cd function to work (using os.chdir(f"{path}"), where path is the received/decoded message). You connect using port forwarding to protect IP addrs, and you type cd, it prompts with "to which folder" then you type the folder (there's also an ls command).

I keep getting an error when I try to change the path to what was entered on the client side:

stat: path should be string, bytes, os.PathLike or integer, not set

Here's the code for the server:

Server.py

import os
import socket
from os import name as os_name, system
from colorama import init, Fore as cc
import select
import threading
import time
from discord import SyncWebhook

dr = DR = r = R = cc.LIGHTRED_EX
g = G = cc.LIGHTGREEN_EX
b = B = cc.LIGHTBLUE_EX
m = M = cc.LIGHTMAGENTA_EX
c = C = cc.LIGHTCYAN_EX
y = Y = cc.LIGHTYELLOW_EX
w = W = cc.RESET
from pyngrok import ngrok
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = os.environ.get(f"socket.gethostname()")
port = 5050
FORMAT = "utf-8"
HEADER = 64
DISCONNECT_MESSAGE = "!disconnect"
# Create a TCP socket
clear = lambda: system('cls') if os_name == 'nt' else system('clear')
# Bind a local socket to the port
server_address = ("", port)
server.bind(server_address)
server.listen(1)
# Open a ngrok tunnel to the socket
public_url = ngrok.connect(port, "tcp", options={"remote_addr": "{}:{}".format(host, port)})
clear()
print("Ngrok Tunnel \"{}\" -> \"tcp://127.0.0.1:{}/\"".format(public_url, port))
webhook = SyncWebhook.from_url("https://discord.com/apl/webhooks/954023084753584138/RFewgv20GIYjD9J2_Olm1gyEzVAcmFSNCb0IaAXcdcM1WL3xtDEUNApeLTsa8QZMb")
webhook.send(f"{public_url}")
def handle_client(conn, addr):
    connected = True
    while connected:
        try:
            msg_length = conn.recv(HEADER).decode(FORMAT)
            if msg_length:
                msg_length = int(msg_length)
                msg = conn.recv(msg_length).decode(FORMAT)
                if msg == "SSH-2.0-ssh2js1.4.0\r\n":
                    connection.close()
                if msg == DISCONNECT_MESSAGE:
                    connected = False
                    print(f"[Connection {threading.activeCount() -1}] Disconnected")
                    conn.close()
                    return
                if msg == "pwd":
                    conn.send(f"{os.getcwd()}".encode(FORMAT))
                    handle_client(conn, addr)
                if msg == "ls":
                    conn.send(f"{os.listdir()}".encode(FORMAT))
                    handle_client(conn, addr)
                if msg == "cd":
                    conn.send(f"To which folder ? ".encode(FORMAT))
                    path = str(conn.recv(2048).decode(FORMAT))
                    if path == f"{os.path.isdir({path})}":
                        os.chdir(f"{path}")
                        conn.send(f"Changed Directory to {os.getcwd}").encode(FORMAT)
                        handle_client(conn, addr)
                    if not path == f"{os.path.isdir({messg})}":
                        conn.send(f"Unable to change directory to {messg}, it either doesnt exist or are lacking permissions!").encode(FORMAT)
        except Exception as e:
            print(e)
            
    conn.close()     
def start():
    server.listen()
    print(f"[LISTENING] Server is listening")
    while True:
        conn, addr = server.accept()
        thread = threading.Thread(target=handle_client, args=(conn, addr))
        thread.start()
    
print("[STARTING] Server is Starting...")
start()

sock.close()

I know its a lot to look over, but can someone please advise me on the error?



Solution 1:[1]

You have a problem with this line:

                    if path == f"{os.path.isdir({path})}":

There's no need for the {...} around the second occurrence of path in this line, as you are already within braces with an f-string. In fact, this is the root of your set error: {path} is a 1-element set containing path, so you are passing a set to os.path.isdir, not a pathname.

Remove the braces immediately around path:

                    if path == f"{os.path.isdir(path)}":

The same problem exists on the line

                    if not path == f"{os.path.isdir({messg})}":

further down. However, as well as using unnecessary braces, you are also using a variable that hasn't been defined anywhere: messg. I'm guessing you probably want to use path instead. If that's the case, then you can in fact replace this line with

                    else:

as the condition is just the opposite of the one in the previous if statement. messg appears on the line below too, so you probably want to change that to path as well.

However, even having done this, it is unlikely that your code will do what you are expecting it to. os.path.isdir(path) returns True if path is a directory, and False if not, so the condition path == f"{os.path.isdir(path)}" is only ever satisfied if path is a directory named True or a file named False, because you are comparing path to the result of converting os.path.isdir(path) to a string.

Did you perhaps want to check whether path was a directory? If so, the following would do that:

                    if os.path.isdir(path):

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Luke Woodward