Skip to content

Instantly share code, notes, and snippets.

@fillest
Last active March 1, 2024 17:20
Show Gist options
  • Save fillest/a6bd2ba07ee5707e39041e05548a1ad2 to your computer and use it in GitHub Desktop.
Save fillest/a6bd2ba07ee5707e39041e05548a1ad2 to your computer and use it in GitHub Desktop.
python3 -m venv venv
venv/bin/pip install -U pip
venv/bin/pip install -U setuptools wheel
venv/bin/pip freeze --all | grep -v pkg-resources
import argparse
cli_parser = argparse.ArgumentParser()
cli_parser.add_argument('--smth-str', default = 'val', help = "")
cli_parser.add_argument('-n', type = int, default = 2, choices = [1, 2, 3])
cli_parser.add_argument('-o', '--optional-smth', action = 'store_true')
cli_parser.add_argument('smth-required')
cli_args = cli_parser.parse_args()
import sys
print("...", file=sys.stderr) #print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
import sys; print ...; sys.stdout.flush() #py2
import logging
logging.basicConfig(level = logging.INFO, format = '%(asctime)s %(levelname)-5.5s %(name)s:%(lineno)d:%(funcName)s %(message)s')
logger = logging.getLogger(__name__)
logger.error("%s %s", 1, 2) #debug, info, warning, critical, exception
"%.3f" % 0.5556 #0.556
f"{elapsed:0.2f} sec"
"{a:.3f}".format(a = 0.5556) #"{:.3f}".format(0.5556)
# %d for ints
"%-4s" % #pad right with spaces
"%+4s" % #pad left with spaces
#shallow-merge dicts
a | b #v3.9+
{**a, **b} #v3.5+
{**a, 'k': 123}
#note: can throw OSError: [Errno 18] Invalid cross-device link
import tempfile
import os
def write_file (fpath, content):
fd, tmp_fpath = tempfile.mkstemp()
try:
with open(tmp_fpath, 'wb') as f:
f.write(content)
finally:
os.close(fd)
os.rename(tmp_fpath, fpath)
def main ():
#
if __name__ == '__main__':
main()
import datetime
datetime.datetime.utcfromtimestamp(ts)
datetime.datetime.utcnow()
datetime.timedelta(hours = 3)
dt.strftime('%Y.%m.%d %H:%M:%S')
datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S')
calendar.timegm(dt.utctimetuple()) #import calendar
#modern py3 https://blog.miguelgrinberg.com/post/it-s-time-for-a-change-datetime-utcnow-is-now-deprecated
now = datetime.datetime.now(datetime.timezone.utc)
#modern py3
import datetime
import time
def datetime_parse_utc(s: str, format: str):
return datetime.datetime(*(time.strptime(s, format)[:6]), tzinfo=datetime.timezone.utc)
datetime_parse_utc('2024-03-01 15:23:32', '%Y-%m-%d %H:%M:%S')
import signal
import sys
should_stop = [False]
def plan_stop (signum, _frame):
if signum == signal.SIGTERM:
should_stop[0] = True
print("caught SIGTERM", file = sys.stderr)
else:
print(f"caught unexpected signal {signum}", file = sys.stderr)
def main ():
signal.signal(signal.SIGTERM, plan_stop)
_got_signal = False #good enough to consider atomic
def _handle_signal (signum, _frame):
global _got_signal
_got_signal = True
print(f"Got signal: {signal.Signals(signum).name}", file = sys.stderr, flush = True)
def init_stop_signal_handlers (signals = {signal.SIGTERM, signal.SIGINT}):
for sig in signals:
signal.signal(sig, _handle_signal)
def got_stop_signals ():
global _got_signal
return _got_signal
import contextlib
import cStringIO
import gzip
def compress (str_):
with contextlib.closing(cStringIO.StringIO()) as buf:
buf.seek(0)
buf.truncate(0)
with gzip.GzipFile(fileobj = buf, compresslevel = 8, mode = 'wb') as gzf:
gzf.write(str_)
return buf.getvalue()
def decompress (bindata):
with contextlib.closing(cStringIO.StringIO(bindata)) as strfile:
with gzip.GzipFile(fileobj = strfile, mode = 'rb') as gzfile:
return gzfile.read()
#jinja2
{{ var|default('not defined') }}
{% if somevar is defined %}
{% endif %}
#library logging, to prevent "No handlers could be found for logger ...". in __init__.py
logging.getLogger(__name__).addHandler(logging.NullHandler())
#build url
'...?' + urllib.urlencode({'id': 1})
import requests
from requests.auth import HTTPBasicAuth
with requests.Session() as sess:
sess.auth = HTTPBasicAuth(os.getenv('user', 'test'), os.getenv('password', 'test'))
timeout = (10, 30) #not avail for session
resp = sess.post('https://url', params = {'name': 123}, data = {'name': 123}, timeout = timeout)
#jinja2
# {# comment #}
# ... ## comment --TODO check if enabled by default
import threading
#py2
thr = threading.Thread(target = fn, name = 'myname', args = [], kwargs = {})
thr.daemon = True
#py3
thr = threading.Thread(target = fn, name = 'myname', args = [], kwargs = {}, daemon = True)
thr.start()
thr.join()
lock = threading.Lock()
with lock:
#
import concurrent.futures
with concurrent.futures.ThreadPoolExecutor(max_workers = 2) as executor:
futures = [
executor.submit(fn),
executor.submit(fn),
]
#shutdown (with) waits by default - no need to call anything if you don't need result or to raise
for future in concurrent.futures.as_completed(futures):
ret = future.result() #raises
#by default suppresses exceptions - e.g. wrap the callback
#use cancel_futures to stop (e.g. on signal) or check at start of the callback
#decorator
import functools
def final_name (_arg):
def deco (orig_fn):
@functools.wraps(orig_fn)
def wrapper (*args, **kwargs):
return orig_fn(*args, **kwargs)
return wrapper
return deco
#py3 json to/from file
with open(fpath, 'w', encoding = 'utf-8') as f:
json.dump(v, f, ensure_ascii = False)
with open(fpath, encoding = 'utf-8') as f:
v = json.load(f)
import sys; assert sys.version_info[0] > 2, "python3 required"
from operator import itemgetter
alist.sort(key = itemgetter(0))
https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html#built-in-types
#fabric stuff
with hide('stdout'):
out = run('')
#regexps
import re
match = re.match(r'^foo(.+)$', s)
if match:
match[1] #--py3?
re.search(r'^foo(.+)$', s, re.MULTILINE)
#combining string literal modifiers
a = 1; print(rf'\\ {a}')
> \\ 1
#kw-only
def fn (*, arg): pass
fn(arg = 123)
os.path.expanduser('~/some-path')
class N:
def __init__(self):
self.v = 1
random.randint(1, 3) #1 to 3 inclusively
import contextlib
@contextlib.contextmanager
def fn (...):
res = ...
try:
yield res
finally:
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment