Analitycs

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

вторник, 25 октября 2011 г.

Сравнение нагрузки PyCurl vs HTTPClientFactory+Deferred в сервисе на Twisted

Решил перевыложить с хабры свое небольшое старое исследование по поводу производительности Twisted при использовании  PyCurl и HTTPClientFactory - пусть лежит все в одном месте, раз уж начал активно писать в блог.

В процессе разработки одного проекта на Python+Twisted (распределителя запросов между несколькими СМС гейтами Kannel) пришлось переписать вызов URL различных сервисов с разных серверов c блокирующего вызова через PyCurl на неблокирующий (client.HTTPClientFactory + deferred). Чтобы иметь перед глазами реальные данные о нагрузке, решил дать много запросов и посмотреть на результаты

Описание теста

Использовался Jakarta/Apache Jmeter - очень полезная софтинка, к сожалению, почему-то применяют ее для тестов достаточно редко (может, просто не знают о ее существовании?), но мне она весьма нравится - ибо возможности у нее большие и даже краткое описание наврядли влезет в несколько постов - если кому интересно, могу потом пробежаться по ней вкратце.
В 200 потоков прогнано 100 запросов на один и тот же сервер, но со случайными данными (чтобы исключить кэширование). Прогонялось на обыкновенной рабочей машине с GUI под Ubunta — так, для примерной оценки.

Результаты теста

Одна ошибка — не справилась база, так что погрешностью можно пренебречь.

Графики распределения

Блокирующий (PyCurl)
Неблокирующий (deferred)

Итоги

Как видно из результата теста — при одинаковой нагрузке при использовании defered минимальное значение отклика сервера почти в 2.5 раза меньше (из-за отказа базы), а максимальное — меньше в два раза, чем у блокирующего. Среднее значение - также меньше в 2 раза.

Америку я, конечно, не открыл, но по-крайней мере — теперь на руках конкретные цифры по производительности. Надеюсь, кому-нибудь они пригодятся.

четверг, 20 октября 2011 г.

Как демонизировать(daemon) проект на Twisted?

Есть три способа демонизировать проект на Twisted.

1) использование родного демона twistd. По идее - это более "методически грамотный" способ, но в свое время что-то не завелся у меня "в лоб", по этому до сих пор применяю второй.

2) скрестить старый работающий демон с реактором Twisted

#!/usr/bin/python                                                                                               
import sys
import src.daemon
import procname

class YourServer(twisted.web.server.Site):
    pass

class YourDaemon(Daemon):
    name   = 'yourserverd'
    site   = None
    server = None

    #--------------------------------------------------------------------------
    def __init__(self):
        self.server = YourServer()
        Daemon.__init__(self, pidfile='/var/run/%s.pid' % (self.name.lower()) )
        procname.setprocname(self.name)

    #--------------------------------------------------------------------------
    def run(self):
        self.server = YourServer()
        reactor.listenTCP(self.server.port, self.server)
        reactor.run()

if __name__ == '__main__':
      daemon = YourDaemon()
      daemon.processAction(sys.argv)

Да, procname служит для переименования процесса, о чем писал тут.


3) есть еще правда и python-daemon (PEP-3143), надо бы повнимательней изучить, но думаю что родной twistd оптимальней.

Вопрос Python+Mac+Qt+MySQL+py2app

Джентельмены (ну и дамы, разумеется), а никто на Python под Мак/кросплатформенно, да еще и с особыми извращениями (Qt+MySQL) не пишет случайно? Да еще и все это извращение в приложения .app не собирает, случаем?

Есть проблемка, а спросить не у кого, приходится на StackOverflow постить вопросы.

Заранее спасибо!

Да, "мсье знает толк..." (с)

суббота, 15 октября 2011 г.

Python py2app: AttributeError: 'module' object has no attribute 'TickCount'

Симптомы

После запуска собранного с помощью py2app пакета для MacOS на другой машине получаем падение с ошибкой

AttributeError: 'module' object has no attribute 'TickCount'

Лечение

В файле setup.py отключить argv_emulation, то есть - поставить в False

APP = ['MyApp.py']
OPTIONS = { 
   'argv_emulation': False,
   ...
}

setup(
    app=APP,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)


Подробности тут

вторник, 11 октября 2011 г.

Как узнать из какого каталога Python использует библиотеку? (import xxx)


$ python

Python 2.6.7 (r267:88850, Oct  8 2011, 08:42:47)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> import PyQt4
>>> PyQt4

<module 'PyQt4' from '/Users/michael_xiii/Envs/py26/lib/python2.6/site-packages/PyQt4/__init__.py'>

понедельник, 10 октября 2011 г.

Python - RuntimeError: maximum recursion depth exceeded while getting the str of an object

При активном использовании рекурсивных функций в Питоне начинает вываливаться ошибка RuntimeError: maximum recursion depth exceeded while getting the str of an object

Лечение быстрое, но не оптимальное

