PyX not installed correctly when using scapy - python

I am trying to use scapy in python 3.6 to parse pcap files, and of the features I am trying to use is pdfdump.
from scapy.all import *
packets = rdpcap('***path***/nitroba.pcap')
for packet in packets[0:1]:
packet.psdump("isakmp_pkt.eps",layer_shift=1)
And I am getting the following error:
"ImportError: PyX and its depedencies must be installed"
Obviously I installed it, and a simple "import pyx" works, but the error persists. I did some digging and found that the problem originates in this code:
def _test_pyx():
"""Returns if PyX is correctly installed or not"""
try:
with open(os.devnull, 'wb') as devnull:
r = subprocess.check_call(["pdflatex", "--version"], stdout=devnull, stderr=subprocess.STDOUT)
except:
return False
else:
return r == 0
when executed, it determines if pyx is installed correctly, but it says "FileNotFoundError: [WinError 2] The system cannot find the file specified".
Ideas?

In my case (Ubuntu 18, scapy 2.4.3), I had to install pdflatex, i.e.,
sudo apt install texlive-latex-base

Got the answer myself - when I entered the scapy command line interface it said that I needed to install miktex which is a dependency of PyX, so I did.
The second error simply looks like a bug - it looks like there is a missing "import os" statement in the packet.py module, but there is an os.startfile in line 531.
I added it, and it worked:)

Its currently 2022 in the future and this works for me with Jupyer labs running on Ubuntu 20.04
pip install pyx
At least this works for me:
from scapy.all import *
pkt = IP()
pkt.canvas_dump()

Related

FileNotFoundError: [Errno 2] No such file or directory: 'fluidsynth': 'fluidsynth'

The python code in question:
import subprocess
subprocess.call(["fluidsynth", "-V"])
Steps to try to resolve:
make sure that fluidsynth is installed. In terminal, I type fluidsynth -V and the output actually calls fluidsynth.
attempted os.system("fluidsynth -V") but get the same error.
also tried subprocess.run("fluidsynth -V") but to no avail.
which fluidsynth yields /usr/bin/fluidsynth, and I checked that /usr/bin/ is included in $PATH
I'm not sure why the code that I'm typing into the terminal stops working when I use the subprocess call. Any ideas?
#jure c solved the problem by adding /usr/bin to the call

How to distribute and or package a python file with all dependencies pre-downloaded without building an executable

I have written a python script which depends on paramiko to work. The system that will run my script has the following limitations:
No internet connectivity (so it can't download dependencies on the fly).
Volumes are mounted with 'noexec' (so I cannot run my code as a binary file generated with something like 'pyInstaller')
End-user cannot be expected to install any dependencies.
Vanilla python is installed (without paramiko)
Python version is 2.7.5
Pip is not installed either and cannot be installed on the box
I however, have access to pip on my development box (if that helps in any way).
So, what is the way to deploy my script so that I am able to provide it to the end-user with the required dependencies, i.e paramiko (and sub-dependencies of paramiko), so that the user is able to run the script out-of-the-box?
I have already tried the pyinstaller 'one folder' approach but then faced the 'noexec' issue. I have also tried to directly copy paramiko (and sub-dependencies of paramiko) to a place from where my script is able to find it with no success.
pip is usually installed with python installation. You could use it to install the dependencies on the machine as follows:
import os, sys
def selfInstallParamiko():
# assuming paramiko tar-ball/wheel is under the current working directory
currentDir = os.path.abspath(os.path.dirname(__file__))
# paramikoFileName: name of the already downloaded paramiko tar-ball,
# which you'll have to ship with your scripts
paramikoPath = os.path.join(currentDir, paramikoFileName)
print("\nInstalling {} ...".format(paramikoPath))
# To check for which pip to use (pip for python2, pip3 for python3)
pipName = "pip"
if sys.version_info[0] >= 3:
pipName = "pip3"
p = subprocess.Popen("{} install --user {}".format(pipName, paramikoPath).split())
out, err= p.communicate("")
if err or p.returncode != 0:
print("Unable to self-install {}\n".format(paramikoFileName))
sys.exit(1)
# Needed, because sometimes windows command shell does not pick up changes so good
print("\n\nPython paramiko module installed successfully.\n"
"Please start the script again from a new command shell\n\n")
sys.exit()
You can invoke it when your script starts and an ImportError occurs:
# Try to self install on import failure:
try:
import paramiko
except ImportError:
selfInstallParamiko()

How to check if a module is installed in Python and, if not, install it within the code?

I would like to install the modules 'mutagen' and 'gTTS' for my code, but I want to have it so it will install the modules on every computer that doesn't have them, but it won't try to install them if they're already installed. I currently have:
def install(package):
pip.main(['install', package])
install('mutagen')
install('gTTS')
from gtts import gTTS
from mutagen.mp3 import MP3
However, if you already have the modules, this will just add unnecessary clutter to the start of the program whenever you open it.
EDIT - 2020/02/03
The pip module has updated quite a lot since the time I posted this answer. I've updated the snippet with the proper way to install a missing dependency, which is to use subprocess and pkg_resources, and not pip.
To hide the output, you can redirect the subprocess output to devnull:
import sys
import subprocess
import pkg_resources
required = {'mutagen', 'gTTS'}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed
if missing:
python = sys.executable
subprocess.check_call([python, '-m', 'pip', 'install', *missing], stdout=subprocess.DEVNULL)
Like #zwer mentioned, the above works, although it is not seen as a proper way of packaging your project. To look at this in better depth, read the the page How to package a Python App.
you can use simple try/except:
try:
import mutagen
print("module 'mutagen' is installed")
except ModuleNotFoundError:
print("module 'mutagen' is not installed")
# or
install("mutagen") # the install function from the question
If you want to know if a package is installed, you can check it in your terminal using the following command:
pip list | grep <module_name_you_want_to_check>
How this works:
pip list
lists all modules installed in your Python.
The vertical bar | is commonly referred to as a "pipe". It is used to pipe one command into another. That is, it directs the output from the first command into the input for the second command.
grep <module_name_you_want_to_check>
finds the keyword from the list.
Example:
pip list| grep quant
Lists all packages which start with "quant" (for example "quantstrats"). If you do not have any output, this means the library is not installed.
You can check if a package is installed using pkg_resources.get_distribution:
import pkg_resources
for package in ['mutagen', 'gTTS']:
try:
dist = pkg_resources.get_distribution(package)
print('{} ({}) is installed'.format(dist.key, dist.version))
except pkg_resources.DistributionNotFound:
print('{} is NOT installed'.format(package))
Note: You should not be directly importing the pip module as it is an unsupported use-case of the pip command.
The recommended way of using pip from your program is to execute it using subprocess:
subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'my_package'])
Although #girrafish's answer might suffice, you can check package installation via importlib too:
import importlib
packages = ['mutagen', 'gTTS']
[subprocess.check_call(['pip', 'install', pkg])
for pkg in packages if not importlib.util.find_spec(pkg)]
You can use the command line :
python -m MyModule
it will say if the module exists
Else you can simply use the best practice :
pip freeze > requirements.txt
That will put the modules you've on you python installation in a file
and :
pip install -r requirements.txt
to load them
It will automatically you purposes
Have fun
Another solution it to put an import statement for whatever you're trying to import into a try/except block, so if it works it's installed, but if not it'll throw the exception and you can run the command to install it.
You can run pip show package_name
or for broad view use pip list
Reference
If you would like to preview if a specific package (or some) are installed or not maybe you can use the idle in python.
Specifically :
Open IDLE
Browse to File > Open Module > Some Module
IDLE will either display the module or will prompt an error message.
Above is tested with python 3.9.0

Installing PocketSphinx in Python3, Lubuntu 15.10

