Показаны сообщения с ярлыком python. Показать все сообщения
Показаны сообщения с ярлыком python. Показать все сообщения

суббота, 1 июня 2024 г.

bottle vs flask?

 Есть 2 схожих фреймворка, bottle и flask, весьма похожи, оба на питоне, основное отличие - bottle.py это ровно 1 файл, кинули в проект и всё. Пригодно для чего-то совсем мелкого.  Ну и статус развития bottle под вопросом.

среда, 17 апреля 2019 г.

Пример проверки пользователя в LDAP

import  ldap
c = ldap.initialize("ldap://ldap.loc")
# Fix for MS AD
# https://www.python-ldap.org/en/latest/faq.html
c.set_option(ldap.OPT_REFERRALS, 0)
# Сначала получаем данные юзера от админа
c.bind_s('admin', 'admin_pass')
res = c.search_s('dc=ldap,dc=loc', ldap.SCOPE_SUBTREE, "SAMAccountName=USER",['objectclass'], 1)
new_cred = res[0][0]
# Теперь пробуем подключиться как нужный юзер
c.bind_s(new_cred, 'user_pass')
print "OK"

вторник, 30 января 2018 г.

python+yaml

yum install python-pip
pip install pyyaml


down vote
accepted
#!/usr/bin/env python

import yaml

with open("example.yaml", 'r') as stream:
    try:
        print(yaml.load(stream))
    except yaml.YAMLError as exc:
        print(exc)


Или вообще так
Dict = yaml.load(open('filename'))

Хотя он только yaml 1.1, и
Do not use PyYAML, it is long dead, use ruamel.yaml.
from ruamel import yaml

понедельник, 3 июля 2017 г.

json in bash

https://stackoverflow.com/questions/1955505/parsing-json-with-unix-tools

1) jq
curl -s 'https://api.github.com/users/lambda' | jq -r '.name'

2) python
Python 2:
export PYTHONIOENCODING=utf8
curl -s 'https://api.github.com/users/lambda' | \
    python -c "import sys, json; print json.load(sys.stdin)['name']"
Python 3:
curl -s 'https://api.github.com/users/lambda' | \
    python3 -c "import sys, json; print(json.load(sys.stdin)['name'])"

пятница, 19 августа 2016 г.

python: ошибка SyntaxError: invalid token у rpmbuild

Для питона достаточно бесполезный функционал компилирования иногда ломает сборку пакета. Фикс - в spec файл в начало добавляем
%global _python_bytecompile_errors_terminate_build 0

четверг, 17 декабря 2015 г.

python mailers

Совсем простой вариант - через email
https://docs.python.org/2/library/email-examples.html

Можно взять небольшую обёртку mailer, но размер кода оно сильно не уменьшит, а зависимость добавит.

Ими легко слать через системный почтовик и системные очереди. Если требуется подключаться к тому же gmail - код несколько усложняется - добавляются шаги авторизации, starttls итд, и тогда добавляется библиотека smtplib (или всякие yagmail)

Когда требуется поддержка юникода, добавляется она не сложно, только надо помнить что некоторые заголовки типа Subject, From, To требуют особого кодирования, недопустимо просто писать юникод-строку, так делают только быдлокодеры. Должно быть так:
from email.header import Header
msg = MIMEMultipart()
msg['Subject'] = "%s" % Header(subject, 'utf-8') - вообще тут надо отделить имя от адреса и преобразовать только имя, или наоборот склеивать преобразованное имя с адресом. Под рукой нет готового примера. При этом итоговый вариант будет таким:
From: =?UTF-8?B?0J0J0J0J0J0J=?= <mail@mail.me>

С текстом проще
msg.attach(MIMEText(text, 'plain', "UTF-8"))
msg.attach(MIMEText(html, 'html', 'UTF-8'))


Если используются фреймворки типа flask, там обычно есть свои обёртки/реализации, тот же flask-mailer
Также есть пакеты для более массовой рассылки, на базе шаблонов, тот же pymassmailer

среда, 16 декабря 2015 г.

decoder jpeg not available (вариант encoder libtiff not available)

доставить библиотеки
yum install libjpeg-devel
yum install freetype-devel
yum install libpng-devel

также может требоваться конкретная версия либы
yum install libjpeg-devel zlib1g-devel libpng12-devel

