Skip to content

Instantly share code, notes, and snippets.

@saghul
Created June 21, 2011 06:31
Show Gist options
  • Save saghul/1037345 to your computer and use it in GitHub Desktop.
Save saghul/1037345 to your computer and use it in GitHub Desktop.
Importing Python modules from the web
# Derived from: http://paste.pocoo.org/show/407530/
import sys
import imp
import urllib2
import urlparse
class WebImporter(object):
def __init__(self, path):
url = urlparse.urlparse(path)
if url.scheme not in ('http', 'https'):
raise ImportError
self.path = path
self._cache = {}
@classmethod
def register(cls):
sys.path_hooks.append(cls)
def _get_source_and_filename(self, name):
rv = self._cache.get(name)
if rv is not None:
return rv
url_name = name.replace('.', '/')
if url_name.endswith('.py'):
urls = (url_name)
else:
urls = (url_name + '.py', url_name + '/__init__.py')
for filename in urls:
try:
url = urlparse.urljoin(self.path, filename)
try:
resp = urllib2.urlopen(url)
except urllib2.URLError:
continue
if resp.code == 404:
continue
rv = resp.read(), url
self._cache[name] = rv
return rv
except IOError:
continue
raise ImportError(name)
def get_source(self, name):
return self._get_source_and_filename(name)[0]
def get_filename(self, name):
return self._get_source_and_filename(name)[1]
def find_module(self, name, path=None):
try:
self._get_source_and_filename(name)
except ImportError:
return None
return self
def load_module(self, name):
source, filename = self._get_source_and_filename(name)
sys.modules[name] = mod = imp.new_module(name)
mod.__loader__ = self
mod.__file__ = filename
if filename.endswith('/__init__.py'):
mod.__path__ = [filename.rsplit('/', 1)[0]]
exec source in mod.__dict__
return mod
def test1():
sys.path.insert(0, 'http://random.saghul.net/foo.py')
import foo
print foo.__file__
foo.foo()
def test2():
sys.path.insert(0, 'http://random.saghul.net/bar')
from bar import baz
print baz.__file__
baz.test()
def test3():
sys.path.insert(0, 'http://random.saghul.net/pymodules/')
import simplejson
print simplejson.__file__
try:
r = urllib2.urlopen('http://api.icndb.com/jokes/random')
except urllib2.URLError:
pass
else:
data = simplejson.loads(r.read())
if data.get('type', None) == 'success':
print data['value']['joke']
if __name__ == '__main__':
WebImporter.register()
print "---------- TEST 1 -----------"
test1()
print "---------- TEST 2 -----------"
test2()
print "---------- TEST 3 -----------"
test3()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment