Problem with running Python package from within LO

When I try to install pyexcel-ods I get the message that it is already installed…in my pipx environment, but LibreOffice is still unable to find it when I run the script. I know I have encountered this problem way back when I was starting out writing python script for LO…but (blush!) I have forgotten how to solve it!

Distributor ID: Ubuntu
Description: Ubuntu 23.10
Release: 23.10
Codename: mantic
LibreOffice LibreOffice 7.6.5.2 60(Build:2)
geany geany 1.38 (built on 2021-10-14 with GTK 3.24.30, GLib 2.68.4)
Python Python 3.11.6

Any help much appreciated.

At first: Check how LibreOffice is installed. While an install via APT/.deb usually uses the python installed in Ubuntu now the default is Snap for *buntu. The container may not see the installed python and can even bring its own.
.
I can’t look myself, as I have no Ubuntu her. My last installs were Mint and Debian, so without Snap…

1 Like

Yes I have Libreoffice snap installed.

Basically I an trying to determine correlation coefficients for two columns of numbers.

This is the error I am getting:

<class ‘ModuleNotFoundError’>: No module named ‘pyexcel_ods’

  File "/snap/libreoffice/315/lib/libreoffice/program/pythonscript.py", line 1058, in getScript
    mod = self.provCtx.getModuleByUrl( fileUri )
  File "/snap/libreoffice/315/lib/libreoffice/program/pythonscript.py", line 495, in getModuleByUrl
    exec(code, entry.module.__dict__)
  File "/home/yodap/snap/libreoffice/315/.config/libreoffice/4/user/Scripts/python/MyPythonLibrary/CorrCoeff.py", line 2, in <module>
    import pyexcel_ods
  File "/snap/libreoffice/315/lib/libreoffice/program/uno.py", line 346, in _uno_import
    return _builtin_import(name, *optargs, **kwargs)

Here is my code:

import pyexcel_ods
import pandas as pd

def calculate_correlation(data, data_columns, comparison_column):
    # Extract relevant columns
    selected_data = data[data_columns + [comparison_column]]

    # Calculate correlation
    correlation = selected_data.corr()[comparison_column]

    return correlation

def write_correlation_to_ods(correlation, output_file, cell):
    # Write correlation coefficient to the specified cell in the .ods file
    sheet = pyexcel_ods.get_sheet(file_name=output_file)
    sheet[cell] = correlation
    sheet.save_as(output_file)

I have run this through ChapGPT but it is not coming up with much in the way of answers.

Here is some more output from the command line:

