How to include third party Python packages in Sublime Text 2 plugins - python

I'm writing a sublime text 2 plugin that uses a module SEAPI.py which in itself imports the requests module.
Since sublime text 2 uses it's own embedded python interpreter, it doesn't see the requests module installed in my ubuntu machine (I get the following error: ImportError: No module named requests).
Best solution I could find so far was to copy the 'requests' module (the whole directory of files) from /usr/lib/python2.7/dist-packages/requests into my plugin directory in the sublime text packages dir.
But after that, it says that it can't find the 'urllib3' module.
Is there a better way to import the requests module so that I won't have to copy all the files into my plugin directory ?
The current code I'm using is as follows:
MyPlugin.py
import sublime
import sublime_plugin
import SEAPI
...
SEAPI.py
import requests
try:
import simplejson as json
except:
import json
from time import time, sleep
...
Edit:
The selected answer is correct and fixes my main question, but a different problem exists with using the current version of 'Requests' with the embedded sublime text 2 interpreter. ST2's python is missing various modules which exist in regular 2.7 python (such as 'fileio').
I've solved it with using the 'Requests' module from here:
https://github.com/bgreenlee/sublime-github
And I had to edit the 'urllib3/response.py' file to this:
try:
from cStringIO import StringIO as BytesIO
except ImportError:
pass # _fileio doesn't seem to exist in ST's python in Linux, but we don't need it

You need to bundle full requests distribution with your Python package and then modify Python's sys.path (where it looks for modules) to point to a folder containing requests folder.
Download Requests library from a PyPi and extract it manually under your plugin folder
Before importing requests in your plugin, append the corrcet folder to sys.path to point a folder where it can found requests import
The (untested) code should look like something like this:
import sys
import os
# request-dists is the folder in our plugin
sys.path.append(os.path.join(os.path.dirname(__file__), "requests-dist"))
import requests
This also assumes that requests setup.py does not do any hacks when you install the module using easy_install or pip.
You also could import requests zip directly as Python supports importing from ZIP files, assuming requests is distributed in compatible way. Example (advanced):
https://github.com/miohtama/ztanesh/blob/master/zsh-scripts/python-lib/zipimporter.py
More about sys.path trick (2004)
http://www.johnny-lin.com/cdat_tips/tips_pylang/path.html

Mikko's answer is good, but I may have found a slightly easier way:
import MyAwesomePlugin.requests
"MyAwesomePlugin" being the name of your plugin, of course.

Related

Import statements not working / I think I broke Python / file structure issues?

[I am new to Python (and programming in general) and will definitely say something stupid in this question.]
I had two python programs. In one of them the import statements were working. And in the other one the import statements were not working.
I suspected this had something to do with the file location of the modules relative to the Python files.
It turned out the program that wasn't working was in a sub folder of the program that was working.
So, as an experiment, I tried moving the venv folder into the sub folder where the other program was, but I ended up canceling that once I discovered that I would need to replace some of the files. (Due to the fact that is already had a venv folder.)
Then, as an experiment, I tried renaming the venv folder to "venv1" just to see if the good program would run. I was not surprised when it didn't.
But then I renamed it back to "venv," and it still wasn't working.
from bs4 import BeautifulSoup
import requests
import json, requests
import urllib.request
import bs4 as bs
import urllib
# .... etc ...
output
ModuleNotFoundError: No module named 'bs4'
...
...
...
oh, and if I try:
#from bs4 import BeautifulSoup
import requests
import json, requests
import urllib.request
import bs4 as bs
import urllib
# .... etc ...
Output:
ModuleNotFoundError: No module named 'requests'
I tried pip installing them again (my terminal doesn't recognize sudo pip install) and this is what I got
PS C:\Users\****\Desktop> pip install requests
Requirement already satisfied: requests in c:\users\****\appdata\local\programs\python\python310\lib\site-packages (2.27.1)
I thought maybe I'd look this one up, but the folder "appdata" doesn't exist on my computer, in that location.
What happened and how can I fix it?
The appdata folder should exist in that location. It is a hidden folder, and by default, Windows won't display hidden files/folders. You can view it by pressing WIN+R, and then typing "appdata", and clicking "OK". It should then come up in a file explorer window.
The python packages are installed, but not visible to the scripts. It sounds like you virtual environment may be incorrectly set up. If you open a CMD prompt, and then type in python -m site, it will show you the locations of your python's system path. You should see the install locations for the packages, in this case, you'll probably see the following: C:\\Users\\****\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages.

Is it possible to specify the search path for a module in a python script? If it is, how do I do that?

I have been coding in python for about 2 months, but I'm only familiar with basic object-oriented programming, so I do not really understand things like how searching for modules is implemented. (Basically I'm a noob.)
I pip installed a package called Opentrons Opentrons 2.5.2 and all its dependencies into the samefolder as a python script I'm currently writing. However when I tried to import the module below[1], I get an error saying that "Opentrons is not a module". Then, I tried shifting it into the python library because I found out the search path using the pprint module and it seems to work. I was wondering if I can specify the search path from the .py file itself instead of manually printing the search path and putting the file into the library that the script searches for. (Willing to put in images of the directories I put the opentrons package in if it helps.)
[1]
import sys
import pprint
pprint.pprint(search.path)
from opentrons import robot, containers, instruments
Edit: I realise that the fact that I am running all my scripts in a Spyder console located in a python 3.6 environment might be important.
You can try using the __import__ function, or importlib. This should allow you to specify the path.

