Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
pipista - pip module (for installing other modules) for Pythonista
import os, os.path, sys, urllib2, requests
class PyPiError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
def _chunk_report(bytes_so_far, chunk_size, total_size):
if (total_size != None):
percent = float(bytes_so_far) / total_size
percent = round(percent*100, 2)
print 'Downloaded %d of %d bytes (%0.2f%%)' % (bytes_so_far, total_size, percent)
if bytes_so_far >= total_size:
print ''
else:
print 'Downloaded %d bytes' % (bytes_so_far)
def _chunk_read(response, chunk_size=32768, report_hook=None, filename=None):
file_data = []
if response.info().has_key('Content-Length'):
total_size = response.info().getheader('Content-Length').strip()
total_size = int(total_size)
else:
# No size
total_size = None
if report_hook:
print '* Warning: No total file size available.'
if (filename == None) and (response.info().has_key('Content-Disposition')):
# If the response has Content-Disposition, we take file name from it
try:
filename = response.info()['Content-Disposition'].split('filename=')[1]
if filename[0] == '"' or filename[0] == "'":
filename = filename[1:-1]
except Exception:
sys.exc_clear()
filename = 'output'
if (filename == None):
if report_hook:
print "* No detected filename, using 'output'"
filename = 'output'
bytes_so_far = 0
while True:
chunk = response.read(chunk_size)
bytes_so_far += len(chunk)
if not chunk:
break
else:
file_data.append(chunk)
report_hook(bytes_so_far, chunk_size, total_size)
return (file_data, filename)
def _download(src_dict, print_progress=True):
headers = {'User-Agent' : 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6;en-US; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9'}
if print_progress:
print '* Downloading:', src_dict['url']
req = urllib2.Request(src_dict['url'], headers=headers)
response = urllib2.urlopen(req)
output = src_dict['url'].split('/')[-1].split('#')[0].split('?')[0]
if print_progress:
data,filename = _chunk_read(response, report_hook=_chunk_report, filename=output)
else:
data,filename = _chunk_read(response, report_hook=None, filename=output)
if (len(data) > 0):
try:
f = open(filename, 'wb')
for x in data:
f.write(x)
f.close()
if print_progress:
print '* Saved to:', filename
except Exception:
if print_progress:
print '! Error:', sys.exc_info()[1]
raise
else:
if print_progress:
print '* Error: 0 bytes downloaded, not saved'
def pypi_download(pkg_name, pkg_ver='', print_progress=True):
pypi = xmlrpclib.ServerProxy('http://pypi.python.org/pypi')
hits = pypi.package_releases(pkg_name, True)
if not hits:
raise PyPiError('No package found with that name')
if not pkg_ver:
pkg_ver = hits[0]
elif not pkg_ver in hits:
raise PyPiError('That package version is not available')
hits = pypi.release_urls(pkg_name, pkg_ver)
if not hits:
raise PyPiError('No public download links for that version')
source = ([x for x in hits if x['packagetype'] == 'sdist'][:1] + [None])[0]
if not source:
raise PyPiError('No source-only download links for that version')
return _download(source, print_progress)
def pypi_versions(pkg_name, limit=10, show_hidden=True):
if not pkg_name:
return []
pypi = xmlrpclib.ServerProxy('http://pypi.python.org/pypi')
hits = pypi.package_releases(pkg_name, show_hidden)
if not hits:
return []
if len(hits) > limit:
hits = hits[:limit]
return hits
def pypi_search(search_str, limit=5):
if not search_str:
return []
pypi = xmlrpclib.ServerProxy('http://pypi.python.org/pypi')
hits = pypi.search({'name': search_str}, 'and')
if not hits:
return []
hits = sorted(hits, key=lambda pkg: pkg['_pypi_ordering'], reverse=True)
if len(hits) > limit:
hits = hits[:limit]
return hits
def install_xmlrpclib(path='.'):
# Grab the 2.7.3 version of xmlrpclib - even though Pythonista 1.2 is 2.7.0
r = requests.get('http://hg.python.org/cpython/raw-file/70274d53c1dd/Lib/xmlrpclib.py')
lib_file = os.path.join(path, 'xmlrpclib.py')
with open(lib_file, 'w') as f:
f.write(r.text)
# The following code is intentionally executed on import of the pipista module.
# It patches the standard import search paths to include the directory pipista
# installs downloaded modules in.
# If you really don't like this functionality, just edit this script to:
# _auto_path = False
_auto_path = True
# Begin library prep
if _auto_path:
# Get pipista location
mod_path = os.path.abspath(__file__)
mod_dir = os.path.dirname(mod_path)
lib_dir = os.path.join(mod_dir, 'pypi-modules')
if not os.path.exists(lib_dir):
try:
os.mkdir(lib_dir)
except Exception:
# Fail silently, if we can't make the directory
sys.exc_clear()
# Make sure lib_dir exists before adding it to the paths
if os.path.exists(lib_dir):
if lib_dir not in sys.path:
sys.path += [lib_dir]
# Attempt to load xmlrpclib - not present in Pythonista 1.2
try:
import xmlrpclib
except ImportError:
# Doesn't seem to be available - attempt to download it.
sys.exc_clear()
install_xmlrpclib(lib_dir)
import xmlrpclib

nheagy commented Dec 13, 2013

How is this used?

aegroup commented Jan 2, 2014

Import pipista
pipista.pypi_search | version | download

Just FYI: I believe this version doesn't work in iOS 7.1. It downloads the tar files okay, but doesn't process them. Haven't tried whether the forked versions fix this.

kmaiya commented Mar 15, 2014

So if i want to intall nltk cam i use this , and can someone give me precise directions on how to use pipista

cclauss commented Mar 16, 2014

You can not merely run pipista.

Instead, you must use the Pythonista commandline to import it and use it following the example in the first post in this thread: http://omz-forums.appspot.com/pythonista/post/5794924494585856

cclauss commented Aug 21, 2014

Pipista does not uncompressed/unpack (unzip / ungzip / unbz2 / untar) its results. There are several modules in Pythonista for doing that: http://omz-software.com/pythonista/docs/library/archiving.html but the current Pypista does not do that uncompressing/unpacking for you.

And even after untaring I have problems to see this module in my scripts. import detects nothing :/

glyph commented May 24, 2016

These URLs should really be https :-(. It's not safe to download code via http.

Behinder commented Jul 7, 2016

Pipista started to return error "Must access using HTTPS instead of HTTP". How to fix it?

@Behinder: I changed the pypi url's to https (just in the two strings), and this error^ seemed to go away.

boxed commented Aug 24, 2016

A updated, hopefully working, version can be found here: github.com/boxed/pipista

boxed commented Aug 27, 2016

It turns out my work was unnecessary. A working project is at: https://github.com/ywangd/stash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment