Python ftplibでファイルをFTP GETする

最近お目にかからなくなってきたFTPサーバから、データをGETするスクリプトを組んでたのでメモ。
ftplibを使って、指定ディレクトリからデータをGETする簡単なサンプルコードです。
gzファイル取りたかったのでバイナリモードにしてますが、ASCIIモードの場合はretrlines()で。
下記サンプルコードではファイル名固定ですが、「あるディレクトリ配下のすべてのファイルをGET」とかする場合は、nlst()が便利だと思う。

ftp_srv.cwd(archive_path)
for getfile in ftp_srv.nlst():
    ...
    ...

NLSTの結果をリストオブジェクトで返してくれるので操作しやすい。

# coding=utf-8
import os
import ftplib
from ftplib import FTP
if __name__ == '__main__':
    archive_path = 'archive/20130619'
    filename = 'service.log.gz'
    try:
        ftp_srv = FTP('FTPサーバ', 'ユーザー名', 'パスワード') #FTPサーバへ接続
        ftp_srv.cwd(archive_path) # カレントディレクトリの指定(archive_pathがカレントになる)
        file_path = '/'.join([archive_path, filename])
        if not os.path.isfile(file_path):
            # バイナリモードでファイルを開く
            with open(file_path, 'wb') as f:
                ftp_srv.retrbinary('RETR '+filename, f.write) # バイナリモードでファイルを受信
        ftp_srv.quit()
    except ftplib.all_errors, e:
        print '%s' % e

pythonからだと意外とFTPは扱いづらいというか、プリミティブな感じがしました。
SCPとかSFTPならparamikoやFabric使えば良いっぽいし、ftplibは今後使うことあるのかどうか・・・。

Python Fabricで複数台のNginxのキャッシュクリアをする小ネタ

前回にNginxのキャッシュについて書いたので、今回は複数台のNginxキャッシュクリアをするコードスニペット的なのを書いてみます。
自動実行でも良いのですが、今回は手動でコマンドを叩いて消します。
キャッシュクリアに使うのはPython Fabricです。
Fabricを使えば、簡単に複数サーバでキャッシュクリアを実行出来るので本当に便利ですね。

# -*- coding: utf-8 -*-
from fabric.api import env, run, roles, cd, sudo
from fabric.contrib import console
def nginx():
        env.roledefs.update({'nginx':['192.168.0.1','192.168.0.2','192.168.0.3']})
@roles('nginx')
def cache_clear():
    with cd('/var/cache/nginx'):
       sudo('ls -la')
       if console.confirm('Do you really want to delete the cache?', default=True):
           sudo('rm -rf ./*')

そして以下のコマンドで実行します。

$ fab nginx cache_clear

結局やってるのは「sudo rm -rf ./*」なのですが、間違うとかなり危険なので一応、一覧参照と確認を入れてます。
たったこれだけで複数台のサーバで、横断的にキャッシュクリアできるのは良いですね。

Python botoにAWSのアクセスキーIDとシークレットキーを予め設定しておく小ネタ メモ

最近知ったbotoの小ネタ。
botoを使っていると、毎回AWSのアクセスキーIDとシークレットキーをベタに書いていたのですが、/etc/boto.cfgに書いておけば以下の書き方が出来るというお話

import boto.ec2
region = 'ap-northeast-1'
conn = boto.ec2.connect_to_region(region)

設定ファイルはこんな感じに成ります。

/etc/boto.cfg
[Credentials]
aws_access_key_id=アクセスキーID
aws_secret_access_key=シークレットキー
# 複数切り替える場合は、予め書いておいてコメントアウトしておくと便利
# aws_access_key_id=アクセスキーID2
# aws_access_key_id=シークレットキー2

バッチサーバー等で複数のスクリプト実行してる場合便利ですね。

Python Fabricでデプロイしてみた

最近デプロイツールを探していたのだけど、やはりPythonで書きたいなと思い、勉強がてらFabricを使ってデプロイスクリプトを書いてみました。
設定とコードをなるべく切り分けたかったので、このあいだ知ったConfigParser使って設定を外部化させてみました。
Fabricのrolesを使いたかったので、Keyに対して、カンマ区切りで複数のValueを持たせられるようにしてみました。とりあえず動く程度なのでも
う少し綺麗にまとめるかも、っというかもっとスマートな方法があるはず・・・。

Pythonで設定ファイルを読み込みたい場合の方法 ConfigParser

Pythonでコードを書いていると設定する項目が増えてきていろいろと大変・・・。
別のファイルにまとめられないかなと思ったら、ConfigParserなる便利なモジュールがあったので使ってみました。
テストで使用した設定ファイルの内容は以下のものとなります。
FileName:config_file

[options]
spam: egg
hoge: huga
[example]
host=192.168.1.10
port=22
user=iiwake

[]で括られているのが各セクションとなり、それ以下がオプションとなります。
オプションは、左がKeyで右がValueとなっており、「:(コロン)」「=(イコール)」が使用出来るようです。
では実際に読み込んでみます。
read()にて、用意した設定ファイルを指定し読み込みます。

>>> import ConfigParser
>>> conf = ConfigParser.SafeConfigParser()
>>> conf.read('config_file')

get(‘セクション名’, ‘オプション名’)で値を取り出せます。

>>> conf.get('options', 'spam')
'egg'

sections()で各セクション名が返されます。また、options(‘セクション名’)でセクション内の各オプションを返します。

>>> for section in conf.sections():
...     for option in conf.options(section):
...         print '[section: %s] option: %s' % (section, conf.get(section, option))
...
[section: options] option: egg
[section: options] option: huga
[section: example] option: 192.168.1.10
[section: example] option: 22
[section: example] option: iiwake

items(‘セクション名’)はオプション名を指定せず(key, value)のペアで取り出せます。

>>> for section in conf.sections():
...     print 'section: %s, option: %s' % (section, conf.items(section))
...
section: options, option: [('spam', 'egg'), ('hoge', 'huga')]
section: example, option: [('host', '192.168.1.10'), ('port', '22'), ('user', 'iiwake')]

has_option()を使えば、オプションの有無がわかります。

>>> for section in conf.sections():
...     if conf.has_option(section, 'spam'):
...         print conf.get(section, 'spam')
...
egg

意外と簡単に設定の外部化ができました。
ただ、値を複数持つオプション等が出来ないようなので(そこまで調べてませんが)そう言った事をする場合、自前で解析しなくてはならないかも。
 

PythonでDaemon化をする メモ

pythonかphpで、スクリプトをデーモン化できないかなぁと思ったら、pythonで案外簡単に出来そうだったのでメモ
モジュールのインストール

pip install python-daemon

実際のコード

# -*- coding: utf-8 -*-
from daemon import DaemonContext
from lockfile.pidlockfile import PIDLockFile
dc = DaemonContext(
pidfile=PIDLockFile(‘/tmp/daemon.pid’),
stderr=open(‘err_console.txt’, ‘w+’)
)
def run():
while True:
# 何やらの処理
with dc:
run()

以上
ね、簡単でしょ。