Posts Tagged: укрощение питона

SQLFORM.grid — коробочный настраиваемый броузер таблиц

Быстро вывести табличку с базой данных поможет такая простая конструкция в web2py :

grid = SQLFORM.grid(db.table)

А вот и параметры ее

SQLFORM.grid(
query,
fields=None, # выборка полей для вывода
field_id=None, # id - поле
left=None, # LEFT JOIN
headers={}, # Заголовки
orderby=None, # сортировка
groupby=None, # группировка
searchable=True, # поле поиска
sortable=True, # кнопки сортировки
paginate=20, # записей на страницу
deletable=True, # кнопка удалить
editable=True, # кнопка редактировать
details=True, # кнопка Подробнее
selectable=None, # чекбокс для выбора
create=True, # можно создавать новые элементы
csv=True, # экспорт в csv
links=None, # поля - ссылки
links_in_grid=True, # показывать в главной таблице ссылки
upload='<default>', #
args=[], #
user_signature=True, #
maxtextlengths={}, # максимальная длина текста в полях
maxtextlength=20, #
onvalidation=None, # функция вызываемая при проверке формы
oncreate=None, # функция при создании нового элемента
onupdate=None, # функция при редактировании элемента
ondelete=None, # функция при удалении элемента
sorter_icons=(XML('&#x2191;'), XML('&#x2193;')), # иконки сортировки
ui = 'web2py', # можно поставить jquery-ui, либо описать все компоненты индивидуально словарем
showbuttontext=True, # Текст на кнопках
_class="web2py_grid", # класс формы
formname='web2py_grid', # имя формы
search_widget='default', # поисковая форма
ignore_rw = False, #
formstyle = 'table3cols', #
exportclasses = None, #
formargs={}, # аргументы формы
createargs={}, # аргументы функции создания нового элемента
editargs={}, # аргументы функции редактирования элемента
viewargs={}, # аргументы функции просмотра элемента
buttons_placement = 'right', # кнопки справа
links_placement = 'right' # ссылки справа
)

Credits : http://www.web2py.com/book/default/chapter/07#SQLFORM.grid

logging : пишем логи в файл

Выводим время, уровень ошибки, файл и строку вызова, ну и естественно, текст сообщения:

import logging
logging.basicConfig(format = u'%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s] %(message)s', level = logging.DEBUG,  filename = u'applog.log')

logging.debug('This is just a debug')

via http://habrahabr.ru/post/144566/

upd: лучший пример со stackoverfow :

import logging
log = logging.getLogger("mylog")
log.setLevel(logging.DEBUG)

formatter = logging.Formatter(
    "%(asctime)s %(threadName)-11s %(levelname)-10s %(message)s")
# Alternative formatting available on python 3.2+:
# formatter = logging.Formatter(
#     "{asctime} {threadName:>11} {levelname} {message}", style='{')

# Log to file
filehandler = logging.FileHandler("debug.txt", "w")
filehandler.setLevel(logging.DEBUG)
filehandler.setFormatter(formatter)
log.addHandler(filehandler)

# Log to stdout too
streamhandler = logging.StreamHandler()
streamhandler.setLevel(logging.INFO)
streamhandler.setFormatter(formatter)
log.addHandler(streamhandler)

# Test it
log.debug("Some message")
log.error("An error!")
try:
    something()
except:
    log.exception("An exception occured!")

via http://stackoverflow.com/questions/4722745/logging-between-classes-in-python

 

scrapy — кроулим, парсим и грабим

scrapy — весьма ценная библиотека для тех, кому нужно пройти по большому массиву страниц (с большой вложенностью, заранее не ограниченному), и добыть оттуда набор однотипной информации.

В общем, пойди туда — пока не знаю куда, принеси то — пока не знаю что. И сформируй из этого таблицу csv или файл json.

pip install scrapy
# создаем новый проект - ScrapySample
scrapy startproject ScrapySample

Редактируем конфигурационные файлы. Сначала что собирать — файл item.py в папке webcrawl

from scrapy.item import Item, Field
class ScrapySample(Item):
    title = Field()
    link = Field() 
    content = Field() 
    pass

Теперь сам паук. В папкe ScrapySample/spiders создаем ScrapySpider.py

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from scrapy.http.request import Request
from scrapy_sample.items import ScrapySampleItem