I have installed PocketSphinx (python-pocketsphinx, pocketsphinx-hmm-wsj1, pocketsphinx-lm-wsj), but get this error from trying to run a piece of Python3 code to recognise speech in an audio file.
$ python3 web_speech_api.py 02-29-2016_00-12_msg1.wav
Fatal Python error: Py_Initialize: Unable to get the locale encoding
File "/usr/lib/python2.7/encodings/__init__.py", line 123
raise CodecRegistryError,\
^
SyntaxError: invalid syntax
Current thread 0x00007fe1548de700 (most recent call first):
Aborted (core dumped)
I have both Python 2.7, Python 3.5 and Anaconda installed to make things complicated and I guess the error might be due to this somehow?
I have added the lines below to my ~/.bachrc.
export PYTHONPATH=/usr/lib/python2.7
export PATH=$PATH:$PYTHONPATH
Wasn't sure whether to put python3.5 or 2.7, but 3.5 gave me an error [...] ImportError: No module named '_sysconfigdata_m'.
I have also removed the line that was automatically added for setting the path to anaconda, and don't need the Anaconda packages for this project.
$ which python
/usr/bin/python
$ echo "$PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/python2.7
Here is the code as well if it is of any help:
#!/usr/bin/ python
import sys
import pocketsphinx
if __name__ == "__main__":
hmdir = "/usr/share/pocketsphinx/model/hmm/wsj1"
lmdir = "/usr/share/pocketsphinx/model/lm/wsj/wlist5o.3e-7.vp.tg.lm.DMP"
dictd = "/usr/share/pocketsphinx/model/lm/wsj/wlist5o.dic"
wavfile = sys.argv[1]
speechRec = pocketsphinx.Decoder(hmm = hmdir, lm = lmdir, dict = dictd)
wavFile = file(wavfile,'rb')
speechRec.decode_raw(wavFile)
result = speechRec.get_hyp()
print(result)
I'm very thankful for help straightening out my error and hopefully also sorting out my mess of different Python versions...

error while trying to install a package using the python-apt API

I found a code which i need. It is from this link : How to install a package using the python-apt API
#!/usr/bin/env python
# aptinstall.py
import apt
import sys
pkg_name = "libjs-yui-doc"
cache = apt.cache.Cache()
cache.update() # error is in this line
pkg = cache[pkg_name]
if pkg.is_installed:
print "{pkg_name} already installed".format(pkg_name=pkg_name)
else:
pkg.mark_install()
try:
cache.commit()
except Exception, arg:
print >> sys.stderr, "Sorry, package installation failed [{err}]".format(err=str(arg))
However i can't make it work. I searched about the problem on the web. It is said that there should be no package manager,apt,pip etc active in order to work with this code. However, no package manager,apt,pip etc. is open in my computer. I thought that when computer starts, some package manager can be active. So i typed
ps -aux
in terminal and look at the active processes, but i didn't see any active process related to package manager(i'm not %100 sure about this, because any process i don't know can be related to package manager.But how could i know it?) To sum up,i started the computer and opened only terminal. Then i typed python aptinstall.py and hit enter. I take the following error :
Traceback (most recent call last):
File "aptinstall.py", line 7, in <module>
cache.update()
File "/usr/lib/python2.7/dist-packages/apt/cache.py", line 397, in update
raise LockFailedException("Failed to lock %s" % lockfile)
apt.cache.LockFailedException: Failed to lock /var/lib/apt/lists/lock
I delete the lock by giving the command in terminal :
sudo rm /var/lib/dpkg/lock
It didn't work too.
How can i solve this problem? Any idea will be appreciated.
Please try looking for update-manager in ps. It runs automatically on a periodic basis, so it may be locking the apt db.
There are three different reasons which cause this error.
1 - As i mentioned earlier, if any package manager is runnning(for example;pip,apt-get,synaptic,etc), it gives the error.
2 - If you are using your ubuntu in a virtual machine, this causes the same error.
3 - If you are running your program without root privileges, this causes the same error. For example ,if you are running your program with "python aptinstall.py" you get the error, running the program with "sudo python aptinstall.py" is the correct one.

Categories

Resources