pysmb
pysmb is an experimental SMB/CIFS library written in Python that provides a pure Python implementation of the client-side SMB/CIFS protocol (SMB1 and SMB2). It enables Python applications to access and transfer files to and from SMB/CIFS shared folders, such as Windows file shares and Samba folders. The library is actively maintained, with the current version 1.2.13 released on September 19, 2025, and regular updates.
Warnings
- breaking pysmb version 1.0.0 introduced a complete rewrite of the library, making its API incompatible with previous versions (0.x.x). Applications written for 0.x.x will need significant updates.
- breaking In pysmb 1.2.0, the `deleteFiles()` and `storeFileFromOffset()` methods in `SMBProtocolFactory` and `SMBConnection` classes were updated. The `timeout` parameter now requires a named argument, and a new `delete_matching_folders` parameter was added to `deleteFiles()`.
- gotcha pysmb can conflict with other libraries like `impacket` if both are installed in the same environment, as they might both contain a file named `smbconnection.py`. This can lead to import errors or unexpected behavior due to name collisions.
- gotcha Attempting to reuse an `SMBConnection` instance by calling `connect()` again after a `close()` call (or a previous failed connection) might lead to an `UnboundLocalError` or `Connection reset by peer` errors. The connection state is not always properly reset for reuse.
- gotcha Users might encounter `smb.smb_structs.OperationFailure: Failed to list shares: Unable to connect to IPC$` when attempting to list shares. This error often indicates underlying network configuration issues, incorrect permissions, or server-side restrictions on accessing the IPC$ share, rather than a bug within `pysmb` itself.
Install
-
pip install pysmb
Imports
- SMBConnection
from smb.SMBConnection import SMBConnection
Quickstart
import os
import tempfile
from smb.SMBConnection import SMBConnection
# Replace with your SMB server details and credentials
SERVER_IP = os.environ.get('SMB_SERVER_IP', '127.0.0.1')
SERVER_NAME = os.environ.get('SMB_SERVER_NAME', 'MYSERVER') # Must match remote machine name
USER_ID = os.environ.get('SMB_USER_ID', 'guest')
PASSWORD = os.environ.get('SMB_PASSWORD', '')
CLIENT_MACHINE_NAME = os.environ.get('SMB_CLIENT_NAME', 'myclient') # Can be arbitrary
SHARE_NAME = os.environ.get('SMB_SHARE_NAME', 'public') # Example share name
REMOTE_FILE_PATH = os.environ.get('SMB_REMOTE_FILE_PATH', '/test.txt') # Path on the share
try:
conn = SMBConnection(USER_ID, PASSWORD, CLIENT_MACHINE_NAME, SERVER_NAME, use_ntlm_v2=True)
# Connect to the SMB server on port 445 (direct TCP) or 139 (NetBIOS session service)
connected = conn.connect(SERVER_IP, 445)
if connected:
print(f"Successfully connected to {SERVER_IP} with user {USER_ID}")
# Example: List shares (optional, sometimes IPC$ connection errors can occur)
try:
shares = conn.listShares()
print("Available shares:")
for share in shares:
print(f" - {share.name}")
except Exception as e:
print(f"Warning: Could not list shares (this might be expected for some configurations): {e}")
# Example: Retrieve a file
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
file_attributes, filesize = conn.retrieveFile(SHARE_NAME, REMOTE_FILE_PATH, temp_file)
print(f"Retrieved file '{REMOTE_FILE_PATH}' from share '{SHARE_NAME}'. Size: {filesize} bytes.")
print(f"Local copy saved to: {temp_file.name}")
# Always close the connection
conn.close()
print("Connection closed.")
else:
print(f"Failed to connect to {SERVER_IP}")
except Exception as e:
print(f"An error occurred: {e}")