jborean93 / smbprotocol

Python SMBv2 and v3 Client
MIT License
318 stars 73 forks source link

error in smbprotocol python svcript #284

Closed alberto-fraccarollo closed 1 month ago

alberto-fraccarollo commented 1 month ago

Hi, I'm writing a python script to transfer file to s3 with smb file gateway on AWS.

I recieve two errors in vscode:

bum smbprotocol is corrected installed. How I could fix it.

Regards

(my script below)

import os
import random
import time
from concurrent.futures import ThreadPoolExecutor, as_completed

try:
    from smbprotocol.connection import Connection
    from smbprotocol.share import Share
    from smbprotocol.file import File
except ImportError as e:
    print("Error importing SMB Protocol modules. Ensure you have installed the 'smbprotocol' package.")
    raise e  # Raise the error for further handling

# Establishes a connection to the SMB share
class SMBConnection:
    def __init__(self, server_ip, share_name):
        self.server_ip = server_ip
        self.share_name = share_name
        self.connection = Connection(uuid=random.uuid4(), server=self.server_ip, port=445)
        self.share = None

    def connect(self):
        self.connection.connect()
        self.share = Share(self.connection, self.share_name)
        print(f"Connected to SMB share at {self.server_ip}/{self.share_name}")

    def upload_file(self, local_path, remote_path):
        # Open the file to upload
        with open(local_path, 'rb') as local_file:
            # Create a new file in the SMB share
            remote_file = File(self.share, remote_path)
            remote_file.create()
            remote_file.write(local_file.read())  # Upload the entire file
            remote_file.close()
            file_size = os.path.getsize(local_path)
        return file_size

# Function to create dummy files to upload
def create_dummy_files(directory, num_files, size_range):
    os.makedirs(directory, exist_ok=True)
    for i in range(num_files):
        filename = f"file_{i + 1}.txt"
        file_path = os.path.join(directory, filename)
        file_size = random.randint(*size_range)
        with open(file_path, 'wb') as f:
            f.write(os.urandom(file_size))

# Function to handle file uploads
def upload_file(conn, local_path, remote_path, user):
    start_time = time.time()
    file_size = conn.upload_file(local_path, remote_path)
    end_time = time.time()
    upload_time = end_time - start_time
    return user, os.path.basename(local_path), file_size, upload_time

# Main function to execute the upload process
def main():
    # Configuration parameters for the upload process
    server_ip = "192.168.xxx.xxx"
    share_name = "pelicanproject-tst-docswebsmb"
    local_directory = r"C:\Users\alberto.f\Downloads\test-upload-files-smb-python"
    remote_directory = "Docsweb/device/AWS_TEST_WW/WW0000001B/0000000000/0000000000/0000000007-Alberto-test/"
    num_files = 100
    file_size_range = (1 * 1024 * 1024, 5 * 1024 * 1024)  # File size between 1 MB and 5 MB
    num_users = 10  # Number of users

    # Ensure the local directory exists and create dummy files if it's empty
    os.makedirs(local_directory, exist_ok=True)
    if not os.listdir(local_directory):
        create_dummy_files(local_directory, num_files, file_size_range)

    # Establish a connection to the remote SMB share
    conn = SMBConnection(server_ip, share_name)
    conn.connect()

    # Prepare tasks for uploading files
    upload_tasks = [
        (conn, os.path.join(local_directory, filename),
         os.path.join(remote_directory, filename),
         f"User{user}")
        for user in range(1, num_users + 1)
        for filename in os.listdir(local_directory)
    ]

    # Execute uploads in parallel using a thread pool
    results = []
    with ThreadPoolExecutor(max_workers=10) as executor:
        future_to_task = {executor.submit(upload_file, *task): task for task in upload_tasks}

        for future in as_completed(future_to_task):
            results.append(future.result())

    # Save upload process results to a file
    results_file = os.path.join(local_directory, "results.txt")
    with open(results_file, "w") as f:
        f.write("User,Filename,FileSize (MB),UploadTime (seconds)\n")
        for result in results:
            f.write(f"{result[0]},{result[1]},{result[2] / (1024 * 1024):.2f},{result[3]:.4f}\n")

    print(f"The upload process is complete. Results saved in {results_file}")

# Entry point for the script
if __name__ == "__main__":
    main()
jborean93 commented 1 month ago

There is no smbprotocol.share and smbprotocol.file which is why the error is happening. You might be better off using the high level API in smbclient which makes it a lot simpler to do things like copy a file or read/write to a file.

alberto-fraccarollo commented 1 month ago

Hi #jborean93, thanks for your suppport. I fix it!

Best regards