pyqtdeploy: howto add egg's?

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

pyqtdeploy: howto add egg's?

Schluchti
Hi all,

I am using pyqtdeploy to create PyQt Applications for Android. It took me some time, but finally I got a simple PyQt application working on Android. Now, I would like to add some additional modules to my PyQt application - in particular "pycrypto". Therefore, I downloaded the pycrypto sourcecode, compiled it with the Android NDK compiler toolchain against my statically compiled Python and created a *.egg file.

But now I'm a little bit lost...how can I add the Python egg to pyqtdeploy? According to the pyqtdeploy documentation I should add the Python egg to the sys.path file, right? I did this, by adding the following path to sys.path: "C:\tomatoview-app\static_android_libs\ext\pycrypto-2.6.1-py3.4.egg". Unfourtunately this doesn't work...when I try to import something from pycrypto (e.q: from Crypto.Cipher import blockalgo) I'm always getting "ImportError: No module named 'Crypto'".

I also tried to unpack the generated *.apk file to check if it contains the pycrypto library, but there is nothing pycrypto related in there.

What am I doing wrong? I would really appreciate any help.

Kind Regards
Bernhard
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Phil Thompson-5
On 3 Feb 2016, at 2:02 pm, Schluchti <[hidden email]> wrote:

>
> Hi all,
>
> I am using pyqtdeploy to create PyQt Applications for Android. It took me
> some time, but finally I got a simple PyQt application working on Android.
> Now, I would like to add some additional modules to my PyQt application - in
> particular "pycrypto". Therefore, I downloaded the pycrypto sourcecode,
> compiled it with the Android NDK compiler toolchain against my statically
> compiled Python and created a *.egg file.
>
> But now I'm a little bit lost...how can I add the Python egg to pyqtdeploy?
> According to the pyqtdeploy documentation I should add the Python egg to the
> sys.path file, right? I did this, by adding the following path to sys.path:
> "C:\tomatoview-app\static_android_libs\ext\pycrypto-2.6.1-py3.4.egg".
> Unfourtunately this doesn't work...when I try to import something from
> pycrypto (e.q: from Crypto.Cipher import blockalgo) I'm always getting
> "ImportError: No module named 'Crypto'".
>
> I also tried to unpack the generated *.apk file to check if it contains the
> pycrypto library, but there is nothing pycrypto related in there.
>
> What am I doing wrong? I would really appreciate any help.

You have to add the .egg to the .apk yourself. Alternatively build the package differently so that it can be statically linked with your application.

Phil
_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Schluchti
Hi Phil,

thanks for your reply.

Sorry for the dumb question, but what do you mean by "adding the .egg manually to the .apk"?
I unpacked a *.apk and found a "lib" folder in there. Do you mean that I should put the *.so files in there
and add the corresponding *.py files via pyqtdeploy?

I also tried to compile pycrypto statically, but unfourtunately it didn't work.
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Phil Thompson-5
On 3 Feb 2016, at 6:50 pm, Schluchti <[hidden email]> wrote:

>
> Hi Phil,
>
> thanks for your reply.
>
> Sorry for the dumb question, but what do you mean by "adding the .egg
> manually to the .apk"?
> I unpacked a *.apk and found a "lib" folder in there. Do you mean that I
> should put the *.so files in there
> and add the corresponding *.py files via pyqtdeploy?

I don't know anything about creating .apk files - that's left to the Qt and Android tools. Presumably they include a mechanism for adding additional files and libraries.

Phil
_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Schluchti
Hi Phil,

I figured out, that I could just add the corresponding *.so to the resources qrc.

The *.so should get loaded with the following code snippet (in _AES.py):

def __bootstrap__():
   global __bootstrap__, __loader__, __file__
   import sys, pkgutil, imp
   __file__ = pkgutil.get_data(__name__,'_AES.cpython-34m.so')
   __loader__ = None; del __bootstrap__, __loader__
   imp.load_dynamic(__name__,__file__)
__bootstrap__()


However, now I get the following error:

File: ":/Crypto/Cipher/_AES.py", line 20 in __bootstrap__
TypeError: 'NoneType' object is not callable


At first I thought, that the *.so filename was just wrong and therefore, I got the NoneType Error, so
I changed the filename in _AES.py to something other like 'test.so'. Surprisingly, now, I get a different error message than before:

File ":/pkgutil.py" line 629, in get_data
ImportError: qrcimporter: error opening file :/Crypto/Cipher/test.so


Ok, so the filename should be fine, right? I googled a little bit, and found the following statement in the pkgutil documentation: "If the package cannot be located or loaded, or it uses a PEP 302 loader which does not support get_data(), then None is returned.". Is it possible, that get_data() is not implemented in the pyqtdeploy loader or am I doing something completely wrong?


