virtualenv venv
. venv/bin/activate
pip install --editable .
You want to really understand decorators? Watch this video!
boilerplate:
import functools
def decorator(func):
@functools.wraps(func)
def wrapper_decorator(*args, **kwargs):
# Do something before
value = func(*args, **kwargs)
# Do something after
return value
return wrapper_decorator
When you want to publish a beta version, you can use a special tag that won't be proposed to client using pip install package --upgrade
example :
current version = 3.0.1
next version = 3.1.0
I can tag with 3.1.0-alpha.1
pip install --upgrade won't upgrade to this version but pip install package==3.1.0-alpha.1 will
django template does not like defaultdict, 2 solutions:
1) set default_factory to None
or
2) cast defaultdict to a simpledict
"The template variable resolution algorithm in Django will attempt to resolve new_data.items as new_data['items'] first, which resolves to an empty list when using defaultdict(list)."
# filter out all elements not with x > 5
a = [el for el in data if el['x'] > 5]
# get all the 'c' attributes as a list
b = [el['c'] for el in data]
# get all the 'c' attributes for the elements with x > 5
c = [el['c'] for el in data if el['x'] > 5]
In Jinja2:
a: {{ data | selectattr('x', 'gt', 5) | list }}
b: {{ data | map(attribute='c') | list }}
c: {{ data | selectattr('x', 'gt', 5) | map(attribute='c') | list }}
Ce truc obscur qui t'arrive et où la solution se trouve au fond d'une PR
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
python dependency management with lock file
++++++++++++++++++++++
Version avec interface cmd
++++++++++++++++++++++
Prérequis :
pip install pudb
Pour docker, dans le docker compose ajouter
stdin_open: true
tty: true
Faire docker attach container_name
Comment break/debug :
Là où on veut break, il suffit de coller cette ligne : import pudb; pu.db
Dans le terminal où on a fait docker attach on doit voir l'interface de pudb
++++++++++++++++++++++
Version + simple
++++++++++++++++++++++
Prérequis : python 3.7
Pour docker, dans le docker compose ajouter
stdin_open: true
tty: true
Faire docker attach container_name
Comment break/debug :
breakpoint()
Dans le terminal où on a fait docker attach on doit voir un prompt
On peut print les variables
"continue" pour continuer
Here's my filter code
from django import template
register = template.Library()
@register.filter()
def smooth_timedelta(timedeltaobj):
"""Convert a datetime.timedelta object into Days, Hours, Minutes, Seconds."""
secs = timedeltaobj.total_seconds()
timetot = ""
if secs > 86400: # 60sec 60min 24hrs
days = secs // 86400
timetot += "{} days".format(int(days))
secs = secs - days*86400
if secs > 3600:
hrs = secs // 3600
timetot += " {} hours".format(int(hrs))
secs = secs - hrs*3600
if secs > 60:
mins = secs // 60
timetot += " {} minutes".format(int(mins))
secs = secs - mins*60
if secs > 0:
timetot += " {} seconds".format(int(secs))
return timetot
Then in my template I did
{% load smooth_timedelta %}
{% timedeltaobject|smooth_timedelta %}
def atoi(text):
return int(text) if text.isdigit() else text
def natural_keys(text):
return [ atoi(c) for c in re.split(r'(\d+)', text) ]
my_list.sort(key=natural_keys)
Au top pour faire des petits helper en cmd line
from distutils.util import strtobool
bool(strtobool('true'))
FOO = bool(strtobool(os.environ['FOO']))
retcode = subprocess.call(['echo', 'foo'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
un container qui va update les autres containers si une image plus récente a été trouvée (stop, rm, pull, recreate)
Pratique sur serveur perso pour les choses qui tournent en latest
Implémentation en Go, il y a le pendant python ici : https://github.com/pyouroboros/ouroboros
datetime.date.today().strftime("%Y-%m-%d")
datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
simple example on how to write a kubernetes operator
pour ne pas bufferiser l'ouput d'un script python et avoir le résultat en direct dans un | tee -a :
python -u script.py | tee -a mon.log
Good to know because it hurts me so bad:
When doing a put/post request with requests library, if the response is a redirect, request do the request again BUT with GET method...
-,-
python -m SimpleHTTPServer 8000
python -m http.server 8000
def print_format_table():
"""
prints table of formatted text format options
"""
for style in range(8):
for fg in range(30,38):
s1 = ''
for bg in range(40,48):
format = ';'.join([str(style), str(fg), str(bg)])
s1 += '\x1b[%sm %s \x1b[0m' % (format, format)
print(s1)
print('\n')
print_format_table()
python3 log to file AND stdout
import logging
logging.basicConfig(handlers=[logging.FileHandler('/var/log/runner/process1.log'),logging.StreamHandler()],format='%(asctime)s %(levelname)s %(message)s',level=logging.INFO)
logging.info('foo')
Encore mieux pour supporter le logrotate sans copytruncate :
import logging.handlers
logging.basicConfig(handlers=[logging.handlers.WatchedFileHandler('/var/log/worker/worker1.log'),logging.StreamHandler()],format='%(asctime)s %(levelname)s %(message)s',level=logging.INFO)
/var/log/worker/*.log {
monthly
rotate 12
compress
delaycompress
missingok
notifempty
create 644 root root
}
Python 2:
import logging as loggingg
logging = loggingg.getLogger('simple_example')
logging.setLevel(loggingg.INFO)
formatter = loggingg.Formatter('%(asctime)s %(levelname)s %(message)s')
console_handler = loggingg.StreamHandler()
console_handler.setLevel(loggingg.INFO)
console_handler.setFormatter(formatter)
file_handler = loggingg.FileHandler('/var/log/worker/worker3.log')
file_handler.setLevel(loggingg.INFO)
file_handler.setFormatter(formatter)
logging.addHandler(console_handler)
logging.addHandler(file_handler)
for root, dirs, files in os.walk("folder"):
for file in files:
if file.endswith(".yml"):
print(os.path.join(root, file))
with open(os.path.join(root, file), "r") as sources:
lines = sources.readlines()
with open(os.path.join(root, file), "w") as sources:
for line in lines:
sources.write(re.sub(r'pattern', 'foo', line))
Add /json to pypi package url.. Magic!
subnets = ec2.subnets.all()
subnets_sorted = sorted(subnets, key=lambda k: k.tags[next(index for (index, d) in enumerate(k.tags) if d["Key"] == "Name")]['Value'])
Well, my python level is not good enough to clearly understand this but my Google level was largely enough to build this
Running Bottle with a different server
As said above, the standard server is perfectly suitable for development, personal use or a small group of people only using your application based on Bottle. For larger tasks, the standard server may become a bottleneck, as it is single-threaded, thus it can only serve one request at a time.
But Bottle has already various adapters to multi-threaded servers on board, which perform better on higher load. Bottle supports Cherrypy, Fapws3, Flup and Paste.
If you want to run for example Bottle with the Paste server, use the following code:
from bottle import PasteServer
...
run(server=PasteServer)
This works exactly the same way with FlupServer, CherryPyServer and FapwsServer.
import logging
logging.basicConfig(filename='log.txt', format=logging.BASIC_FORMAT)
logging.error('OH NO!')
try:
raise Exception('Foo')
except:
logging.exception("Oops:")
Un cours en français qui a l'air très bien. Via sametmax sur twitter
useful script to migrate redis server without downtime
Pratique pour avoir des stat rapidement dans ses scripts python (si on n'a pas de stack graphite sous la main)
How to pretty print a json string :
cat pref.json | python -m json.tool
for uuoc nazi ;) :
< pref.json python -m json.tool
or
python -m json.tool < pref.json
Pour le fun et le learning : faire du tcp avec python / scapy
via sametmax
mini web framework en python, dans le meme genre que bottle :
http://bottlepy.org/docs/dev/index.html
une lib pour interagir facilement avec bash
Un serveur http wsgi en python, pour faire tourner du django. A voir si les perf sont meilleure qu'avec le mod apache
L'équivalent de php-fpm pour python (mettre un nginx devant)
Twisted is an event-driven networking engine written in Python and licensed under the open source MIT license.
virtualenv is a tool to create isolated Python environments.
Librairie python qui va nous servir pour piclodio2 (https://github.com/Sispheor/Piclodio2)
Chaque réveil est en fait une ligne dans le cron, avec un commentaire dans lequel on retrouve son id.. Du coup avec cette lib, l'interaction avec le cron va être + simple :-)
via Nico
Pour rendre un json lisible :
cmd_qui_donne_du_json | python -mjson.tool
python ou perl, faudrait choisir pour concevoir des scripts d'admin moins crades qu'en bash
Objectif : tapper /obug <number> dans xchat m'ouvre un onglet dans ff vers l'url du bug
1) activer le module python dans les options
2) créer un fichier .py dans /home/arnaud/.xchat2/
3)
module_name = "openbuginredmine"
module_version = "1.0"
__module_description__ = "module to open bug in redmine"
import os
import xchat
def obug(word, word_eol, userdata):
if len(word) < 2:
print "Second arg must be the bug number!"
else:
os.system("firefox https://monurlredmine.com/issues/"+word[1])
return xchat.EAT_ALL
xchat.hook_command("obug", obug, help="/obug <number> open bug in ff")
Et voilà, plus qu'à reboot le xchat, ou bien /load nomdufichier.py
ça peut etre appliqué à plein de trucs : pouvoir lancer ce qu'on veut depuis xchat
Différence entre python et php
Et un site pour débuter en python lorsqu'on vient de php :
http://www.inspyration.org/tutoriels/debuter-python-lorsque-lon-vient-de-php
Qu'est ce que l'unicode ? qu'est-ce qu'un encodage ? Comment python gère ça
Autres liens dans l'article à lire :
http://www.cs.tut.fi/~jkorpela/unicode/guide.html
http://www.joelonsoftware.com/articles/Unicode.html
http://en.wikipedia.org/wiki/Character_encoding
http://en.wikipedia.org/wiki/UTF-8
Forum pour demander de l'aide/chercher des réponses sur Python
Site pour apprendre à développer avec une approche interactive. Python en particulier