Архив метки: 2.x

2.x/stdlib — parser. Документация

parser — Доступ к распарсенным деревьям Python

Модуль parser предоставляет интерфейс для внутреннего парсера Python и компилятора байт-кода. Основная цель этого интерфейса — позволить коду на Python редактировать дерево выражений Python и создавать из него выполняемый код. Это лучше чем пытаться разобрать и модифицировать произвольный фрагмент кода на Python because parsing is performed in a manner identical to the code forming the application. Кроме того, это быстрее.
Note

 

Начиная с 2.5, более удобно влезть в этапы генерации Abstract Syntax Tree (AST) и компиляции, при помощи подуля ast.
Модуль parser экспортирует имена, документированные тут, заменяя “st” на “ast”; это наследие ещё тех времён, когда не было другого AST и никак не связано с AST из Python 2.5. Кроме того, это ещё и причина того, что именованные аргументы функций называются ast, а не st. Функции “ast” убраны в Python 3.
Есть несколько вещей, которые надо иметь ввиду при работе с этим модулем. Данная документация не является руководством по редактированию распарсенного дерева кода Python, но некоторые примеры использования модуля parser Вы тут встретите.
Особенно важно хорошее понимание обработки грамматики Python внутренним парсером. Более подробная информация о синтаксисе языка находится в The Python Language Reference. Сам парсер создаётся из грамматических спецификаций, определённых в файлеGrammar/Grammar в стандартной постановке Python. Распарсенные деревья сохранённые в объектах ST, создаваемых этим модулем, являются актуальным выводом внутреннего парсера, когда они создаются функциями expr() или suite(), описанными ниже. Объекты ST создаваемые функцией sequence2st() имеют схожую структуру. Имейте ввиду, что значения последовательностей, которые “корректны” могут отличаться для разных версий Python, если отличается формальная грамматика языка. Однако, перенос кода из одной версии Python в другую всегда будет создавать корректное распарсенное дерево для данной
версии, с тем лишь ограничением, что переход на более старую версию не будет поддерживать более новые конструкции языка. Распарсенные деревья, обычно, не совместимы меду разными версиями, тогда как для исходного кода гарантируется forward-compatible.
Каждый элемент последовательности, возвращаемый функциями st2list() или st2tuple() имеет простую форму. Последоватльность, представляющая нетерминальные элементы грамматики всегда имеет длину больше одного. Первый элементом является число, которое идентифицирует выражение грамматики. Эти числа имеют символические имена, определённые в заголовочном файле CInclude/graminit.h и в модуле Python symbol. Каждый дополнительные элемент последовательности представляет компонент выражения, который был распознан в исходной строке: они всегда являются последовательносями той же формы, что и родительская последовательность. Важный аспект этой структуры, который надо иметь ввиду, что ключевые слова, используемые для идентификации типа родительского узла, такое как if в if_stmt, включается в узел дерева без дополнительной трактовки. Например, ключевое слово if представляется кортежем (1, 'if'), где 1 — числовое значение, ассоциированное с токеном NAME, который также включает переменные и функции, определённые пользователем. В альтернативной возвращаемой форме, когда требуется информация о номере строки, тот же самый токен может быть представлен как (1, 'if', 12), где 12 — номер строки, в которой был найден терминальный символ.
Терминальные элементы представляются похожим образом, но без дочерних элементов и без дополнений в виде исходного кода, который был идентифицирован. Опять же смотрите выше пример для ключевого слова if. Различные типы терминальных символов определены в заголовочном файле C Include/token.h и модуле Python token.
Объекты ST не требуются для поддержки функциональности этого модуля, но они используются для трёх целей: чтобы позволить приложению снизить стоимость обработки сложных распарсенных деревьев, чтобы предоставить представление распарсенного дерева, которое потребляет меньше памяти, чем представление при помощи списков или кортежей, и для того, чтобы проще сождавать дополнительные модули на С, которые манипулируют этими деревьями. Простой класс обёртка может быть создан в Python для того, чтобы скрыть использ

Скачивание файла с Google Docs и преобразование ods в csv

Возникла передо мной такая задача: мы храним таблицу соответсвия мака, ip и имени ПК в гуглодоксе, она и поддерживается в актуальном состоянии. DHCP сервер работает на FreeBSD, соответственно файл с настройками сервера вполне себе текстовый. И чтобы не обновлять данные и там и там был сделан скриптик. Наверняка можно было бы сделать проще, в некоторых случаях даже понятно как (например в функции csv2dhcp), но для небольшой таблицы я заморачиваться не стал.
Для работы понадобится pyquery и второй питон (считаем, что это у Вас уже есть). Кроме того, нам нужна библиотека для доступа к Google API.

Итак, по порядку:
  1. Заходим на страницу
  2. Выбираем Drive API и Python/Command Line
  3. Нажимаем на Настроить проект
  4. Вводим имя проекта, Далее
  5. По двум появившимся ссылкам скачиваем starter application и client secret, которым заменяем такой же файл в распакованном архиве
  6. Редактируем файл sample.py
Ниже будет код. Функцию csv2dhcp писал сам, ods2csv взял отсюда, остальное из документации по Google API. Немножно моих комментариев в коде.
Если будут комментарии/улучшения — буду благодарен