sudo aptitude install libjpeg62 libjpeg62-dev zlib1g-dev
sudo apt-get install libjpeg8-dev

в особо запущенных случаях
sudo ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib

pip uninstall pil
pip install pillow

если уже стояло
# reinstall pillow
pip install --no-cache-dir -I pillow

SQLAlchemy Custom Types

http://docs.sqlalchemy.org/en/latest/core/custom_types.html
http://docs.sqlalchemy.org/en/latest/orm/composites.html

Допустим, есть у нас задача - на лету переводить столбец uuid в unhex-представление.
class HashColumn(VARBINARY):
  def bind_expression(self, bindvalue):
  #bindvalue = type_coerce(bindvalue, Binary)
  return func.unhex(func.replace(bindvalue, '-', ''))

  def column_expression(self, col):
    return func.lower(func.hex(col))

def select(table_name):
  table = Table(table_name, self.metadata, Column("uuid", HashColumn(20)), autoload=True, extend_existing=True)
  select = table.select()
  ...
Казалось бы, тут был бы логичнее TypeDecorator, но..

<Elmer> oh yeah that TypeDecorator doesn't work because the process_bind_param and process_result_value methods should be Python code, func.hex/func.unhex create SQL function calls

Правильно создаём table и получаем автоматом преобразование.

http://stackoverflow.com/questions/33923914/python-sqlalchemy-binary-column-type-hex-and-unhex/33925980#33925980
http://stackoverflow.com/questions/34039039/python-sqlalchemy-binary-column-type-hex-and-unhex-with-autoloaded-table

вторник, 8 декабря 2015 г.

python: inline картинки

Суть:

msgRoot = MIMEMultipart('related')
html = """\
    <p>This is an inline image<br/>
        <img src="cid:image1">
    </p>
"""
msgHtml = MIMEText(html, 'html')

Подробнее:

пятница, 4 декабря 2015 г.

InsecureRequestWarning: Unverified HTTPS request is being made.

При использовании requests, даже когда выставляем verify=False, в логи может сыпать варнингами
InsecureRequestWarning: Unverified HTTPS request is being made.

Как отключить этот crap:
https://urllib3.readthedocs.org/en/latest/security.html#disabling-warnings

в случае прямого использования urllib3
import urllib3
urllib3.disable_warnings()

В случае requests
import requests.packages.urllib3 as urllib3
urllib3.disable_warnings()

четверг, 3 декабря 2015 г.

python+mysql

во 2 питоне есть MySQLdb, в 3 его нет. Самая простая замена:
import pymysql
pymysql.install_as_MySQLdb()

Более полный список вариантов

вторник, 11 августа 2015 г.

Делаем цветной вывод логов

Самый простой вариант -- используя цветовые коды и print
print u"\x1b[31;40mЧто-то красное на чёрном\x1b[0m"

Но использовать такую конструкцию очень сложно, особенно если цветовых вариантов больше одного. Да и замена цвета будет той ещё головной болью...
Можно составить "карту" цветов и использовать в виде переменных (или подключить colorama), но это очень неудобно. Примеры в комментах. Или.
Особенно, когда нужно несколько цветов по разным уровням ошибки, и появляется обёртка вида
def mylog-red-black(string):
    print u"\x1b[31;40m%s\x1b[0m" % (string,)
....

понедельник, 8 июня 2015 г.

python: замеряем время выполнения блока

time.time

Очень простой и вполне рабочий метод на базе time, работает даже во 2 питоне (в 3 есть ещё несколько функций в модуле, с бОльшей точностью)

вторник, 2 июня 2015 г.

python: многопоточность

Есть 2 модуля, схожие по названиям и функциям, но работающие чуть по разному, это
threading.Thread
и
multiprocessing.Process

Но threading создаёт нить внутри процесса (количество процессов не меняется), а mp - создаёт новый процесс.

https://docs.python.org/2/library/threading.html
https://docs.python.org/2/library/multiprocessing.html

В остальном использование довольно простое, делаем инстанс класса, start и при необходимости join

понедельник, 1 июня 2015 г.

Python: пишем в syslog

Хороший стартовый пример
https://gist.github.com/sweenzor/1782457

123456789101112131415161718192021
import logging
import logging.handlers
 
log = logging.getLogger(__name__)
 
log.setLevel(logging.DEBUG)
 
handler = logging.handlers.SysLogHandler(address = '/dev/log')
 
formatter = logging.Formatter('%(module)s.%(funcName)s: %(message)s')
handler.setFormatter(formatter)
 
log.addHandler(handler)
 
 
def hello():
log.debug('this is debug')
log.critical('this is critical')
 
if __name__ == '__main__':
hello()

123
matt@Jenkins:~$ tail -n 2 /var/log/syslog
Feb 9 11:56:19 Jenkins logtest.hello: this is debug
Feb 9 11:56:19 Jenkins logtest.hello: this is critical

Нюансы.
Для SysLogHandler обязателен адрес, у линукса /dev/log, у macos что-то вроде /var/run/syslog, надо уточнять.

Также можно сделать так
handler = logging.handlers.SysLogHandler(address = ('localhost',514), facility=19)
и тут localhost можно заменить на удаленный хост, хотя лучше поручить пересылку логов тому же rsyslog

Также есть менее удобный модуль syslog
import syslog
syslog.openlog( 'myTestLog', 0, syslog.LOG_LOCAL4 )
syslog.syslog( '%%TEST-6-LOG: Log msg: %s' % 'test msg' )

Ну и напоследок интересный линк
http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-python-apps/

понедельник, 25 мая 2015 г.

python: 7 способов получить hostname

Все работают в линуксе, но далеко не все - в винде. Плюс в ряде случаев hostname и hostname -f могут не совпадать, надо проверить, что лучше подойдёт.

1) import os; print os.uname()[1]
2) import platform; print platform.uname()[1] - как 1, но более универсален, работает и в винде
3) import platform; print platform.node()
4) import socket; print socket.gethostname() (подвид: socket.gethostbyaddr(socket.gethostname())
5) import socket; print socket.getfqdn() - 4 и 5 как раз могут дать разные результаты
6 и 7) - совсем костыльные решения, os.getenv('HOSTNAME') и os.environ['HOSTNAME']

До кучи - есть всякие os.system() и os.popen(), но это совсем костыли и даже не стоят упоминания.

линки
https://wiki.python.org/moin/Powerful%20Python%20One-Liners/Hostname
http://stackoverflow.com/questions/20792499/how-to-get-fully-qualified-host-name-in-python
http://stackoverflow.com/questions/4271740/how-can-i-use-python-to-get-the-system-hostname

вторник, 19 мая 2015 г.

python и рекурсивная работа с файлами

1) os.listdir
import os
for filename in os.listdir(os.getcwd()):
if filename.endswith(".txt"):
print(os.path.join(root, file))

2) os.walk
import os
for root, dirs, files in os.walk(yourpath, topdown=False):
    for name in files:
        print(os.path.join(root, name))
        stuff
    for name in dirs:
        print(os.path.join(root, name))
        stuff

3) glob
import glob
for filename in glob.glob('*.txt'):
...

http://stackoverflow.com/questions/18262293/python-open-every-file-in-a-folder
http://stackoverflow.com/questions/3964681/find-all-files-in-directory-with-extension-txt-with-python

пятница, 12 сентября 2014 г.

Работаем с REST

Например, пишем своё апи и нужен некий стандарт, по которому будет взаимодействовать мир и наш апи. Раньше для этого использовали чистый XML и SOAP, сейчас всё более популярным становится rest-подход.
REST=REpresentational State Transfer
http://en.wikipedia.org/wiki/Representational_state_transfer

Много вопросов может вызывать, что передавать в заголовках, что в теле запроса.

Также нет чёткого разделения между PUT и POST, оба метода могут как добавлять записи, так и менять их. Тут совет такой: POST всегда добавляет запись, PUT добавляет если такой не было и меняет, если была. Это позволяет заново послать запрос, если нет уверенности в первом получении сервером, и это не должно вызывать дублей и ошибок.

Есть неплохое введение у Рея
Designing a RESTful API with Python and Flask
Writing a Javascript REST client
Designing a RESTful API using Flask-RESTful
Implementing a RESTful Web API with Python & Flask

Тут много интересного, в том числе замена POST-ом операций PUT и DELETE

вторник, 12 августа 2014 г.