Python - mwicat/personal GitHub Wiki
pipsi
apt-get install python3-venv
sudo pip3 install virtualenv wheel
curl https://raw.githubusercontent.com/mitsuhiko/pipsi/master/get-pipsi.py | python3
pipsi install --python /usr/bin/python3.7 hovercraft
pipsi install --python /usr/bin/python3.7 -e .
Bootstrap project
cookiecutter gh:mwicat/cookiecutter-pypackage
Bootstrap project from config
cookiecutter gh:mwicat/cookiecutter-pypackage --config-file cookiecutter-mypackage.yaml --overwrite-if-exists --no-input
create virtualenv
python3 -m venv yourvenv
source yourvenv/bin/activate
install apps from virtualenvs
python3 -m pip install --user pipx
python3 -m userpath append ~/.local/bin
install apps
pipx install PACKAGE
list apps
pipx list
export PATH="$PATH:$HOME/.local/bin/mgr"
chain exceptions
from six import raise_from
raise_from(new_exception, original_exception)
uwsgi app
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
uwsgi --http :9090 --wsgi-file foobar.py
Progressbar
sudo pip install progressbar2
import progressbar
WIDGETS = [
progressbar.FormatLabel('%(value)d/%(max)d'), ' ',
progressbar.Percentage(), ' ',
progressbar.Bar(), ' ',
progressbar.FileTransferSpeed(unit='lines'), ' ',
progressbar.ETA()
]
def pbar(seq, *args, **kw):
kw['widgets'] = WIDGETS
return progressbar.ProgressBar(*args, **kw)(seq)
lines = 944567
for row in pbar(rows, max_value=lines):
continue
import progressbar
with progressbar.ProgressBar(max_value=10) as bar:
for i in range(10):
time.sleep(0.1)
bar.update(i)
Remote debugging
pip install remote-pdb
from remote_pdb import set_trace; set_trace(port=4444)
or:
export REMOTE_PDB_PORT=4444
from remote_pdb import set_trace; set_trace()
Reload module list
import pkg_resouces; pkg_resources.get_distribution('winpdb2').activate()
Python 2.5 Compilation
http://www.talino.org/tutorials/install-python-261-without-trashing-ubuntu/
Edit ./Modules/Setup
Uncomment zlib line
sudo aptitude install build-essential libncursesw5-dev libreadline5-dev libssl-dev libgdbm-dev libbz2-dev libc6-dev libsqlite3-dev libdb-dev tk-dev
Fabric need Paramiko:
on windows - http://www.voidspace.org.uk/python/modules.shtml#pycrypto
Arguments parsing
from argh import *
@arg('text', default='hello world')
def another_echo(text):
print text
parser = ArghParser()
parser.add_commands([echo, another_echo])
if __name__ == '__main__':
parser.dispatch()
IPython
from IPython import embed; embed()
CPU Profiling
python -m cProfile -o profile_data.pyprof sql_distribution.py
sudo pip install pyprof2calltree
sudo apt-get install kcachegrind
pyprof2calltree -i profile_data.pyprof -k
Tornado timeout
tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 2, handler)
Memory profiling
from guppy import hpy
hp=hpy()
h=hp.heap()
h.byrcs
Torando profiling
from guppy import hpy; hp=hpy()
def stop_handler():
print 'stopping tornado'
IOLoop.instance().stop()
print 'snapshot'
h = hp.heap()
print 'starting ipython'
from IPython import embed; embed()
Fabric
import paramiko
paramiko.util.log_to_file('ssh.log')
Print object count on signal
import signal, gc
def debug(sig, frame):
gc.collect()
count0, count1, count2 = gc.get_count()
count = count0 + count1 + count2
statsd.gauge('memory.object_count', count)
signal.signal(signal.SIGUSR1, debug) # Register handler
Print stack trace on signal
import code, traceback, signal, sys
def debug(sig, frame):
"""Interrupt running process, and provide a python prompt for
interactive debugging."""
d={'_frame':frame} # Allow access to frame object.
d.update(frame.f_globals) # Unless shadowed by global
d.update(frame.f_locals)
message = "Signal recieved : entering python shell.\nTraceback:\n"
message += ''.join(traceback.format_stack(frame))
sys.exit(1)
signal.signal(signal.SIGUSR1, debug) # Register handler
Too small /tmp
mkdir -p $HOME/tmp
export TMPDIR=$HOME/tmp
export PIP_DOWNLOAD_CACHE=$HOME/tmp
Remote console
sudo pip install rfoo
S:
from rfoo.utils import rconsole
rconsole.spawn_server()
C:
rconsole
Debugging
import pdb; pdb.set_trace()
Remote debugging
port: 51000 http://winpdb.org/docs/embedded-debugging/
sudo pip install winpdb
S:
rpdb2 -s -d -r script.py
or
import rpdb2; rpdb2.start_embedded_debugger('haslo', fAllowRemote=True, timeout=60)
C:
winpdb -olocalhost -a script.py
Get all instances of a class
instances = [obj for obj in gc.get_objects() if isinstance(obj, data.bcspell.BCspell)]
gc.get_referrers(instances[0])
Reuse Twisted protocols
from twisted.protocols import basic
from twisted.internet import protocol
rec = basic.NetstringReceiver()
from StringIO import StringIO
s = StringIO()
transport = protocol.FileWrapper(s)
rec.makeConnection(transport)
rec.sendString('marek')
s.getvalue()
Pyro
With nameserver
python -m Pyro4.naming
import Pyro4, nltk
Pyro4.Daemon.serveSimple({nltk.tokenize: 'tokenize'}, ns=True)
import Pyro4
tokenize=Pyro4.Proxy('PYRONAME:tokenize')
tokenize.word_tokenize('fajnie, co nie?')
Without nameserver
import Pyro4, nltk
Pyro4.Daemon.serveSimple({nltk.tokenize: 'tokenize'}, ns=False, port=4433)
import Pyro4
tokenize=Pyro4.Proxy('PYRO:tokenize@localhost:4433')
tokenize.word_tokenize('fajnie, co nie?')
Current traceback
import traceback; print ''.join(traceback.format_stack())
Time
import time; time.strftime("%d%m%y_%H%M%S", time.localtime())
Parse dates
from datetime import datetime
s = '2018-04-09 15:00:00'
dt = datetime.strptime(s, '%Y-%m-%d %H:%M:%S')
sudo pip install python-dateutil
from dateutil.parser import parse as parse_date
parse_date('21 Aug')
sudo pip install python-datemath
from datemath import parse as parse_datemath
parse_datemath('now-2d')
from dateutil.parser import parse as parse_date
from datemath import parse as parse_datemath
try:
start_dt = parse_date(start)
except ValueError:
start_dt = parse_datemath(start)
start_ts = time.mktime(start_dt.timetuple())
Format date
ISO8601
from datetime import datetime
import pytz
ts = 1463288494
tz = pytz.timezone('GMT')
print(datetime.fromtimestamp(ts, tz).isoformat())
import time
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(1347517370))
setup.py
#!/usr/bin/env python
from setuptools import find_packages, setup
setup(name='relmaker',
version='0.0.1',
description='a tool',
author='mwicat',
author_email='mwicat at gmail.com',
url='http://URL',
packages=find_packages(),
package_data={'relmaker': ['templates/*']},
include_package_data=True,
zip_safe=False,
install_requires=[
'argh>=0.24.1',
'argcomplete',
'requests',
'pygments',
],
entry_points={'console_scripts': [
'relmaker = relmaker.main:main'],
})
syntax color pygments
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import get_formatter_by_name
def hl(data, format):
return highlight(data, get_lexer_by_name(format), get_formatter_by_name('terminal'))
Parse url query
import urllib
url = 'http://foo.appspot.com/abc?def=ghi'
parsed = urllib.parse.urlparse(url)
u = urllib.parse.parse_qs(parsed.query)
from furl import furl
url = 'http://www.google.com/?one=1&two=2'
f = furl(url)
print f.args['three']
Encode url query
urllib.parse.urlencode(f)
Parse html
http://lxml.de/3.7/api/index.html
sudo pip install lxml cssselect
from lxml import html
url = 'http://econpy.pythonanywhere.com/ex/001.html'
params = {'a': 2}
page = requests.get(url, params=params)
tree = html.fromstring(page.content)
for div in tree.cssselect('a'):
print '%s: %s' % (div.text_content(), div.get('href'))
Configuration file
import ConfigParser
import os
RC_NAME = '.nagiosquery'
RC_FILE = os.path.join(os.path.expanduser('~'), RC_NAME)
cfg = ConfigParser.ConfigParser()
if os.path.exists(RC_FILE):
cfg.read(RC_FILE)
try:
username = cfg.get('credentials', 'username')
password = cfg.get('credentials', 'password')
except ConfigParser.Error:
username = None
password = None
Module directory path
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
Debug urllib/requests
try:
import http.client as http_client
except ImportError:
import httplib as http_client
http_client.HTTPConnection.debuglevel = 1
Decompile
sudo pip install uncompyle6
uncompyle6 -o src -r dir1 dir2
Timed seq
def timed_seq(seq, rate):
last_sec = int(time.time())
curr_cnt = 0
it = iter(seq)
while True:
curr_sec = int(time.time())
if curr_sec != last_sec:
curr_cnt = 0
last_sec = curr_sec
if curr_cnt < rate:
yield next(it)
curr_cnt += 1
time.sleep(0.001)
jinja templates
sudo pip install Jinja2
from jinja2 import Template
tpl = open('template.jinja2').read()
template = Template(tpl, trim_blocks=True, lstrip_blocks=True)
domains = [l.strip().split() for l in open('domains.lst')]
domains = [{'name' : d[0], 'sub': len(d) > 1} for d in domains]
print(template.render(domains=domains))
Parse number with commas
import locale
locale.setlocale(locale.LC_ALL, '')
locale.atof('100,050.23')
py2to3
2to3 --output-dir=mycode-py3 -W -n mycode
-W, --write-unchanged-files
Also write files even if no changes were required
(useful with --output-dir); implies -w.
-n, --nobackups Don't write backups for modified files