ImportError: No module named 'Crypto' , using AES in python

I'm using Crypto.Cipher.AES in a django project ,but get this error.
I've installed pycrypto 2.6.1 with pip and it really exists on my disk,Pycharm does not show any errors and AES.py can be viewed.
My PC is windows 10,python version is 3.5.1, and django is 1.9.6.
I'm confused and find no solutions. Thanks in adcance!
This seems like it could be one of two problems:
An import conflict, i.e. there is another module/file named Crypto that
python is attempting to import.
The path to your module isn't in sys.path.
To solve 1, check the full import error stack trace to find where the Crypto.Cipher.AES is trying to import from, this should match the path of your Crypto module. Also check for any files/folders with the name Crypto that would cause an import collision in your application.
To solve 2, check your sys.path:
import sys
print sys.path
This is where the system looks when trying to import a module. If the exact path or root path to your module doesn't exist within this list, then the module will not be found.
You can add a path using the following:
sys.path.append('path/to/your/module')

How do i convert my Python script (that has imported modules) to a windows exe?

Here are the import modules that my script uses :
import datetime
from dateutil import parser
from tkinter import filedialog
import tkinter
import mailbox
import pprint
import json
import urllib.request
from tkinter import *
#my script code here
How can i convert it into a windows exe. Im using python 3.4. People have suggested cx_freeze however there is no documentation on it therefore have no idea how to use it? Py2exe worked on a test script with no imported modules, but when i tried to compile my script, it didnt work? If my script is called test.py, what would the cx_freeze command be to covnert it?
Try www.py2exe.org/
py2exe is a nice module that you may find useful.
Or, if you are in linux/mac then you might try freeze method try https://wiki.python.org/moin/Freeze
I highly suggest PyInstaller.
I used to use it in order to create the exe file with multiple library files, then compress all these files into a self extracting archive, obtaining a fully working standalone exe file.
It doesn't require other scripts or code, you only have to create the file using "Makespec.py" and "Build.py".
If I'm not wrong, there is a new version compatible with Python 3.4...otherwise you could convert your script to Python 2.7.

Python modules' paths

In some Python scripts I see the following imports:
import fileA
import someDir.fileB
from fileC import functionA
There exist corresponding files fileA.py, someDir/fileB.py and fileC.py. However, while looking in the Requests source code, I found this in the __init__.py file:
from requests.packages.urllib3.contrib import pyopenssl
In this case, requests is the CWD and packages.urllib3.contrib.pyopenssl.py is the file. Why does this defy convention? I do see that the packages.urllib3.contrib directory does also have a __init__.py file, which seems to be related.
Furthermore, I'm not sure if it is related but I think it is so I post it here. In my script I have the folder kennethreitz/requests, since the application depends on the Requests module but I'm deploying it to environments which might not have Requests installed. However, simply adding to the file import kennethreitz.requests is not including the Requests module. I import kennethreitz.requests.__init__ and a few other obvious permutations but I cannot get the module to import. How can I package Requests with my code? The obvious Google searches are not helping.
requests is using an absolute import. You cannot arbitrarily nest packages into other directories and still expect things to work.
Instead, add the kennethreitz directory (which should not have a __init__.py file) to your sys.path module search path. That way the requests module will still be importable as a top-level package.
Next, you may want to look into Python packaging, dependencies and using a tool like pip or zc.buildout to deploy your code for you. Those tools handle dependencies for you and will install requests as required. See the Python Packaging User Guide for an introduction.

Categories