yodap@yodap-NUC11:~$ pip list
Package               Version
--------------------- -------------------
argcomplete           2.0.0
attrs                 23.1.0
Babel                 2.10.3
bcrypt                3.2.2
beautifulsoup4        4.12.2
blinker               1.6.2
Brlapi                0.8.4
certifi               2022.9.24
chardet               5.1.0
click                 8.1.6
cloud-init            23.4.4
colorama              0.4.6
colorlog              6.7.0
command-not-found     0.3
configobj             5.0.8
cryptography          38.0.4
cupshelpers           1.0
dbus-python           1.3.2
defer                 1.0.6
defusedxml            0.7.1
distro                1.8.0
distro-info           1.5+ubuntu0.23.10.1
dnspython             2.4.1
duplicity             1.2.2
fasteners             0.17.3
freetype-py           2.4.0
future                0.18.2
ghp-import            2.1.0
gpg                   1.18.0
html5lib              1.1
httplib2              0.20.4
idna                  3.3
importlib-metadata    4.12.0
iniconfig             1.1.1
jaraco.classes        3.2.1
jeepney               0.8.0
Jinja2                3.1.2
joblib                1.2.0
jsonpatch             1.32
jsonpointer           2.0
jsonschema            4.10.3
keyring               24.2.0
language-selector     0.1
launchpadlib          1.11.0
lazr.restfulclient    0.14.5
lazr.uri              1.0.6
livereload            2.6.3
lml                   0.1.0
lockfile              0.12.2
louis                 3.26.0
lunr                  0.6.2
lxml                  4.9.3
Mako                  1.2.4.dev0
Markdown              3.4.4
markdown-it-py        3.0.0
MarkupSafe            2.1.3
mdurl                 0.1.2
mergedeep             1.3.4
mkdocs                1.4.2
monotonic             1.6
more-itertools        10.1.0
netifaces             0.11.0
nltk                  3.8.1
notify2               0.3
numpy                 1.24.2
oauthlib              3.2.2
odfpy                 1.4.1
olefile               0.46
packaging             23.1
paramiko              2.12.0
pexpect               4.8.0
Pillow                10.0.0
pip                   23.2
pipx                  1.2.0
pluggy                1.2.0
psutil                5.9.4
ptyprocess            0.7.0
pycairo               1.24.0
pycups                2.0.1
pyexcel-io            0.6.6
pyexcel-ods           0.6.0
Pygments              2.15.1
PyGObject             3.46.0
pyinotify             0.9.6
PyJWT                 2.7.0
PyNaCl                1.5.0
pyparsing             3.1.0
pyrsistent            0.18.1
pyserial              3.5
pytest                7.4.0
python-apt            2.6.0+ubuntu1
python-dateutil       2.8.2
python-debian         0.1.49+ubuntu2
pytz                  2023.3
pyxdg                 0.28
PyYAML                6.0.1
pyyaml_env_tag        0.1
regex                 2022.10.31
reportlab             4.0.4
requests              2.31.0
requests-toolbelt     1.0.0
rich                  13.3.1
rlPyCairo             0.3.0
SecretStorage         3.3.3
setuptools            68.1.2
Shredder              2.9.0 Odd Olm
simplejson            3.19.1
six                   1.16.0
soupsieve             2.4.1
systemd-python        235
tornado               6.3.2
tqdm                  4.64.1
ubuntu-drivers-common 0.0.0
ubuntu-pro-client     8001
ufw                   0.36.2
unattended-upgrades   0.1
urllib3               1.26.16
usb-creator           0.3.16
userpath              1.9.0
wadllib               1.3.6
watchdog              3.0.0
webencodings          0.5.1
wheel                 0.41.0
xdg                   5
xkit                  0.0.0
xlrd                  1.2.0
zim                   0.75.1
zipp                  1.0.0


yodap@yodap-NUC11:~$ pipx list
venvs are in /home/yodap/.local/pipx/venvs
apps are exposed on your $PATH at /home/yodap/.local/bin
   package pyexcel-ods 0.6.0, installed using Python 3.11.6
    - csv2ods
    - mailodf
    - odf2mht
    - odf2xhtml
    - odf2xml
    - odfimgimport
    - odflint
    - odfmeta
    - odfoutline
    - odfuserfield
    - xml2odf



yodap@yodap-NUC11:~$ /usr/bin/python3 -m pipx install pyexcel-ods 'pyexcel-ods' already seems to be installed. Not modifying existing installation in '/home/yodap/.local/pipx/venvs/pyexcel-ods'. Pass '--force' to force installation. yodap@yodap-NUC11:~$ /usr/bin/python3.11 -m pipx install pyexcel-ods 'pyexcel-ods' already seems to be installed. Not modifying existing installation in '/home/yodap/.local/pipx/venvs/pyexcel-ods'. Pass '--force' to force installation. yodap@yodap-NUC11:~$ /usr/bin/python3.11 -m pipx install pyexcel_ods 'pyexcel-ods' already seems to be installed. Not modifying existing installation in '/home/yodap/.local/pipx/venvs/pyexcel-ods'. Pass '--force' to force installation. yodap@yodap-NUC11:~$ /usr/bin/python3 -m pipx install pyexcel_ods 'pyexcel-ods' already seems to be installed. Not modifying existing installation in '/home/yodap/.local/pipx/venvs/pyexcel-ods'. Pass '--force' to force installation. yodap@yodap-NUC11:~$

I have tried pyexcel-ods and pyexcel_ods....and while both are found...they never get used in the script as they cannot be found by it.


I think the problem is (as alluded to earlier by Wanderer) that I recently changed over from Libreoffice 7. something to the snap version 24.2.2.2....I seem to have totally lost the plot. Where am I going wrong? All help much appreciated!

In short:

pyexcel_ods, pandas, numpy … are completly standalone, … there is NO NEED to run it on top of any running LibreOffice-Instance !

@snapd: there is also no reason to use it, go back to a normal Installation via apt-get