Bernhard

Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Phil Thompson-5
On 4 Feb 2016, at 1:47 pm, Schluchti <[hidden email]> wrote:

>
> Hi Phil,
>
> I figured out, that I could just add the corresponding *.so to the resources
> qrc.
>
> The *.so should get loaded with the following code snippet (in _AES.py):
>
> def __bootstrap__():
>   global __bootstrap__, __loader__, __file__
>   import sys, pkgutil, imp
>   __file__ = pkgutil.get_data(__name__,'_AES.cpython-34m.so')
>   __loader__ = None; del __bootstrap__, __loader__
>   imp.load_dynamic(__name__,__file__)
> __bootstrap__()
>
>
> However, now I get the following error:
>
> File: ":/Crypto/Cipher/_AES.py", line 20 in __bootstrap__
> TypeError: 'NoneType' object is not callable
>
>
> At first I thought, that the *.so filename was just wrong and therefore, I
> got the NoneType Error, so
> I changed the filename in _AES.py to something other like 'test.so'.
> Surprisingly, now, I get a different error message than before:
>
> File ":/pkgutil.py" line 629, in get_data
> ImportError: qrcimporter: error opening file :/Crypto/Cipher/test.so
>
>
> Ok, so the filename should be fine, right? I googled a little bit, and found
> the following statement in the pkgutil documentation: "If the package cannot
> be located or loaded, or it uses a PEP 302 loader which does not support
> get_data(), then None is returned.". Is it possible, that get_data() is not
> implemented in the pyqtdeploy loader or am I doing something completely
> wrong?

get_data() support was added in v1.2, but probably not heavily tested.

Phil
_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Schluchti
In reply to this post by Schluchti
Hi Phil,

I am using pyqtdeploy v1.2, so I assume that I am doing something wrong here. I will investigate this further.

Do you know if there is a sample pyqtdeploy project where the use of external modules is demonstrated?
I took a look at the pyqtdeploy repository, but I could only find a demo application without external modules.

Bernhard
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Phil Thompson-5
On 4 Feb 2016, at 4:52 pm, Schluchti <[hidden email]> wrote:

>
> Hi Phil,
>
> I am using pyqtdeploy v1.2, so I assume that I am doing something wrong
> here. I will investigate this further.
>
> Do you know if there is a sample pyqtdeploy project where the use of
> external modules is demonstrated?
> I took a look at the pyqtdeploy repository, but I could only find a demo
> application without external modules.
Try playing with the attached. snowballstemmer is an .egg that gets installed with Sphinx.

Phil


_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt

import_egg.pdy (648 bytes) Download Attachment
import_egg.py (101 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Schluchti
In reply to this post by Schluchti
Hi Phil,

thanks for the example - it works. If i'm not completely wrong, then snowballstemmer looks like as it is pure Python. Importing pure Python modules into my application work as expected, but as soon as I need external *.so files it doesn't work.

Bernhard
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Phil Thompson-5
On 5 Feb 2016, at 7:13 pm, Schluchti <[hidden email]> wrote:
>
> Hi Phil,
>
> thanks for the example - it works. If i'm not completely wrong, then
> snowballstemmer looks like as it is pure Python. Importing pure Python
> modules into my application work as expected, but as soon as I need external
> *.so files it doesn't work.

You could try renaming the .so as described here...

http://pyqt.sourceforge.net/Docs/pyqtdeploy/tutorial.html#defining-the-application-source

...in the section covering sys.path.

Phil
_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Schluchti
In reply to this post by Schluchti
Hi Phil,

unfourtunately, I cannot place the *.so in the same directory as the Android executable. At least, when I tried, it failed due to permission problems (my device isn't rooted).

After some further debugging, I think that this line doesn't work:
imp.load_dynamic(__name__,__file__)

In the Python Setup.dist I found that there are certain platforms where dynamic loading isn't supported. Do I need to enable this somehow when building the static Python?

Bernhard
Reply | Threaded
Open this post in threaded view
|

Re: pyqtdeploy: howto add egg's?

Phil Thompson-5
On 6 Feb 2016, at 1:56 pm, Schluchti <[hidden email]> wrote:

>
> Hi Phil,
>
> unfourtunately, I cannot place the *.so in the same directory as the Android
> executable. At least, when I tried, it failed due to permission problems (my
> device isn't rooted).
>
> After some further debugging, I think that this line doesn't work:
> imp.load_dynamic(__name__,__file__)
>
> In the Python Setup.dist I found that there are certain platforms where
> dynamic loading isn't supported. Do I need to enable this somehow when
> building the static Python?

If you are using pyqtdeploycli to configure the Python build then look at the --enable-dynamic-loading command line option.

Phil
_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt