Manually installing Python package not found on Conda

Hello,
Is there a specific protocol for manually installing Python packages into Julia for use with PyCall? Music21 is a package unavailable via Conda package manage that I downloaded via PIP into my native Anaconda Python folder. If I understand correctly, unless one alters the environment variable for Python’s initialization, the package must installed local to the Conda Julia folder if it is to be retrievable via PyCall.

The original Anaconda package was installed in ./anaconda3/lib/python3.6/site-packages (5.3.0). Mapping the hierarchy into Julia’s miniconda folder, I came up with /.julia/v0.6/Conda/deps/usr/lib/python3.7 as the place to store this. All I did was copy and paste the folder. I presume I did something wrong because I am receiving this error:

Main> @pyimport Music21 as mtw
ERROR: PyError (PyImport_ImportModule) <class 'ModuleNotFoundError'>
ModuleNotFoundError("No module named 'Music21'")

Help is greatly appreciated. Thank you!

This thread might be able to help…?

1 Like

See A Documented/Preferred way of installing PyPi dependencies · Issue #50 · JuliaPy/Conda.jl · GitHub and in particular this example.

2 Likes

I was able to get Music21 installed thanks to your suggestions. As far as using PyCall to reference a specific function, I am having trouble.

According to Music21’s website, in order to display a short melody in musical notation one would type this in Python:
converter.parse("tinynotation: 3/4 c4 d8 f g16 a g f#").show()

I did this to initialize music21, which seemed to work:

@pyimport music21
music21: Certain music21 functions might need these optional packages: matplotlib, scipy;
                   if you run into errors, install them by following the instructions at
                   http://mit.edu/music21/doc/installing/installAdditional.html

Now, I am trying to recreate the above Python example in Julia by typing:

converter.parse("tinynotation: 3/4 c4 d8 f g16 a g f#").show()
ERROR: UndefVarError: converter not defined
Stacktrace:
 [1] eval(::Module, ::Any) at ./boot.jl:235

Can anyone help me discover what I am doing wrong?

Thanks,
Nakul

For those who are curious, I was able to ascertain the secondary solution. It has to do with dot overloading.

This stack overflow thread gets to the bottom of the problem.

Looks like the equivalent is:

music21 = pyimport("music21")
music21[:converter][:parse]("tinynotation: 3/4 c4 d8 f g16 a g f#")[:show]()
1 Like

Thank you @stevengj ! By the way, I’m a fan of this Pull Request because it simplifies a lot of syntax in the manner that one would expect to see in Python. I understand that there are talks to merge this pull request soon.

In the interim, I was wondering if there was a way of instead using PyCall in such a way that I can run a large block of code using native Python syntax akin to the syntax described in the pull request. Specifically, I am seeing if I can avoid repeatedly using the [:show] syntax so that my code is backwards compatible with Python as well as future releases of PyCall if/once the pull request gets merged.

For example:

PyCall(#run python script)

converter.parse(“tinynotation: 3/4 c4 d8 f g16 a g f#”).show()
#more blocks of python code

#end of script

py"""
...Python code...
"""
1 Like

Thank you very much. That’s awesome. Happy birthday by the way! @stevengj