Python script with access to an SMB device

I try running a python script on my router. (First time using python)

from smb.SMBConnection import SMBConnection

I assume a module for smb connection is missing. How could I install it on my turris Omnia?

Hello @Mannshoch, you should read on the β€œvirtual environment” topics on python. For example: Python Virtual Environments: A Primer – Real Python

In short you need to create a sandboxed environment where you will be able to download / install libraries (in your case pysmb.

Currently there is a bug on omnia which prevents you to do the virtualenv the β€œeasy way”, I found a solution here: Python3 venv failed - #3 by sandor.balazsi

user@omnia:~$ python3 -m venv venv --without-pip
user@omnia:~$ source venv/bin/activate
(venv) user@omnia:~$ wget https://bootstrap.pypa.io/get-pip.py
--2023-11-14 10:20:23--  https://bootstrap.pypa.io/get-pip.py
Resolving bootstrap.pypa.io... 151.101.0.175, 151.101.64.175, 151.101.128.175, ...
Connecting to bootstrap.pypa.io|151.101.0.175|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2632263 (2.5M) [text/x-python]
Saving to: β€˜get-pip.py’

get-pip.py                                   100%[==============================================================================================>]   2.51M  --.-KB/s    in 0.1s

2023-11-14 10:20:24 (19.5 MB/s) - β€˜get-pip.py’ saved [2632263/2632263]

(venv) user@omnia:~$ python3 get-pip.py
Collecting pip
  Downloading pip-23.3.1-py3-none-any.whl.metadata (3.5 kB)
Collecting setuptools
  Downloading setuptools-68.2.2-py3-none-any.whl.metadata (6.3 kB)
Collecting wheel
  Downloading wheel-0.41.3-py3-none-any.whl.metadata (2.2 kB)
Downloading pip-23.3.1-py3-none-any.whl (2.1 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 10.1 MB/s eta 0:00:00
Downloading setuptools-68.2.2-py3-none-any.whl (807 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 13.5 MB/s eta 0:00:00
Downloading wheel-0.41.3-py3-none-any.whl (65 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.8/65.8 kB 5.5 MB/s eta 0:00:00
Installing collected packages: wheel, setuptools, pip
Successfully installed pip-23.3.1 setuptools-68.2.2 wheel-0.41.3
(venv) user@omnia:~$ pip3 install pysmb
Collecting pysmb
  Downloading pysmb-1.2.9.1.zip (1.4 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 10.2 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Collecting pyasn1 (from pysmb)
  Downloading pyasn1-0.5.0-py2.py3-none-any.whl (83 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 83.9/83.9 kB 6.9 MB/s eta 0:00:00
Collecting tqdm (from pysmb)
  Downloading tqdm-4.66.1-py3-none-any.whl.metadata (57 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 57.6/57.6 kB 5.2 MB/s eta 0:00:00
Downloading tqdm-4.66.1-py3-none-any.whl (78 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 78.3/78.3 kB 6.9 MB/s eta 0:00:00
Building wheels for collected packages: pysmb
  Building wheel for pysmb (setup.py) ... done
  Created wheel for pysmb: filename=pysmb-1.2.9.1-py3-none-any.whl size=84803 sha256=879139aca5711dac858303a017b56d6e4872220e536c575ce7fc4c3b5aaa6c22
  Stored in directory: /tmp/.cache/wheels/79/fb/86/032760e32fad1d9277f6ace4664fd1e946cb763711948ec2bb
Successfully built pysmb
Installing collected packages: tqdm, pyasn1, pysmb
Successfully installed pyasn1-0.5.0 pysmb-1.2.9.1 tqdm-4.66.1
(venv) user@omnia:~$ python3
Python 3.9.18 (main, Oct 09 2023, 18:02:40)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from smb.SMBConnection import SMBConnection
>>>
(venv) user@omnia:~$

When you work on your script you always need to do the β€œsource venv/bin/activate” (venv == your name of virtual environment).

To turn off virtual environment just type β€œdeactivate”

1 Like

thanks I will try it according that.

I will use my turris Omnia as a Proxy for internet communication of a device for Backup that itself do not have Internet access. Internet β†’ Script on Turris β†’ smb share.

Do you know how the command should look like in cron if I wish to start the script?

With a virtualenvironment something like this: How to schedule a python script cron job that have packages in virtual environment? - Unix & Linux Stack Exchange

So if your virtualenv is named β€œvenv” and in your home dir, create a bash script:

#!/bin/bash
source /home/user/venv/bin/activate
cd /path/to/python_script/
python3 script.py
deactivate

After this mark it executable:

chmod 755 /home/user/bash_script.sh

And add your script to crontab (you can use luci for this):

5 4 * * * /home/user/bash_script.sh

For crontab time you can use: https://crontab.guru/

1 Like

The virtual environment seems working as you described. But I need webdavclient3 for my script. if in install it with pip I get the error:

  /tmp/pip-install-xyp1xomd/lxml_bc14a101e71146cbbe99cf59428d5c7b/setup.py:67: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
    import pkg_resources
  Building lxml version 4.9.3.
  Building without Cython.
  Error: Please make sure the libxml2 and libxslt development packages are installed.
  [end of output]

Do you have an Idea how to solve that?

that package seems to be pretty old, found this: webdav4

That installed without problem.

Thanks a lot, that works.
You seems really skilled. My you also know a library for saving files to smb?
A script I have use smbprotocol, but that library do not work on turris omnia. I found pysmb, but this library seems not able to save files in chunks. (needed for huge files).
My goal at the end is to download huge files ~ 4GB from DAVS to a SMB drive.

Hello, yes if you install pysmb you can chunk in python directly. Found a example script (I did not test this, so be careful):

from smb.SMBConnection import SMBConnection

def upload_file_to_smb(local_file_path, smb_share, smb_username, smb_password, smb_host, smb_folder):
    # Create an SMB connection
    conn = SMBConnection(smb_username, smb_password, 'your-client-name', 'smb-server-name', use_ntlm_v2=True)
    
    try:
        # Connect to the SMB server
        if conn.connect(smb_host, 445):
            with open(local_file_path, 'rb') as local_file:
                # Specify the remote file path on the SMB share
                remote_file_path = f'\\{smb_folder}\\{local_file_path.split("/")[-1]}'
                
                # Create the remote file on the SMB share
                file_attributes = conn.createFile(smb_share, remote_file_path, accessMode=2)

                # Upload the file in chunks
                while True:
                    chunk = local_file.read(8192)  # 8 KB chunks
                    if not chunk:
                        break
                    conn.writeFile(smb_share, remote_file_path, chunk, file_attributes)

                # Close the remote file
                conn.closeFile(smb_share, file_attributes)

    finally:
        # Disconnect from the SMB server
        conn.close()

# Example usage
local_file_path = 'path/to/local/file.txt'
smb_share = 'your_smb_share'
smb_username = 'your_smb_username'
smb_password = 'your_smb_password'
smb_host = 'smb_server_ip'
smb_folder = 'remote_folder'

upload_file_to_smb(local_file_path, smb_share, smb_username, smb_password, smb_host, smb_folder)

Thanks a lot for your support until now. Currently I have a Problem with GCC, it seems that turris has a not compartible gcc. All pip installs I do with involves gcc not work. It seems many tools need something called cffi. Do you know a way getting either gcc work or do this job on another pc?

I am not aware of this directly, but made a quick check and I see:

python3-cffi - 1.14.6-3.9-1 - Foreign Function Interface for Python calling C code.
python3-cffi-src - 1.14.6-3.9-1 - Foreign Function Interface for Python calling C code.  This package contains the Python source files for python3-cffi.

available in the turris repository, did you try to install it via OPKG ?

1 Like

Yes, It was my first try to find the software in the Repo.

So even with installation of this package you receive some kind of error?
Any details would help out in debugging.