# -*- coding: utf-8 -*-
#
# Copyright (C) 2012 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the «License»);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an «AS IS» BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

«»»Command-line skeleton application for Drive API.
Usage:
  $ python sample.py

You can also get help on all the command-line flags the program understands
by running:

  $ python sample.py —help

To get detailed log output run:

  $ python sample.py —logging_level=DEBUG
 
Для работы надо поставить gdata:
 
  #$ pip install gdata
  $ pip install pyquery
 
Подключение API:

  https://developers.google.com/drive/quickstart-python
«»»

import gflags
import httplib2
import logging
import os
import sys

from apiclient.discovery import build
from oauth2client.file import Storage
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import flow_from_clientsecrets
from oauth2client.tools import run
from apiclient import errors

FLAGS = gflags.FLAGS

# CLIENT_SECRETS, name of a file containing the OAuth 2.0 information for this
# application, including client_id and client_secret.
# You can see the Client ID and Client secret on the API Access tab on the
# Google APIs Console
CLIENT_SECRETS = 'client_secrets.json'

# Helpful message to display if the CLIENT_SECRETS file is missing.
MISSING_CLIENT_SECRETS_MESSAGE = «»»
WARNING: Please configure OAuth 2.0

To make this sample run you will need to download the client_secrets.json file
and save it at:

   %s

«»» % os.path.join(os.path.dirname(__file__), CLIENT_SECRETS)
# Временные файлы, куда сохраняется скачаный файл и конвертированый в csv
TEMP_FILE = '/home/ishayahu/IP range.ods'
TEMP_FILE2 = '/home/ishayahu/IP range.csv'
# Имя итогового файла
dhcp_file_name = '/home/ishayahu/dhcp'
# Set up a Flow object to be used for authentication.
# Add one or more of the following scopes. PLEASE ONLY ADD THE SCOPES YOU
# NEED. For more information on using scopes please see
# .
FLOW = flow_from_clientsecrets(CLIENT_SECRETS,
    scope=[
      'https://www.googleapis.com/auth/drive',
      'https://www.googleapis.com/auth/drive.apps.readonly',
      'https://www.googleapis.com/auth/drive.metadata.readonly',
      'https://www.googleapis.com/auth/drive.file',
      'https://www.googleapis.com/auth/drive.scripts',
      'https://www.googleapis.com/auth/drive.readonly',
    ],
    message=MISSING_CLIENT_SECRETS_MESSAGE)

# The gflags module makes defining command-line options easy for
# applications. Run this program with the '—help' argument to see
# all the flags that it understands.
gflags.DEFINE_enum('logging_level', 'ERROR',
    ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
    'Set the level of logging detail.')

def retrieve_all_files(service):
  «»»Retrieve a list of File resources.

  Args:
    service: Drive API service instance.
  Returns:
    List of File resources.
  «»»
  result = []
  page_token = None
  while True:
    try:
      param = {}
      if page_token:
        param['pageToken'] = page_token
      files = service.files().list(**param).execute()

      result.extend(files['items'])
      page_token = files.get('nextPageToken')
      if not page_token:
        break
    except errors.HttpError, error:
      print 'An error occurred: %s' % error
      break
  return result

def download_file(service, drive_file):
  «»»Download a file's content.

  Args:
    service: Drive API service instance.
    drive_file: Drive File instance.

  Returns:
    File's content if successful, None otherwise.
  «»»
  #download_url = drive_file.get('downloadUrl&#
39;)
  # Так как файл в родом формате для гугла, то скачать его нельзя и
  # downloadUrl просто отсутствует. Поэтому используем ссылки для экспорта
  download_url = drive_file[u'exportLinks'][u'application/x-vnd.oasis.opendocument.spreadsheet']
  if download_url:
    resp, content = service._http.request(download_url)
    if resp.status == 200:
      #print 'Status: %s' % resp
      return content
    else:
      print 'An error occurred: %s' % resp
      return None
  else:
    # The file doesn't have any content stored on Drive.
    return None

def ods2csv(filepath): 
  # комментарии тут: http://python-example.blogspot.ru/2012/10/how-to-convert-ods-to-csv.html
  import sys,zipfile,re,os,csv 
  from pyquery import PyQuery as pq 
  from lxml.cssselect import CSSSelector 
     
  xml = zipfile.ZipFile(filepath).read('content.xml') 
   
  def rep_repl(match): 
    return '%s' %match.group(2) * int(match.group(1)) 
  def repl_empt(match): 
    n = int(match.group(1)) 
    pat = '
    return pat*n if (n<100) else pat 
     
  p_repl = re.compile(r']*?repeated=»(d+)[^/>]*>(.+?table-cell>)') 
  p_empt = re.compile(r']*?repeated=»(d+)[^>]*>') 
  xml = re.sub(p_repl, rep_repl, xml) 
  xml = re.sub(p_empt, repl_empt, xml) 
     
  d = pq(xml, parser='xml') 
  ns={'table': 'urn:oasis:names:tc:opendocument:pen(''.join([root,'.csv']),'wb') as f: 
    for row in data: 
      dw = csv.writer(f) 
      dw.writerow(row) 
     
def csv2dhcp(filepath):
  dhcp_file=open(dhcp_file_name,'w')
  for line in open(filepath,'r'):
    if len(line.strip().split(','))>=6 and line.strip().split(',')[2]:
      dhcp_file.write(«host %s { hardware ethernet %s; fixed-address 192.168.1.%s; }n» % (line.strip().split(',')[5],line.strip().split(',')[2],line.strip().split(',')[1]))
  dhcp_file.close()
   
def main(argv):
  # Let the gflags module process the command-line arguments
  try:
    argv = FLAGS(argv)
  except gflags.FlagsError, e:
    print '%s\nUsage: %s ARGS\n%s' % (e, argv[0], FLAGS)
    sys.exit(1)

  # Set the logging according to the command-line flag
  logging.getLogger().setLevel(getattr(logging, FLAGS.logging_level))

  # If the Credentials don't exist or are invalid, run through the native
  # client flow. The Storage object will ensure that if successful the good
  # Credentials will get written back to a file.
  storage = Storage('sample.dat')
  credentials = storage.get()

  if credentials is None or credentials.invalid:
    credentials = run(FLOW, storage)

  # Create an httplib2.Http object to handle our HTTP requests and authorize it
  # with our good Credentials.
  http = httplib2.Http()
  http = credentials.authorize(http)

  service = build('drive', 'v2', http=http)

  try:
    print «Login success! Starting to work.»
    for entry in retrieve_all_files(service):
    # Пролистываем список всех файлов (как ещё получить нужный не знаю)
    # IP range — имя нужного мне файла
    if entry[u'title']=='IP range':
        print «Writing content to %s» % TEMP_FILE
        open(TEMP_FILE,'w').write(download_file(service, entry))
        print «Converting ods to csv»
        ods2csv(TEMP_FILE)
        csv2dhcp(TEMP_FILE2)
        os.remove(TEMP_FILE)
        os.remove(TEMP_FILE2)
    # For more information on the Drive API API you can visit:
    #
    #   https://developers.google.com/drive/
    #
    # For more information on the Drive API API python library surface you
    # can visit:
    #
    #   https://google-api-client-libraries.appspot.com/documentation/drive/v2/python/latest/
    #
    # For information on the Python Client Library visit:
    #
    #   https://developers.google.com/api-client-library/python/start/get_started

  except AccessTokenRefreshError:
    print («The credentials have been revoked or expired, please re-run»
      «the application to re-authorize»)

if __name__ == '__main__':
  main(sys.argv)

Автор: Ishayahu Lastov

Запуск MoinMoin2.0 под Apache22 на FreeBSD9

Предполагается, что moin2 расположен в /home/ishayahu/moin-2.0
Для начала нам надо установить сам апач и mod_wsgi, чтобы он мог работать с Flask (я использую для этого portmaster (/usr/ports/ports-mgmt/portmaster)):
#portmaster www/apache22 www/mod_wsgi
Далее создаём файл moin-2.0/moinmoin2.wsgi, чтобы апач мог запускать Flask приложение:
#для работы mod_wsgi, так как он блокирует sys.stdout
import sys
sys.stdout=sys.stderr
# Собственно для Flask
from MoinMoin.app import create_app
application = create_app('/home/ishayahu/moin-2.0/wikiconfig.py')

Теперь будем настроивать апач. Создадим конфигурацию виртульного хоста: файл /usr/local/etc/apache22/Includes/wiki.local.conf

    ServerAdmin meoc-it@mail.ru
    DocumentRoot /home/ishayahu/moin-2.0
    ServerName wiki.local
    ServerAlias www.wiki.local
    ErrorLog /home/ishayahu/wiki.local-error_log
    CustomLog /home/ishayahu/wiki.local-access_log combined
    WSGIDaemonProcess moinmoin2 user=ishayahu group=ishayahu threads=5
    WSGIScriptAlias / /home/ishayahu/moin-2.0/moinmoin2.wsgi
   
        WSGIProcessGroup moinmoin2
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
   
Настроиваем запуск вики как сервиса. Создаём файл для запуска апача в виртуальном окружении (нужно виртуальное окнужение для работы moin; не забыть chmod +x /root/start_wiki) /root/start_wiki:
#!/bin/bash
source /home/ishayahu/moin-2.0/env/bin/activate
/usr/local/etc/rc.d/apache22 onestart
Создаём файл для регистрации вики как сервиса /etc/rc.d/wiki (не забыть chmod +x /etc/rc.d/wiki):
#!/bin/sh
#
# PROVIDE: wiki
# REQUIRE: LOGIN
# KEYWORD: shutdown

. /etc/rc.subr

name=»wiki»
start_cmd=»${name}_start»
stop_cmd=»/usr/local/etc/rc.d/apache22 stop»

wiki_start()
{
    /bin/bash /root/start_wiki
}

load_rc_config $name
run_rc_command «$1»
И в /etc/rc.conf:
wiki_enable=»YES»

Автор: Ishayahu Lastov

Продвинутое руководство по логированию (Перевод)

Библиотека logging использует модульный подход и предлагает несколько категорий компонентов: loggers, handlers, filters, и formatters.
  • Logger представляет интерфейс, который использует непосредственно код приложения.
  • Handler посылает запись лога (созданную logger'ом) в соответствующее расположение.
  • Filter позволяет определить, какую запись лога выводить.
  • Formatter определяет расположение записи лога в итоговом выводе.
Информация логирования передаётся между logger, handler, filter и formatter в экземпляре LogRecord.
Логирование осуществляется вызовом методов экземпляра класса Logger (тут и далее он будет называться loggers). Каждый экземпляр имеет своё имя и эти имена располагаются в иерархии пространства имён, используя точки в качестве разделителей. Например, logger с именем ‘scan’ является родительским logger'ом для logger'ов ‘scan.text’, ‘scan.html’ и ‘scan.pdf’. Имена logger'ов могут быть любыми, как Вы хотите, и отображают место, где было создано сообщение лога.
Общепринято использовать  для имён logger'ов имена модулей:
logger = logging.getLogger(__name__)
В таком случае имя logger'a соответствует иерархии пакетов/модулей и интуитивно становится понято, где именно события логируются уже из имени logger'a.
Корень иерархии logger'ов называется root logger. Этот тот logger, который используется функциями debug(), info(), warning(), error() и critical(), которые просто вызывают одноимённые меоды root logger'a. Функции и методы имеют одну и ту же подпись. Имя root logger’а отображается как ‘root’ в выводе логов.
Конечно же возможно логировать сообщения в разные места. Вы можете записывать сообщения в файлы, передавать по HTTP GET/POST, email'y через SMTP, сокеты или OS-специфичные механизмы логирования, такие как syslog или Windows NT event log. Место, куда отправляются логи, определяется классами handler. Вы можете создать свой собственный класс направления логов, если у Вас есть какие-то свои особые потребности.
По умолчанию место направления не задано для сообщение логов. Вы можете определить его при помощи basicConfig(), как в примерах руководства. Если Вы вызываете функции debug(), info(), warning(), error() и critical(), они будут проверять, задано ли это место, и если оно не задано, то вывод направляется в консколь (sys.stderr) и используется формат отображения сообщений по умолчанию.
Формат отображения, задаваемый по умолчанию в basicConfig() для сообщений:
severity:logger name:message
Вы можете изменить его передав строку формата в basicConfig(
)
в аргументе format. Более подробно все опции форматирования описаны в Formatter Objects.

Поток форматирования

иллюстрация тут

Перемещение информации лога между logger'ами и handler'ами иллюстрирован диаграммой по ссылке выше.

Logger'ы

Объекты Logger имеют тройную работу. Во-первых, они предоставляют методы коду приложения, так что приложение может в процессе выполнения логировать сообщения. Во-вторых, объекты logger определяют какие сообщения логов будут работать на этом уровне (объекте фильтра). В третих, объекты logger передают подходящие сообщения логов всем заинтересованным handler'ам.
Чаще всего используемые методы объекта logger относятся к одной из двух категорий: настройка и отправка сообщений.
Вот наиболее часто использемые методы настройки:

  • Logger.setLevel() определяет минимальный уровень сообщений, которые будут обработаны; debug — минимальный встроенный уровень, а critical — максимальный. Например, если установлен уровень INFO, logger будет обрабатывать сообщения уровня INFO, WARNING, ERROR и CRITICAL и игнорировать сообщения уровня DEBUG.
  • Logger.addHandler() и Logger.removeHandler() добавляют и удаляют объекты handler из объекта logger. Handler'ы более подробно обсуждены в Handlers.
  • Logger.addFilter() и Logger.removeFilter() добавляют и удалют объекты filter из объекта logger. Filter'ы более подробно обсуждаются в Filter Objects.

Вам не нужно вызывать эти методы каждый раз для каждого logger, который Вы создаёте. Смотрите последние два абазца этого раздела.
Когда объект logger настроен, следующие методы создают сообщения логов:

  • Logger.debug(), Logger.info(), Logger.warning(), Logger.error() и Logger.critical() создают записи логов с сообщением и уровнем, соответствующим названию метода. Сообщение — это строка формата, которая может содержать стандартный синтаксис подстановки, такой как %s, %d, %f. Остальные аргументы — список объектов, которые должны быть подставлены в поля подстановки сообщения. В соответствии с **kwargs, методы логирования учитывают только именованый аргумент exc_info и использует его для того, чтобы определить, логировать ли информацию об исключении.
  • Logger.exception() создаёт запись в логе, аналогичную методу Logger.error(). Разница в том, что Logger.exception() делает дамп трасировки стека при вызове. Вызывайте этот метод только из обработчика исключений.
  • Logger.log() принимает уровень логирования в качестве аргумента. В этом случае приходится больше печатать, но зато это способ залогировать события пользовательского уровня.

getLogger() возвращает ссылку на экземпляр logger'а с именем, если оно задано, или root, если нет. Имена представляют из себя иерархическую структуру с точками в качестве разделителей. Множественные вызовы getLogger() с одним и тем же имененм будут возвращать ссылку на один и тот же объект logger'а. Logger'ы, находящиеся ниже в иерархии являются дочерними для logger'ов, которые находятся выше. Например, для logger'а с имененм foo logger'ы с именами foo.bar, foo.bar.baz и foo.bam будут дочерними.
Logger'ы поддерживают концепцию эффективного уровня. Если для logger'а не задан уровень явно, то используется уровень его родителя. Если и его родитель не имеет заданного уровня — смотрится родитель родителя, и так далее. Корневой logger всегда имеет явно заданный уровень (по умолчанию это WARNING). При решении вопроса обрабатывать ли событи используется именно эффективный уровень.
Дочерние logger'ы распространяют сообщения handler'ам, связанным с родительским logger'ом. Из-за этого нет необходимости определять и настраивать handler'ы для всех logger'ов в приложении. Но важно сконфигурировать handler'ы для logger'ов верхнего уровня и уже потом создавать при необходимости дочерние logger'ы. (Однако, распространение сообщений можно отключить, задав значением атрибута propagate logger'a равным False.)

Handler'ы

Объекты Handler отвечают за отправку соответствующего сообщения (соответствующего уровня) к его месту назначения, определённого в handler'e. Объекты logger могут добавить себе ноль или более handler'ов при помощи метода addHandler(). Например, приложение может хотеть отправлять все сообщения в файл логов, сообщения уровня ошибки и выше в stdout, а все критические сообщения отправлять на почту. Этот сценарий требует три handler'a, каждый из которых отвечает за отправку сообщений определённого уровня в определённое место.
Стандартная библиотека включает в себя несколько типов handler'ов (см Useful Handlers); это руководство по большей части использует в примерах StreamHandler и FileHandler.
Есть несколько методов у handler'a для разработчиков приложений, о которых стоит позаботиться. Методы, которые нужны тем, кто будет пользоваться встроенными handler'ами (то есть, не будет использовать самописные) следующие:

  • Метод Handler.setLevel() аналогичен методу объекта logger, он определяет минимальный уровень, который будет направлен в соответствующее место. Зачем нужно два метода setLevel()? Уровень, заданный в logger'e определяет уровень сообщений, который будет передан в handler'ы. Уровень, заданный в каждом handler'e определяет сообщения, которые этот handler будут посылать.
  • setFormatter() определяет объект Formatter, который будет использовать этот handler.
  • addFilter() и removeFilter() соответственно добавляют и удаляют объекты фильтров из handler'a.

Код приложения не должен напрямую инициализировать и использовать экземпляры Handler. Вместо этого, класс Handler является базовым классом, который определяет интерфейс, которым должны обладать все handler'ы и определяет некоторое поведение по умолчанию, которое могут использовать дочерние классы (или переопределять их).

Formatter'ы

Fabric: Операции

Операции — функции, которые используются в fabfile и в другом «не ядерном» коде, таком как run()/sudo().

fabric.operations.get(remote_path, local_path = None)

Скачивает один или более файлов с удалённого узла.

get возвращает итерируемый объект, содержащий абсолютные пути ко всем загруженным файлам, который будет пустым, если local_path будет объектом StringIO (ниже мы познакомимся со StringIO более подробно). Этот объект так же выставляет атрибут .failed, содержащий все удалённые пути, загрузка с которых не удалась, и .succeeded, эквивалентный not .failed.
remote_path — это удалённый файл или каталог для загрузки, который может использовать синтаксис подстановки оболочки, например, /var/log/apache2/*.log, и тильды будут замещены на удалённую домашнюю директорию. Относительные пути будут рассматриваться относительно домашнего каталога удалённого пользователя или текущего рабочего каталога, если используются в команде cd. Если удалённый genm указывает на каталог, то он будет рекурсивно скачан.
local_path — локальный путь, куда будут загружены файлы. Если путь относительный, он будет трактоваться относительно текущей рабочей директории. Он может быть построен при помощи стандартной вставки на основании словарей со следующими переменными:
  • host: Значение env.host_string, например, myhostname или user@myhostname-222 (двоеточие между именем узла и номером порта заменено на тире для увеличения совместимости с разными ФС)
  • dirname: Часть каталога из удалённого пути, т.е. src/projectname в /src/projectname/utils.py
  • basename: Часть файла из удалённого пути, т.е. utils.py в /src/projectname/utils.py 
  • path: Полный удалённый путь: /src/projectname/utils.py 
Примечание
Если remote_path — абсолютный путь, то только подкаталоги будут созданы локально и переданы в  переменные выше. Так, например, get('/var/log', '%(path)s') будет записывать файлы как apache2/access.log,postgresql/8.4/postgresql.log и т.д. в локальный рабочий каталог. Он не будет записывать файлы как var/log/apache2/access.log.
Кроме того, когда скачивается один файл, %(dirname)s и %(path)s не имеют особого смысла и будут, соответственно иметь пустое значение и значение, равное %(basename)s. Таким образом, вызов вроде get('/var/log/apache2/access.log', '%(path)s') сохранит локальный файл под именем access.log, а не var/log/apache2/access.log.
Такое поведение предназначено для соответствия программе командной строки scp.
Если значение не задано, то local_path получает значение "%(host)s/%(path)s" чтобы это было безопасно для использования на нескольких узлах.
Предупреждение
Если ваш аргумент local_path не содержит %(host)s и ваш вызов get запускается на нескольких хостах, ваши локальные файлы будут перезаписаны при каждом удачном запуске!
Если local_path не использует вышеозначенные переменные (т.е. это просто явный путь) он будет действовать похоже командам scp или cp, перезаписывая при необходимости существующие файлы, скачивая их в нужное место (т.е. get('/path/to/remote_file.txt', 'local_directory') создаст local_directory/remote_file.txt) и т.п.
local_path может быть и файлоподобным объектом, например, результатом open('path', 'w') или экземпляром StringIO.
Примечание
Попытка выполнить get каталога в файлоподобный объект некорректна и вернёт ошибку.
Примечание
Эта функция будет использовать seek и tell для перезаписи всего содержимого файлоподобного объекта, чтобы это соответствовало поведению put (который тоже использует весь файл). Однако, в отличие от put, указатель файла не будет восстановлен в предыдущую локацию, так как это достаточно бессмыслен
но и/или даже не возможно.
Примечание
Из-за того, как работают наши слои SSH, временные файлы всё равно будут записаны во временный файл на диске, даже если Вы передаёте в качестве аргумента local_path файлоподобный объект или StringIO. Временные файлы будут удалены, но имейте это в виду и не ожидайте прямой передачи данных в память. (Мы надеемся исправить это в будущем, чтобы дать возможность прямой передачи данных в память.)
Примечание
Если файлоподбный объект, такой как StringIO имеет атрибут name, он будет использован в выводе Fabric, вместо простого  obj>
Изменения в версии 1.0: Теперь есть отдельный удалённый рабочий каталог, с которым работает cd, и локальный рабочий каталог, с которым работает lcd.
Изменения в версии 1.0: Теперь можно использовать файлоподобные объекты в качестве аргумента local_path.
Изменения в версии 1.0: local_path может теперь содержать переменные genb и узла.
Изменения в версии 1.0: В аргументе remote_path можно использовать каталоги, которые будут рекурсивно загружены.
Изменения в версии 1.0: Возвращает итерируемый объект, содержащий локальные пути, содержащий атрибуты .failed и.succeeded.
Изменения в версии 1.5: Использует атрибут name файлоподобного объекта для вывода лога
fabric.operations.local(commandcapture=Falseshell=None)
Выполняет команду на локальной системе.
local — это лишь оболочка вокруг использования встроенного модуля Python subprocess с shell=True. Если Вам надо сделать что-то особое — используйте модуль subprocess напрямую.
shell передаётся напрямую в аргумент execute subprocess.Popen‘а (что определяет используемую локально оболочку.) В соответствии со документацией, на Unix по умолчанию используется /bin/sh, так что эта опция полезна для установки других значений, например, /bin/bash.
local на данный момент не способен одновременно вводить и выводить информация, в отличие от run/sudo. Именованный аргумент capture позволяет переключаться между выводом и вводом при необходимости, значение по умолчанию — False.
Когда capture=False, локальные ввод и вывод  subprocess’a направляется напрямую на ваш терминал, хотя Вы можете использовать глобальные настройки вывода output.stdout и output.stderr, чтобы спрятать один из них или оба. В этом режиме возвращаемые значения stdout/stderr всегда будут пустыми.
Если capture=True, то Вы не увидите никакого вывода на вашем терминале, но возвращаемое значение будет храниться в stdout/stderr.
В любом случае, как и при запуске run и sudo, возвращаемое значение содержит атрибуты return_codestderrfailed и succeeded. Более подробно это описано в run.
local будет учитывать менеджер контекста lcd, позволяющий Вам контролировать текущий рабочий каталог вне зависимости от удалённого каталога (которым управляет cd).
Изменения в версии 1.0: Добавлены атрибуты succeeded и stderr.
Изменения в версии 1.0: Теперь учитывает менеджер контекста lcd.
Изменения в версии 1.0: Значение по умолчанию для capture изменено с True на False.
fabric.operations.open_shell(command=None)
Вызывает интерактивную оболочку на удалённой системе.
Если передан аргумент command, то он будет передан  по каналу перед тем, как передать управление пользователю.
Эта функция чаще всего используется когда Вам нужно взаимодействовать с серьёзными командами оболочки или набором команд, например, при отладке или когда нужно провести полностью интерактивное восстановление при ошибке  удалённой программы.
Следует иметь ввиду, что интерактивная оболочка в середине скрипта и не является замено
й команды run, которая тоже может взаимодействовать с удалённым хостом (хотя только во время выполнения переданной команды) и подразумевает решение большего количества программных проблем, таких как обработка ошибок и захват ввода/вывода.
Конкретнее, open_shell предоставляет больше интерактивности, чем run, использование полноценной удалённой оболочки не позволяет Fabric определить, завершилась ли программа с ошибкой и заполняет ввод/вывод вводом/выводом оболочки, таким как заставки входа, приглашения и т.д.
Таким образом, эта функция не имеет возвращаемого значения и не вызывает обработку ошибок Fabric, если какая-либо удалённая программа завершилась с ошибкой.
Начиная с версии 1.0.
fabric.operations.prompt(textkey=Nonedefault=''validate=None)
Выдаёт пользователю запрос с текстом text и возвращает полученное значение (как raw_input).
Для удобства к text будет добавлен одиночный пробел, ничего больше. Таким образом Вы можете завершить свой запрос вопросительным знаком или двоеточием, например prompt("What hostname?").
Если указан key, ввод пользователя и будет сохранён как env. и возвращён этой функцией prompt. Если этот ключ уже существует в env, то его значение  будет перезаписано и пользователю будет выдано предупреждение.
Если передан параметр default, то он будет выведен в квадратных скобках и будет использоваться в случае, если пользователь ничего не введёт (т.e. нажмёт Enter без ввода текста). По умолчанию значением default является пустая строка. Если значением является не пустая строка, то к нему будет добавлен пробел, так что вызов prompt("Каково имя узла?", default="foo") приведёт к отображению Каково имя узла? [foo]  (с пробелом после [foo].)
Опциональный именованный аргумент validate может быть вызываемым объектом или строкой:
  • Если это вызываемый объект, то он будет вызван с полученной от пользователя строкой и должен вернуть значение для сохранения в случае успеха. При ошибке он должен вызвать исключение с сообщением, которое будет показано пользователю.
  • Если это строка, то значение, переданное в параметре validate используется как регулярное выражение. Поэтому рекомендуется использовать «сырые» строки. Обратите внимание, что регулярное выражение будет (в любом случае?) требовать полного совпадения.
В любом случае prompt будет перезапрашивать ввод от пользователя до тех пор, пока не пройдёт валидация (или пользователь не нажмёт Ctrl-C).
Примечание
prompt учитывает env.abort_on_prompts и будет вызывать abort вместо запроса, если этот флаг установлен в True. Если Вы хотите заблокировать ввод пользователя безусловно, но в этом случае запросить информацию у пользователя — оберните код при помощи settings.
Примеры:

# Простейшая форма:


environment = prompt('Please specify target environment: ')



# Со значением по умолчанию и сохранением как env.dish:


prompt('Specify favorite dish: ', 'dish', default='spam & eggs')



# С валидацией, требуем ввод числа:


prompt('Please specify process nice level: ', key='nice', validate=int)



# С валидацией по регулярному выражению:


release = prompt('Please supply a release name',


validate=r'^w+-d+(.d+)?$')


# Запрос вне зависимости от глобальной настройки:


with settings(abort_on_prompts=False):


prompt('I seriously need an answer on this! ')

fabric.operations.put(local_path=Noneremote_path=Noneuse_sudo=Falsemirror_local_mode=Falsemode=None)
Загружает один или более файлов на удалённый хост.
put возвращает итерируемый объект, содержащий абсолютные пути ко всем загруженным файлам. Этот итерируемый объект содержит также атрибут .failed, содержащий пути к локальным файлам, которые не удалось выгрузить (и потому его можно использовать для логической проверки.) Кроме того, Вы можете использовать .succeeded, который эквивалентен not .failed.
local_path может быть как относительным, так и абсолютным путём, или даже каталогом, может содержать символы подстановки оболочки, как они используются в модуле glob. Можно использовать и ~ (так же как в os.path.expanduser).
local_path может быть и файлоподобным объектом, как, например, результатом open('path') или экземпляром StringIO.
Примечание
В таком случае put постарается прочитать всё содержимое файлоподобного объекта, проматывая его при помощи seek (и будет использовать tell для сохранения предыдущей позиции файла).
Примечание
Использование файлоподобного объекта в команде put в аргументе local_path приведёт к удалению временного файла из-за нашей реалиации слоя SSH.
remote_path также может быть абсолютным или относительным путём, но применяется к удалённому узлу. Относительный genm трактуется относительно домашней директории удалённого пользователя, но, при необходимости, можно использовать и тильду (т.е. ~/.ssh/).
Пустая строка в качестве значения любого из двух аргументов пути будет замещена на текущий рабочий каталог.
Хотя протокол SFTP (который используется put) не имеет возможности загрузить файл в локацию, которая не принадлежит подключившемуся пользователю, Вы можете задать use_sudo=True, чтобы обойти это. При использовании этого параметра put загружает файлы во временный каталог на удалённом хосте и затем использует sudo для перемещения их в remote_path.
В некоторых случаях желательно чтобы загруженные файлы имели аналогичный  режим, как и их локальные «коллеги» (например, когда Вы загружаете выполняемые скрипты). Для этого используйте mirror_local_mode=True.
В качестве альтернативы Вы можете использовать именованный аргумент mode для того, чтобы задать режим извлечения так же как и os.chmod или команда Unix chmod.
put учитывает результат cd, так что относительные пути в remote_path будут толковаться относительно текущего удалённого рабочего каталога, если это возможно. Таким образом, например, код ниже выгрузит файл в /tmp/files/test.txt а не в ~/files/test.txt:

with cd('/tmp'):


put('/path/to/local/test.txt', 'files')

Использование lcd будет влиять на local_path аналогичным образом.
Примеры:

put('bin/project.zip', '/tmp/project.zip')


put('*.py', 'cgi-bin/')


put('index.html', 'index.html', mode=0755)

Примечание
Если файлоподобный объект, такой как StringIO, имеет атрибут name, то его значение будет использоваться в выводе Fabric, вместо стандартного  obj>
Изменения в версии 1.0: Теперь учитывается удалённый рабочий каталог, управляемый cd, и локальный рабочий каталог, управляемый lcd.
Изменения в версии 1.0: Теперь можно использовать файлоподобные объекты в аргументе local_path.
Изменения в версии 1.0: В аргументе local_path можно задать каталог, который будет рекурсивно выгружен на удалённый узел.
Изменения в версии 1.0: Возвращает итерируемый объект, содержащий удалённые пути с атрибутами .failed и.succeeded.
Изменения в версии 1.5: Позволяет использовать атрибут name файлоподобного объекта для вывода лога
fabric.operations.reboot(wait=120)
Перезагружает удалённую систему.
Временно изменяет настройки переподключения (timeout и connection_attempts) чтобы убедиться, что попытки подключения не прекратятся как минимум раньше wait секунд.
Примечание
По состоянию на Fabric 1.4, способность переподключиться в пределах сессии больше не требует использования внутреннего API. Хотя мы и не объявляем эту функцию нежелательной, тем не менее добавление к ней новых возможностей не стоит у нас в приоритетах.
Пользователи, желающие получить больше возможностей должны посмотреть исходники этой функции (6 хорошо задокументированных строк) и написать свою собственную адаптацию с различными значениями timeout/attempts или дополнительной логикой.
Появился в версии 0.9.2.
Изменения в версии 1.4: Изменен именованный аргумент wait — ему добавлено значение по умолчанию.
fabric.operations.require(*keys**kwargs)
Проверяет наличие переданных ключей в общем словаре окружения и прерывает выполнение, если их не находит.
Позиционными аргументами должны быть строки, определяющие то, какие переменные окружения должны быть проверены. Если какой-либо из этих переменных не существует, Fabric прервёт выполнение и выведен имена отсутствующих ключей.
Опциональный именованный аргумент used_for может быть строкой, которая будет отправлена на стандартный вывод, чтобы сообщить пользователю, для каких целей будет использоваться отсутствующая переменная. used_for выводится как часть строки вроде этой:
"Th(is|ese) variable(s) (are|is) used for %s"
Опциональный именованный аргумент provided_by может быть списком функций или имён функций, или одной функцией или её именем, которые должны быть выполнены для того, чтобы задать эти переменные; он будет включён в сообщение об ошибке.
Примечание: Подразумевается, что именованные аргументы применяются ко всем переданным ключам как к группе. Если Вам надо, например, указать для разных ключей разные used_for, Вы должны использовать несколько вызовов require().
Изменения в версии 1.1: Позволяет использовать итерируемые значения provided_by, а не одиночные значения.
fabric.operations.run(commandshell=Truepty=Truecombine_stderr=Nonequiet=Falsewarn_only=Falsestdout=None,stderr=None)
Запускает команду оболочки на удалённом узле.
Если shell=True (значение gj умолчанию), run выполнит заданную команду через оболочку, которая определяется переменной env.shell (в сумме получается что-то вроде /bin/bash -l -c "".) Все двойные кавычки (") или знаки доллара ($) в command будут автоматически экранированы, если shell=True.
run возвращает результирующий вывод выполнения удалённой программы в качестве одной (скорее всего состоящей из нескольких строк) строки. Эта строка будет иметь логические атрибуты failed и succeeded, определяющие успешно или нет была выполнена команда, а в атрибуте return_code Вы получите код возврата команды. Более того, он содержит копии запрошенной и реальной строки команды в аргументах .command и .real_command соответственно.
Любой текст, введённый в вашем локальном терминале будет перенаправлен в удалённую программу, пока она выполняется; таким образом Вы можете взаимодействовать удалённой программой, вводя пароли и т.п. Более подробно смотрите в разделе Взаимодействие с удалённой программой.
Вы можете задать pty=False чтобы не создавать псевдотерминал на удалённом хосте в том случае, если это создаёт проблемы для выполняемой команды. Но, таким образом, Fabric надо будет самому передавать весь ввод удалённой программе, в том числе и пароли. (Если pty=True, удалённый псеводтерминал бдует делать всё это сам.) Подробнее об этом в разделе Псевдотерминалы.
Конкретнее, если Вам нужно программно проверить поток вывода ошибок удалённой программы (доступный через атрибут stderr возвращаемого значения функции), Вы можете задать combine_stderr=False. В этом случае есть большая вероятность получения путанного вывода на вашем терминале (хотя возвращаемая run строка будет разделена надлежащим образом). Более подробно смотрите в разделе Комбинирование stdout и stderr.
Чтобы игнорировать ненулевой код возвращения задайте warn_only=True. Чтобы и игнорировать ненулевое возвращаемое значение и принудить команду выполняться тихо, задайте quiet=True.
Чтобы переопределить какие локальные потоки будут использованы для отображения удалённых stdout и/ил
и stderr, определите stdout или stderr. (По умолчанию используются потоковые объекты Python sys.stdout и sys.stderr.)
Например, run("command", stderr=sys.stdout) будет выводить удалённый поток ошибок в локальный поток вывода, сохраняя его как свой собственный атрибут возвращаемого значения (как выше). Или же Вы можете даже передать свой собственный потоковый объект или логировщик, например myout = StringIO(); run("command", stdout=myout).
Примеры:

run("ls /var/www/")


run("ls /home/myuser", shell=False)


output = run('ls /var/www/site1')

Начиная с версии 1.0: Атрибуты succeeded и stderr возвращаемого значения, именованный аргумент combine_stderr, и интерактивное поведение.
Изменения в версии 1.0: Значением по умолчанию pty теперь является True.
Изменения в версии 1.0.2: Значением по умолчанию combine_stderr теперь является None вместо True. Однако поведение по умолчан