Macuyiko / minecraft-python

A Jython driven plugin and interpreter system for Minecraft (on top of Spigot)
BSD 3-Clause "New" or "Revised" License
226 stars 29 forks source link

Can this load external Python modules like requests? #47

Open oddmario opened 3 years ago

oddmario commented 3 years ago

Hello,

Title says it all I guess. Like can I get the PyPI modules to work and use them inside the Python plugins?

Kind regards

Macuyiko commented 3 years ago

Yes, but not in a clean way. Preferably, you'd look for Java library alternatives and drop those JAR files in lib-custom.

Alternatively, you can create a site-packages folder in you spigot directory and unextract whl files in there, e.g. for requests, I have:

14/06/2021  20:21    <DIR>          certifi
14/06/2021  20:21    <DIR>          certifi-2021.5.30.dist-info
14/06/2021  20:21    <DIR>          chardet
14/06/2021  20:21    <DIR>          chardet-4.0.0.dist-info
14/06/2021  20:22    <DIR>          idna
14/06/2021  20:22    <DIR>          idna-2.10.dist-info
14/06/2021  20:22    <DIR>          requests
14/06/2021  20:15    <DIR>          requests-2.25.1.dist-info
14/06/2021  20:20    <DIR>          urllib3
14/06/2021  20:20    <DIR>          urllib3-1.26.5.dist-info

Note that you should make sure to obtain py2.7 compatible packages as Jython is not Python 3 compatible.

In the Minecraft Python console, you can then:

import sys
from os.path import abspath, sep
sys.path.append(abspath('.') + sep + 'site-packages')

import requests
requests.get('https://example.org').text

Not ideal, but preferably I'd wait to find a better approach to this until Jython finally decides to get Python 3 support working or I can find a Java-Python 3 compatible interop package. (I still think Py4J should work but will require some experimenting to figure out, especially with Spigot's threading model.)

oddmario commented 3 years ago

Thank you so much! Using the site-packages method to load the requests module would be easier imo since making a HTTP request using the Java libraries available there is a painful process honestly

d3xt3r0 commented 2 years ago

Yes, but not in a clean way. Preferably, you'd look for Java library alternatives and drop those JAR files in lib-custom.

Alternatively, you can create a site-packages folder in you spigot directory and unextract whl files in there, e.g. for requests, I have:

14/06/2021  20:21    <DIR>          certifi
14/06/2021  20:21    <DIR>          certifi-2021.5.30.dist-info
14/06/2021  20:21    <DIR>          chardet
14/06/2021  20:21    <DIR>          chardet-4.0.0.dist-info
14/06/2021  20:22    <DIR>          idna
14/06/2021  20:22    <DIR>          idna-2.10.dist-info
14/06/2021  20:22    <DIR>          requests
14/06/2021  20:15    <DIR>          requests-2.25.1.dist-info
14/06/2021  20:20    <DIR>          urllib3
14/06/2021  20:20    <DIR>          urllib3-1.26.5.dist-info

Note that you should make sure to obtain py2.7 compatible packages as Jython is not Python 3 compatible.

In the Minecraft Python console, you can then:

import sys
from os.path import abspath, sep
sys.path.append(abspath('.') + sep + 'site-packages')

import requests
requests.get('https://example.org').text

Not ideal, but preferably I'd wait to find a better approach to this until Jython finally decides to get Python 3 support working or I can find a Java-Python 3 compatible interop package. (I still think Py4J should work but will require some experimenting to figure out, especially with Spigot's threading model.)

Is it not possible to use Jython3 for python 3 support?

Thanks.

Matthew-MBG commented 2 years ago

Hi there, I have a small issue. The package I'm trying to import doesn't have a whl file. What should I do?

andriemc commented 2 years ago

@Matthew-MBG If it doesn't that means it's a broken package.

Macuyiko commented 1 year ago

Is it not possible to use Jython3 for python 3 support?

Jython 3 is basically dead in the water, sadly, so Py4J would probably be better.