import sys
sys.setrecursionlimit(XXX)

Где XXX число, подбираемое экспериментально, основываясь на вашей программе. Но лучше, конечно, обходится без рекурсии. ;-)

суббота, 8 октября 2011 г.

PyQT на MacOS - Error: Unable to create the C++ code.

При сборке PyQt на MacOS вот по этому мануалу на команде

python configure.py

упорно вылезает ошибка

Error: Unable to create the C++ code.

Решение оказалось простым, как грабли - в пути до исходников не должно быть пробелов.

Теперь сижу, курю - жду пока соберется. ;-)

пятница, 23 сентября 2011 г.

Python mktime/strptime - TypeError: expected string or buffer

Иногда апдейты повергают меня в транс - недавно ловил баг с PHP+cURL, теперь отличился Python ;-/

Traceback (most recent call last):
  File "test.py", line 22, in 
    s = strptime(row['change_time'], TIME_FORMAT)  File "/usr/lib/python2.6/_strptime.py", line 454, in _strptime_time
    return _strptime(data_string, format)[0]
  File "/usr/lib/python2.6/_strptime.py", line 322, in _strptime
    found = format_regex.match(data_string)
TypeError: expected string or buffer

Описание

Лезем в код - получаем какой-то набор данных из MySQL через питоновский fetchall, затем преобразуем поле со временем и начинаем с ним танцевать.

Перестала работать конструкция
 
    s = strptime(row['change_time'], TIME_FORMAT)
    last_change_time = mktime(s)

После курения манов по времени в Python выясняется, что нужно в mktime отдавать 9 численный tuple


    s = row['change_time'].timetuple()
    last_change_time = mktime(s)

Вот и верь после этого людям... обновляй после этого пакеты...

четверг, 15 сентября 2011 г.

Как исправить ошибку Python datetime.datetime() is not JSON serializable?

Немного о сериализации через simplejson даты/времени, полученной из MySQL

При попытке сдампить результат из fetchall - чтобы отдать данные наружу во фронтендовский в Javascript в стиле

            sql  ='SELECT * FROM xxx WHERE id=%d'                                                          
            self._query(sql % id)
            data = self._cursor.fetchall()

получаем Exception

datetime.datetime(2011, 9, 14, 10, 18, 57) is not JSON serializable

Исправляется дополнительным форматом через лямбда-функцию

            dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime) else None
            response = json.dumps(data, ensure_ascii=False, default=dthandler)
Найдено, как водится - на StackOverflow

пятница, 9 сентября 2011 г.

Что не нужно в Python?


  • быстродействие
  • многопоточность 
  • компилятор
  • проверка типов
  • приватные методы
  • паттерн-матчинг
  • хвостовая рекурсия
  • switch-case
  • карринг
  • ленивость
  • алгебраические типы
  • округление результатов
  • соглашение об именовании 

Python - Да все это не нужно!

Я как бы НЕМНОГО переживаю из-за урезанной многопоточности но терпеть - можно.
И признайтесь честно - все это вам ДЕЙСТВИТЕЛЬНО нужно? ;-)

среда, 7 сентября 2011 г.

Python+MySQL+Bit fields = Error: invalid literal for int() with base 10: '\x01'

Причина - не нужно сравнивать значения, полученные из битового поля MySQL сразу с  int значениями - 0 и 1.

Методически грамотно - преобразовывать:

if int(result) != ord(row['bit_filed']):
    bla-bla-bla

вторник, 6 сентября 2011 г.

Habrahabr - такой хабр... осеннее обострение?


На Хабр можно ходить с разными целями - почитать что-то умное (иногда)... или поржать, потроллить на худой конец. Но последняя неделя - доставляет особенно.

Опрос про опыт работы PHP кодера и место его работы (офис/фриленс)

Разумеется, вариант "я PHP кодер, стаж больше 5 лет, и перешел нахрен на другой язык (python/ruby)" - автор забыл, но ему напомнили... После некоторого глумления в комментах пост исчез. Скриншотов снять не успел.

Создаём сайт на PHP без использования расширения в именах файлов

Здравствуй, Хабр! 
Многие из нас видели сайты, страницы которых не содержат расширения файла. Например, компания Google для поиска использует файл вида /search?q=%s. Многие также знают, что, как правило, такие сайты написаны с использованием технологии Java. Однако не все знают, что также можно делать и для php-скриптов. Если Вам стало интересно, прошу под кат.

Мне стало БЕЗУМНО интересно, но увы - пост уже ушел...

Анализируем производительность сервера

То человек, ВСЕРЬЕЗ предлагающий для построения графиков нагрузки серверов у кластера использовать Excel. Было тут, кеш Гугля

Аренда сервера или виртуальной машины в сети становятся все доступнее. На момент написания статьи аренда мощного 4-х ядерного сервера с неограниченным трафиком обходится всего в 70-100 долларов в месяц. 


