How to include third party Python packages in Sublime Text 2 plugins
Asked Answered
S

2

30

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
Sarmentum answered 2/3, 2013 at 23:12 Comment(0)
J
22

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

Jaworski answered 3/3, 2013 at 0:8 Comment(7)
thanks for the quick reply. I have tried this - sys.path.append(os.path.join(os.path.dirname(file), "/usr/lib/python2.7/dist-packages/")). It seems to see both the 'requests' module and 'urllib3' module which were installed with pip. But now it has the following error - File "/usr/lib/python2.7/dist-packages/urllib3/filepost.py", line 15, in <module> from io import BytesIO File ".\io.py", line 63, in <module> ImportError: No module named _fileioSarmentum
I have edited my question with a solution for this problem. Thanks again Mikko!Sarmentum
The information in this answer is incredibly important to creating Sublime Text plugins. It really should be in the official docs...Tripetalous
It is larger problem of Python community to decide whether requests should go to Python stdlib or not, not ST to alone tackle thisJaworski
Or ST should just let their plugins be developed like any normal Python app (allowing use of a virtualenv, etc). Then we could just pip install requests and then import requests in the plugin's main.py.Tripetalous
@yourfriendzak Unforutnately the best and most promising open source sublime clone is being written in GoLang, and not python. limetextConklin
@MikkoOhtamaa I mean a text editor that is actually not an underperformance, "website in a box" that doesn't even know what overtype mode is. (even MS word has overtype)Conklin
T
5

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.

Tripetalous answered 26/8, 2013 at 11:2 Comment(2)
This most likely breaks if requests library contains any absolute imports.Jaworski
I haven't tested in that scenario, so you might be right. But let's hope requests avoids doing that because absolute paths are almost always a bad idea unless absolutely necessary.Tripetalous

© 2022 - 2024 — McMap. All rights reserved.