I am not quite sure what you mean by “there is NO NEED to run it on top of any running LibreOffice-Instance”. The way I have always run my scripts is by putting them in the Python Library under MyMacros and calling the script from within the sheet/file (using Tools/Macros/organise_python_scripts/PythonLibrary)that is being worked on. Do you mean that there is another way to do this. If so, sorry, I am unaware

Do you mean that I should not have these at the top of the script?

import pyexcel_ods
import pandas as pd

Most users of python have never used python inside LibreOffice. They run their python-code from the command-line or from desktop. Developers will use their IDE. So, if your script does not need any features from LibreOffice it may be easier to start scripts from an simple IDE like geany and import only the resulting data to LibreOffice afterwards.

This will always be necessary, if you wish to use the library inside your code.

…but mine will need features from within LibreOffice as it is within the *.ods file that the data lies…maybe I am not understanding this properly. I have scripts which are called from within an .ods file…If I understand correctly what you are saying, I could just call these files (or sheets within files) from the command line by giving the full address of the file rather than opening it up and calling the script from there…hmmm!

Again, pyexcel_ods dont need Libreoffice to read and write …ods -files!

Thank you for this pointer…I will experiment from within Geany and see how I go! Hmmm!

No, you decided to have the data there. There may be other options. And as @karolus already mentioned: You import a library to access this files without being inside LibreOffice.
.
As a developer and admin you have ti decide, wich problem you are going to solve.

  • Extending of the python environment inside the snap
  • Accessing the external python from inside the snap
  • Avoiding the first two point by removing the snap-version of LO and replacing with an installed version using apt. This version of LO would usually use the system installed python.
  • Avoiding all previous points by running python scripts outside LibreOffice.

As with your data: It is not necessary for python-scripts to be placed inside an LibreOffice odf-file of any kind.
.
In a way you are telling " I always went right around three corners to my next bakery shop" without realizing you could also have gone one corner to the left (assuming a square grid).

Hmm! I have tried with Geany F5…I am not sure that it is less complicated than operating from within LO…it all seems very complicated…

  1. Open your python file in Geany. 2. Click on the “Build” menu and select “Set Build Commands”. 3. In the “Execute commands” section, replace the existing command with the following command:
%python -i "%f"
  1. Click “OK” to save the changes. 5. Press F5 to run your code in the terminal pane.

Then I get…

/tmp/geany_run_script_ZGNDM2.sh: 7: /home/yodap/LOPythonScriptsython3: not found


(program exited with code: 127)

It must be simpler than this…what am I not understanding?

OK, let simplify things completely so I can really grasp the basics. Here is my script. It is the classic HelloWorld script that comes with LO. I have saved it outside of LO. I have set it up in Geany. I want to run it from within Geany and it will write “Hello World” in cell A1 of TestHelloWorld,ods.

def HelloWorldPython():
“”"
Prints the string ‘Hello World’ into cell A1 of a LibreOffice Calc spreadsheet named TestHelloWorld.ods.
“”"

# Load the ODS file
doc = ezodf.opendoc('home/yodap/Python_Projects/TestHelloWorld.ods')

# Get the first sheet
sheet = doc.sheets[0]

# Set the string in cell A1
sheet['A1'].set_value("Hello World")

# Save the changes
doc.save()

return None

Please, can somebody, walk me through the steps of this running through Geany…coz I cannot get it to work!


(program exited with code: 0)
Press return to continue

import ezodf
from pathlib import Path

def main():
    ods_path = Path.home() / "Documents" / "hello.ods"
    print(f"the path: {(p:=ods_path)} {'already exists' if p.exists() else '' }")
    # Load the ODS file
    doc = ezodf.opendoc(f'{ods_path}')
    # Get the first sheet
    sheet = doc.sheets[0]
    # Set the string in cell A1
    sheet['A1'].set_value("Hello World")
    # Save the changes
    doc.save()

if __name__ == "__main__":
    main()

Thank you kindly for that…

Traceback (most recent call last):
File “/home/yodap/Python_Projects/PPScriptorium/HelloWorld.py”, line 1, in
import ezodf
ModuleNotFoundError: No module named ‘ezodf’


(program exited with code: 1)
Press return to continue

This is the output from Geany.

How do I load ezodf into the Geany environment?

How did you install it? propably you need to tell geany the path to your pipx_env?

I found this on the web and am trying to work my way through it…it is a bit confusing.

I cannot find any pipx_env file or folder on my system?

Can someone explain the first paragraph please as it is a bit confusing.