По этой причине многие компании, веб-мастера и разработчики арендуют сервер для нескольких проектов вместо использования разделяемого хостинга. Преимущества очевидны: больший контроль над работой приложений и полное использование ресурсов сервера для своих проектов. Как определить, что производительности сервера стало недостаточно и пора производить обновление или замену? Какой из компонентов стал бутылочным горлышком? Эта статья поможет самостоятельно ответить на вопрос — требуется ли серверу замена? — используя сводные таблицы Microsoft Excel. 


Применяя описанный метод, для вас не составит труда подготовить красивый иллюстрированный отчет руководству, а также быстро найти узкие места в системе. Картинок будет много! Нам понадобятся две вещи: данные и инструмент их анализа. Для анализа данных производительности мы будем использовать «Сводные таблицы» из Microsoft Excel. В качестве примера данных используется записанный в CSV файл результат работы Perfomance Monitor. Это стандартный инструмент Windows Server, однако аналогично можно обработать данные, полученные на любой системе. 

Вот не могу понять - то ли осеннее обострение, то ли кто-то просто массово стебется.

Кстати, в третьем варианте человек-то именно Excel знал очень неплохо - судя по скриншотам. ;-)

понедельник, 5 сентября 2011 г.

Как скопировать dict в Python? copy.deepcopy

При частом переключении с PHP на Python часто ловишь баги и проблемы с копиями объектов, особенно - ассоциативных массивов/dict.
Что бы избежать неявных изменений данных - нужно делать deepcopy - полное копирование.

Вариант новичковый

    node_params = {}
    for key, value in data['params'].iteritems():
        node_params[key] = value

Вариант true pythonic ;-)

    from copy import deepcopy
    ...
    node_params = deepcopy(data['params'])    
Внимательнее с копиями ;-)

пятница, 5 августа 2011 г.

Как переименовать запущенный процесс python?

Когда в списке процессов много запущенных приложений Python - возникает желание избавится от многочисленных /usr/bin/python

# ps aux | grep python
root      6284  0.0  2.7  19740 10740 ?        S    10:55   0:00 /usr/bin/python ./demon start
root      6295  0.0  2.8  19740 10872 ?        S    10:55   0:00 /usr/bin/python ./demon restart
root      6296  0.0  2.7  19740 10748 ?        S    10:55   0:00 /usr/bin/python ./demon restart
root      7429  0.0  0.1   3300   744 pts/5    S+   11:15   0:00 grep python


Тем более демоны должны маскироваться ;-)

Решение - использовать пакет procname. Для Debian нужно иметь установленный PIP и python-dev дальше

#apt-get install python-dev

#pip install procname

Ну и вызов в коде

procname.setprocname('My super-puper process')

Подробности тут

Как определить разрядность системы (32/64 бит) через Python?

import array

#: формат для данных - беззнаковый int 4 байта
# проверка на платформы
if array.array('L').itemsize == 4:
      INTEGER_FORMAT = 'L' # для 32 битных систем
else:
      INTEGER_FORMAT = 'I' # для 64 битных систем

среда, 3 августа 2011 г.

Как поставить pip на Ubuntu/Debian?

Pip - гораздо лучшая альтернатива easy_install для установки пакетов Python. И он наиболее полно себя раскрывает с компаньоном virtualenv.

Устанавливаем pip и virtualenv для Ubuntu 10.10 Maverick и более свежих
$ sudo apt-get install python-pip python-dev build-essential
$ sudo pip install --upgrade pip
$ sudo pip install --upgrade virtualenv
На установке pip на Debian 6 Squeeze - ругнулся,
# pip install virtualenv
Traceback (most recent call last):
File "/usr/bin/pip", line 11, in
from pip.vcs import vcs, get_src_requirement, import_vcs_support
ImportError: cannot import name import_vcs_support
Upd: после некоторых действий по переустановке pip,  и выходу-логину заново - заработал. Причина - осталась неясна, к сожалению.

Для старых версий Ubuntu
Устанавливаем Easy Install
$ sudo apt-get install python-setuptools python-dev build-essential
Устанавливаем pip
$ sudo easy_install pip
Устанавливаем virtualenv
$ sudo pip install --upgrade virtualenv
По материалам: SaltyCrane 

пятница, 29 июля 2011 г.

Ошибка в paramiko - PID check failed. RNG must be re-initialized after fork(). Hint: Try Random.atfork()

Баг в paramiko возникает при использовании некоторых версияй

Варианты решения

1) патчим

locate paramiko/transport.py

в импорты файла добваляем

from Crypto.Random import atfork

и в самое начало метода run() в paramiko/transport.py добавляем вызов

atfork()


2) обновляемся до Paramiko 1.7.7.1

Как переключиться на другую версию Python в MacOS?

При установленных портах
sudo port select --set python python24
 Соответственно, версия питона - та, которая установлена и нужна в данных момент. Тем не менее - могут быть проблемы и лучше все-таки использовать виртуалки.