class ScrapyOrgSpider(BaseSpider):
    name = "scrapy"
    allowed_domains = ["scrapy.org"]
    start_urls = ["http://blog.scrapy.org/"]

    def parse(self, response):
        hxs = HtmlXPathSelector(response)

        next_page = hxs.select("//div[@class='pagination']/a[@class='next_page']/@href").extract()
        if next_page:
            yield Request(next_page[0], self.parse)

        posts = hxs.select("//div[@class='post']")
        items = []
        for post in posts:
            item = ScrapySampleItem()
            item["title"] = post.select("div[@class='bodytext']/h2/a/text()").extract()
            item["link"] = post.select("div[@class='bodytext']/h2/a/@href").extract()
            item["content"] = post.select("div[@class='bodytext']/p/text()").extract()
            items.append(item)
        for item in items:
            yield item
            # возвращаем генератор собранных объектов

Запускаем:

scrapy crawl ScrapySample -o ScrapySample.json -t json

(можно в csv или xml)

Thanks :

http://amaral.northwestern.edu/blogs/2013/apr/8/quick-introduction-web-crawling-using-scrapy-part-/

https://github.com/milinda/Scrapy-Sample/blob/0a8ffba73f5f31b2a37d87530ceb341e7302182d/scrapy_sample/spiders/ScrapySpider.py

dataset — еще одна обертка баз данных для ленивых

 import dataset
db = dataset.connect('sqlite:///:memory:')

table = db['sometable']
table.insert(dict(name='John Doe', age=37))
table.insert(dict(name='Jane Doe', age=34, gender='female'))

john = table.find_one(name='John Doe')

# Внимание, теперь самое вкусное!
# Запросы: 
table = db['users'].table
statement = table.select(table.c.name.like('%Snoopy%'))
result = db.query(statement)

# Сохраняем в json/csv всех
result = db['users'].all()
dataset.freeze(result, 'users.json', format='json')

# Или каждого пользователя в свой файл
# export one JSON file per user
dataset.freeze(result, 'users/{{ id }}.json', format='json', mode='item')

via https://dataset.readthedocs.org/en/latest/

Быстрая база данных с gluon.sql

from gluon.sql import DAL, Field

# Подключаемся. В наличии полтора десятка драйверов - MySQL, PostgreSQL, MongoDB and more...  
db=DAL('sqlite://database.db')

# Создаем таблицу (если ее нет). Мигрируем (если она изменилась), просто открываем (если она не изменилась)
db.define_table('taskList',Field('title'),Field('done','boolean')) 

# Добавляем данные
db['taskList'].insert(title='Beat old sql interfaces',done=False)
db.taskList.insert(title='Beat old sql interfaces',done=False)

# Делаем запрос
for task in db(db.taskList.done==True).select():
     print task.title

Via http://stackoverflow.com/a/2976972

Disclaimer: web2py required

Официальная документация: http://www.web2py.com/book/default/chapter/06

ConfigParser

Очень удобная библиотека для чтения конфигурационной информации из Windows-like .ini файлов.

simple.ini

[bug_tracker]
url = http://localhost:8080/bugs/
username = dhellmann
password = SECRET

configtest.py

from ConfigParser import SafeConfigParser
parser = SafeConfigParser()
parser.read('simple.ini')

print parser.get('bug_tracker', 'url')

via http://pymotw.com/2/ConfigParser/

virtualenv

Пожалуй, эту вещь надо поставить сразу. Virtualenv позволяет устанавливать сторонние пакеты точечно, для тех проектов, в которых они используются.

pip install virtualenv

# создаем папку project со своими site-packages 
virtualenv --no-site-packages project

cd project

# активируем virtualenv
source bin/activate

# смотрим какие пакеты установлены
yolk -l

# устанавливаем новые 
pip install package

# выходим из виртуальной среды
deactivate

Via http://simononsoftware.com/virtualenv-tutorial/

Быстрая установка web2py

web2py — замечательный питоновский веб-фрэймворк с кучей интересных батареек.

Оказывается, есть отличная утилита, которая устанавливает всю связку apache+python+mod_wsgi+web2py+postgresql (пример для Ubuntu)

wget http://web2py.googlecode.com/hg/scripts/setup-web2py-ubuntu.sh
chmod +x setup-web2py-ubuntu.sh
sudo ./setup-web2py-ubuntu.sh

Отсюда : http://web2py.com/book/default/chapter/13

UPDATE: а можно даже и с nginx/uwsgi  https://web2py.googlecode.com/hg/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh

Строим n-grams

Как получить список n-грамм в четыре строки*

n = 3
with open('/path/to/file') as my_file:
    words = my_file.read().split()
ngrams = zip(*[words[i:] for i in range(n)])

* хорошо бы еще нормализовать регистры, морфологию и пунктуацию до этого

via http://www.quora.com/Python-programming-language-1/What-are-some-cool-Python-tricks#

import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one— and preferably only one —obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!