VincentX0905 commented 1 year ago
[14:11:33 WARN]: Traceback (most recent call last):
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\python\mcapi.py", line 104, in wrap_exception
[14:11:33 WARN]:     g()
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\python\mcapi.py", line 125, in <lambda>
[14:11:33 WARN]:     g = lambda: f(*args, **kwargs)
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\.\python-plugins\checkver.py", line 36, in disablee
[14:11:33 WARN]:     check()
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\.\python-plugins\checkver.py", line 17, in check
[14:11:33 WARN]:     corever = requests.get("https://api.purpurmc.org/v2/purpur/%s" % needcorever).json()['tls_version']
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\api.py", line 76, in get
[14:11:33 WARN]:     return request('get', url, params=params, **kwargs)
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\api.py", line 61, in request
[14:11:33 WARN]:     return session.request(method=method, url=url, **kwargs)
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\sessions.py", line 542, in request
[14:11:33 WARN]:     resp = self.send(prep, **send_kwargs)
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\sessions.py", line 655, in send
[14:11:33 WARN]:     r = adapter.send(request, **kwargs)
[14:11:33 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\adapters.py", line 514, in send
[14:11:33 WARN]:     raise SSLError(e, request=request)
[14:11:33 WARN]: SSLError: HTTPSConnectionPool(host='api.purpurmc.org', port=443): Max retries exceeded with url: /v2/purpur/1.19.3 (Caused by SSLError(SSLError(1, u'Received fatal alert: handshake_failure'),))

i get this error i can not get purpur website wuth SSL error

Macuyiko commented 1 year ago

Setting verify=False might help (though this is a quick solution which will ignore SSL).

More info: https://stackoverflow.com/questions/10667960/python-requests-throwing-sslerror

VincentX0905 commented 1 year ago
[18:12:22 WARN]: Traceback (most recent call last):
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\python\mcapi.py", line 104, in wrap_exception
[18:12:22 WARN]:     g()
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\python\mcapi.py", line 125, in <lambda>
[18:12:22 WARN]:     g = lambda: f(*args, **kwargs)
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\.\python-plugins\checkver.py", line 35, in disablee
[18:12:22 WARN]:     check()
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\.\python-plugins\checkver.py", line 17, in check
[18:12:22 WARN]:     corever = requests.get("https://api.purpurmc.org/v2/purpur/%s" % needcorever, verify=False).json()
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\api.py", line 76, in get
[18:12:22 WARN]:     return request('get', url, params=params, **kwargs)
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\api.py", line 61, in request
[18:12:22 WARN]:     return session.request(method=method, url=url, **kwargs)
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\sessions.py", line 542, in request
[18:12:22 WARN]:     resp = self.send(prep, **send_kwargs)
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\sessions.py", line 655, in send
[18:12:22 WARN]:     r = adapter.send(request, **kwargs)
[18:12:22 WARN]:   File "C:\Users\vince\Desktop\MC\site-packages\requests\adapters.py", line 514, in send
[18:12:22 WARN]:     raise SSLError(e, request=request)
[18:12:22 WARN]: SSLError: HTTPSConnectionPool(host='api.purpurmc.org', port=443): Max retries exceeded with url: /v2/purpur/1.19.3 (Caused by SSLError(SSLError(1, u'Received fatal alert: handshake_failure'),))

i add it same i google this issus like java issue

Macuyiko commented 1 year ago

Yes, seems to be a weird interplay between requests, Jython, and OpenSSL on Java. Most likely due because api.purpurmc.org only supports recent TLS.

Perhaps using httplib in this instance is easier (this worked for me):

import httplib
conn = httplib.HTTPSConnection('api.purpurmc.org')
conn.request('GET', '/v2/purpur/1.19.3')
r = conn.getresponse()
print r.status, r.reason
data = r.read()
print data
VincentX0905 commented 1 year ago

thanks it working and can you open a discord guild? This way you don’t have to open an issue for small things It also allows a broad user base to participate