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
Community
  • 1
  • 1
Alexey Zagalsky
  • 307
  • 2
  • 4
  • 10

2 Answers2

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

Mikko Ohtamaa
  • 69,174
  • 40
  • 208
  • 346
  • 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 from io import BytesIO File ".\io.py", line 63, in ImportError: No module named _fileio – Alexey Zagalsky Mar 03 '13 at 08:39
  • I have edited my question with a solution for this problem. Thanks again Mikko! – Alexey Zagalsky Mar 03 '13 at 10:27
  • 3
    The information in this answer is **incredibly important** to creating Sublime Text plugins. It really should be in the official docs... – zakdances Aug 24 '13 at 00:05
  • It is larger problem of Python community to decide whether requests should go to Python stdlib or not, not ST to alone tackle this – Mikko Ohtamaa Aug 24 '13 at 13:24
  • 5
    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`. – zakdances Aug 25 '13 at 07:42
  • 1
    @yourfriendzak Unforutnately the best and most promising open source sublime clone is being written in GoLang, and not python. [limetext](http://limetext.org/) – ThorSummoner Oct 22 '15 at 18:21
  • @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) – ThorSummoner Oct 23 '15 at 05:18
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.

zakdances
  • 16,715
  • 30
  • 94
  • 155
  • 1
    This most likely breaks if requests library contains any absolute imports. – Mikko Ohtamaa Aug 27 '13 at 11:29
  • 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. – zakdances Aug 28 '13 at 01:15