Python - 上位24パッケージの解説と使い方まとめ

`pip install`でおなじみのPyPiから人気パッケージを総合と週間ダウンロード数で上位20パッケージ抽出しました。人気24パッケージの使い方まとめです。週間と総合で重複16という結果に驚きました。ASN.1を扱うpyasn1パッケージだけは利用方法が判らなかったので誰か教えてください。

# PyPi ダウンロード数ランキング
![スクリーンショット 2015-11-20 14.16.23.png](https://qiita-image-store.s3.amazonaws.com/0/65312/588ce65e-68c9-940d-2215-82f633362f3e.png)



# 1.simplejson
jsonのエンコードとデコードを行うライブラリです。総合と週間でぶっちぎり1位のパッケージで1億件以上のDL数を誇ります。速度のみなら[ujsonの方が早い](http://blog.dataweave.in/post/87589606893/json-vs-simplejson-vs-ultrajson)です。

```py:simplejson_1.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import simplejson

# dict to json
d = {i: i**3 for i in xrange(10)}
json_str = simplejson.dumps(d)
print(type(json_str), json_str)

# json to dict
json_dict = simplejson.loads(json_str)
print(type(json_dict), json_dict)
```

```shell-session:実行結果
>>>python simplejson_1.py 
(<type 'str'>, '{"0": 0, "1": 1, "2": 8, "3": 27, "4": 64, "5": 125, "6": 216, "7": 343, "8": 512, "9": 729}')
(<type 'dict'>, {'1': 1, '0': 0, '3': 27, '2': 8, '5': 125, '4': 64, '7': 343, '6': 216, '9': 729, '8': 512})
```

# 2.setuptools
パッケージ管理ソフト。easy_installもsetuptoolsの機能の一つです。同じくパッケージを管理するpipをインストールするために最初に導入することが多いのではないでしょうか。pipをインストールするとsetuptoolsがインストールされます。distributeは2013年にsetuptoolsにマージされています。Python3.4からはPython本体にpipが含まれるようになりました。[詳細はPEP453](https://www.python.org/dev/peps/pep-0453/)。

# 3.requests
Requestsは人が使いやすいように設計されているHTTPライブラリです。HTTP GET、POST、basic認証、OAuth2.0認証を簡潔に書くことができます。

```py:requests_3.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import requests
import simplejson

# json型で応答するAPIにHTTP GETするコード
host = "api-sandbox.oanda.com"
url = "https://{}/v1/candles?instrument=EUR_USD&count=100&candleFormat=midpoint&" \
      "granularity=D&dailyAlignment=0&alignmentTimezone=America%2FNew_York".format(host)
response = requests.get(url)
# HTTP STATUSが正常であること
assert response.status_code == 200
data = simplejson.loads(response.text)
print(type(data), data)
```

```shell-session:実行結果
>>>python ./requests_3.py 
(<type 'dict'>, {u'instrument': u'EUR_USD', u'candles': [{u'complete': True, u'closeMid': 1.09102, u'highMid': 1.09347, u'lowMid': 1.084825, u'volume': 31402, u'openMid': 1.0863, u'time': u'2015-08-05T04:00:00.000000Z'}, {u'complete': True, u'closeMid': 1.09141, u'highMid': 1.0944, u'lowMid': 1.08735, u'volume': 22130, u'openMid': 1.09104, u'time': 
...
```

# 4.virtualenv
1台の端末に複数のPython環境を簡単に構築できます。私はPython2.7+Django1.5の環境、PyPy環境、Python3.5環境を切り替えて利用しています。

```py:インストール、環境構築、使い方
# install
sudo pip install virtualenv
sudo pip install virtualenvwrapper

# hoge環境構築
mkvirtualenv --python=/usr/local/bin/python3 hoge

# 環境一覧
workon

# 環境切り換え
workon hoge

# 環境から抜ける
deactivate
```

# 5.distribute
パッケージ管理ソフト。pipをインストールするとsetuptoolsがインストールされ、distributeは2013年にsetuptoolsにマージされています。そのためパッケージ管理はpipで行えば問題ないです。

# 6.six
sixはPython2系と3系の互換性ライブラリです。2系でも3系でも動作する単一コードを書くためのユーティリティ関数を提供します。

```py:six_6.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import six

# python2系環境で実行
print (six.PY2, six.PY3)


# python2系環境で3系のmetaクラスを利用する
class ABCMeta(type):
    pass


@six.add_metaclass(ABCMeta)
class MyABC(object):
    pass

abc = MyABC()
print abc

```

```py:実行結果
>>>python six_6.py 
(True, False)
<__main__.MyABC object at 0x101d02550>
```

# 7.pip
Pythonのパッケージ管理ソフトウェアです。setuptoolsやdistributeといった他のパッケージ管理ソフトもありますが、迷ったら原則 pip を使ってパッケージの管理を行うのが正解だと思います。easy_installが不評であったため開発された背景があり、Python3.4からはPython本体に含まれるようになりました。[詳細はPEP453](https://www.python.org/dev/peps/pep-0453/)

```shell-session:pip自体のインストールはget-pip.pyを利用すると楽。
curl -kL https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python
```

# 8.certifi
certifiはSSL証明書の信頼性検証を、ルート認証局(CA)を利用して精緻に検証するライブラリです。これ単体で利用するというよりも、他のライブラリが利用して依存しているため、同時にインストールされることが多いです。


```py:certifi_8.py 
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import certifi
# ルート認証局(CA)のファイル設置場所を出力
print(certifi.where())
```

```py:実行結果
>>>python ./certifi_8.py 
/xxxxx/lib/python2.7/site-packages/certifi/cacert.pem
```
# 9.boto
Amazon Web ServicesをPythonから操作するためのインターフェースです。自身の経験だとdeploy時にdeploy先のサーバ一覧をEC2インスタンスに設定したタグから引っ張ってきたり、S3にアクセスしてファイル一覧を取得したりするときに使いました。

```py:s3バケットにbotoでアクセス
import boto
from boto.s3.key import Key
import boto.s3.connection

AWS_ACCESS_KEY_ID = '<access key>'
AWS_SECRET_ACCESS_KEY = '<my secret key>'
Bucketname = 'Bucket-name' 


conn = boto.s3.connect_to_region('ap-southeast-1',
       aws_access_key_id=AWS_ACCESS_KEY_ID,
       aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
       is_secure=True,               # uncommmnt if you are not using ssl
       calling_format = boto.s3.connection.OrdinaryCallingFormat(),
       )
bucket = conn.get_bucket(Bucketname)
```

# 10.pbr
setuptoolsを一貫性を持って管理するためのライブラリです。setup.py にパッケージ情報を書かずに setup.cfg に Metadata2.0 のフォーマットでパッケージ情報を記述できます。各ライブラリのフォーマットを統一するためにsetup.cfgにはデフォルト値が記入されています。

```py:setup.py
import setuptools
from pbr import util

setuptools.setup(
    **util.cfg_to_args())
```

```py:setup.cfg
[metadata]
name = pbr
author = OpenStack
author-email = openstack-dev@lists.openstack.org
summary = Python Build Reasonableness
...
```

# 11.wincertstore
wincertstoreはWindowsのCA証明書とCRL(証明書失効リスト)にアクセスするためのインタフェースを提供します。単体で使うというより、他のパッケージをインストールすると付随してインストールされることが多いと思います。


# 12.python-dateutil
Python標準のdatetimeモジュールを拡張します。月末を算出したり、「次の◯曜日」を算出したり、「当月の最終◯曜日」を算出したりすることができます。使ったことが無かったので[python-dateutilの使い方](http://imagawa.hatenadiary.jp/entry/20111126/1322298988)を参考にして実装しました。

```python-dateutil.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from dateutil.relativedelta import relativedelta, FR
from datetime import date
import calendar

# 月末を計算 ちゃんと11月30日を返却
print "月末計算:", date(2015, 11, 26) + relativedelta(day=31)

# 次の火曜日を返却
print "次の火曜日:", date(2015, 11, 28) + relativedelta(weekday=calendar.TUESDAY)

# 当月の最終金曜日
first_day = date(2015, 11, 1)
rdl = relativedelta(day=31, weekday=FR(-1))
print "当月の最終金曜日:", first_day + rdl

```

```py:実行結果
>>>python ./python-dateutil.py 
月末計算: 2015-11-30
次の火曜日: 2015-12-01
当月の最終金曜日: 2015-11-27
```

# 13.Jinja2
Python製テンプレートエンジンです。Google App Engineで使えます。『DjangoTemplateを意識したテンプレートエンジンである』とドキュメントに表記してある通り、Djangoを利用している人にはとっつきやすいのではないでしょうか。シンプルなPJにおいて”DjangoだとFat(デブ)”な場合に選択肢にあがると思います。


# 14.nose
単体テストを簡単に書けるユニットテストフレームワークです。単純な利用だとassert関数で十分なのですが、複数のテストファイルを生成して一括でテストする際に、nosetestコマンドでファイル名が『test』から始まるpyファイルを一括で試験できて便利です。

```py:test_nose_14.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from unittest import TestCase
from nose.tools import ok_, eq_


def sum(a, b):
    return a + b


def is_even(n):
    return (n % 2 == 0)


class HogeTestCase(TestCase):
    def setUp(self):
        print 'before test'

    def tearDown(self):
        print 'after test'

    def test_sum(self):
        eq_(sum(1, 2), 3)
        eq_(sum(5, 11), 16)
        eq_(sum(0, 0), 0)
        # エラー
        eq_(sum(0, 0), 10000)

    def test_is_even(self):
        ok_(is_even(2))
        ok_(not is_even(3))
        # assertでエラーを出すと正常に動作しない
        assert is_even(15)

```

```py:実行結果
>>>nosetests
FF
======================================================================
FAIL: test_is_even (test_nose_14.HogeTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/xxxx/qiita/pypi_ranking/test_nose_14.py", line 33, in test_is_even
    assert is_even(15)
AssertionError: 
-------------------- >> begin captured stdout << ---------------------
before test

--------------------- >> end captured stdout << ----------------------

======================================================================
FAIL: test_sum (test_nose_14.HogeTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/xxxx/qiita/pypi_ranking/test_nose_14.py", line 27, in test_sum
    eq_(sum(0, 0), 10000)
AssertionError: 0 != 10000
-------------------- >> begin captured stdout << ---------------------
before test

--------------------- >> end captured stdout << ----------------------

----------------------------------------------------------------------
Ran 2 tests in 0.005s

FAILED (failures=2)

```

# 15.lxml
XMLの構文解析を行うライブラリです。lxmlをラップしてより特化したライブラリに利用されていることがよくあります。BeutifulSoupが代表例になるのではないでしょうか。

```py:lxml_15.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import requests
from lxml import html

# HTTP GET
url = "http://google.co.jp/"
response = requests.get(url)

# lxmlでパース
root = html.fromstring(response.text)

# Aタグ出力
anchors = root.xpath('//a')
for anchor in anchors:
    print(anchor.attrib['href'])

```

```py:実行結果
>>>python lxml_15.py 
http://www.google.co.jp/imghp?hl=ja&tab=wi
http://www.google.co.jp/maps?hl=ja&tab=wl
https://play.google.com/?hl=ja&tab=w8
...
```


# 16.docutils
reStructuredText形式でドキュメントを定義しておけば、1ソースでHTML,XML,Latexファイルを出力できます。

# 17.MarkupSafe
XML / HTML / XHTML形式にてエスケープされた安全な文字列を出力できます。


```py:mks_17.py 
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals

from markupsafe import Markup, escape

# エスケープ
print "エスケープ出力:", escape("<script>alert(document.cookie);</script>")

# マークアップ
tmpl = Markup("<em>%s</em>")
print "マークアップ出力:", tmpl % "Peter > Lustig"

```

```py:実行結果
>>>python ./mks_17.py 
エスケープ出力: &lt;script&gt;alert(document.cookie);&lt;/script&gt;
マークアップ出力: <em>Peter &gt; Lustig</em>
```

# 18.pyasn1
ASN.1 は、「情報の構造を定義する」ための言語です。ASN.1 によって構造を定義された情報を、「ASN.1 オブジェクト」と呼びます。pyasn1はpythonでASN.1を定義するためのライブラリです。[PyASN1 programmer's manual](http://www.red-bean.com/doc/python-pyasn1/pyasn1-tutorial.html)を参考に記述しました。上手く使えばシリアライズとデシリアライズ処理を実装できると思います。具体的な利用方法をご存知の方がいらっしゃいましたら教えてください。

![スクリーンショット 2015-11-20 13.36.08.png](https://qiita-image-store.s3.amazonaws.com/0/65312/c07f60f2-1751-05c1-0d0b-2eb445a60f60.png)

```py:pyasn1_18.py 
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from pyasn1.type import univ
"""
定義
;; values specification
age-of-universe INTEGER ::= 13750000000
mean-martian-surface-temperature INTEGER ::= -63
"""

ageOfUniverse = univ.Integer(13750000000)
print ageOfUniverse

meanMartianSurfaceTemperature = univ.Integer(-63)
print meanMartianSurfaceTemperature
```

```py:実行結果
>>>python ./pyasn1_18.py 
13750000000
-63
```

# 19.PyYAML
YAMLはスクリプト言語と人間の読みやすさと相互作用のために設計されたデータのシリアル化形式です。PyYAMLは、Python用のYAMLパーサーです。APIのプロトコルをyaml定義してPythonと他言語で同じモデルを共有したり、excelデータをjson化する際のマッピング時に利用しています。

```py:pyyaml_19.py 
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import yaml

yaml_str = """
fields:
- column: id
  name: ID
  type: int
  validate:
    unique: true

- column: campaign_id
  name: キャンペーンID
  type: int

- column: description
  name: キャンペーン詳細説明
  type: char
"""

y = yaml.load(yaml_str)
print type(y), y

```

```py:実行結果
>>>python ./pyyaml_19.py 
<type 'dict'> {'fields': [{'column': 'id', 'validate': {'unique': True}, 'type': 'int', 'name': 'ID'}, {'column': 'campaign_id', 'type': 'int', 'name': u'\u30ad\u30e3\u30f3\u30da\u30fc\u30f3ID'}, {'column': 'description', 'type': 'char', 'name': u'\u30ad\u30e3\u30f3\u30da\u30fc\u30f3\u8a73\u7d30\u8aac\u660e'}]}
```


# 20.pytz
Pythonのための全世界タイムゾーン定義です。たとえば普段はutc+0で時間を管理していて、表示時のみutc+9の日本時間で出力する処理を簡潔に書くことができます。

```py:pytz_20.py 
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from datetime import datetime
import pytz

# 標準
print datetime.now()

# 日本時間
jst = datetime.now(tz=pytz.timezone('Asia/Tokyo'))
print jst

# ニューヨーク時間
nyt = datetime.now(tz=pytz.timezone('US/Eastern'))
print nyt

# 時刻差
print "diff:", nyt - jst

```

```py:実行結果
>>>python ./pytz_20.py 
2015-11-20 13:56:54.633965
2015-11-20 13:56:54.661743+09:00
2015-11-19 23:56:54.665424-05:00
diff: 0:00:00.003681
```


# 週間10位. pycrypto
Pythonの暗号化ツールキットです。様々な暗号アルゴリズムとプロトコルを提供しています。

```py:AES暗号化と複合化を行う
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from Crypto.Cipher import AES
import base64
import os

# Cipherオブジェクトのブロックサイズ; 16, 24, or 32 for AES
BLOCK_SIZE = 32

# ブロック長に満たない場合はPaddingで埋める
PADDING = '{'

# ブロック長に満たない部分をPaddngで埋める関数
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING

# base64で暗号化と複合化を行う関数
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)

# シークレットキーをランダム生成
secret = os.urandom(BLOCK_SIZE)

# シークレットキーでCipherオブジェクトを生成
cipher = AES.new(secret)

# 文字列を暗号化
encoded = EncodeAES(cipher, 'password')
print 'Encrypted string:', encoded

# 文字列を複合化
decoded = DecodeAES(cipher, encoded)
print 'Decrypted string:', decoded

```

```py:実行結果
>>>python ./aes_w10.py 
Encrypted string: P2vLpfpZgQyh1DPiY7a9TQfjGIiw3HcCh1qBxBwvtBk=
Decrypted string: password
```

# 週間16位. cffi
Cコードを呼び出すための外部関数インタフェースです。

```py:cffi_w16.py
from cffi import FFI

ffi = FFI()
ffi.cdef("""
int printf(const char *format, ...);   // copy-pasted from the man page
""")
C = ffi.dlopen(None)  # loads the entire C namespace
arg = ffi.new("char[]", "world")  # equivalent to C code: char arg[] = "world";
C.printf("hi there, %s.\n", arg)  # call printf

```

```py:実行結果
>>>python ./cffi_w16.py 
hi there, world.
```


# 週間17位. colorama
コンソールのTextを色付けできます。

```py:colorama_w17
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from colorama import Fore, Back, Style
print(Fore.RED + 'あかいろ！')
print(Back.GREEN + '赤文字 + はいけいみどり')
print(Style.DIM + '+ かすんだ文字')
print(Style.RESET_ALL)
print('リセット後の文字色')

```

■ 実行結果
![スクリーンショット 2015-11-20 17.03.17.png](https://qiita-image-store.s3.amazonaws.com/0/65312/50bc0ed4-406e-afef-81f4-23fc8e0092e3.png)


# 週間20位. rsa
RSAの実装。暗号化と復号化、署名と署名の確認、およびキー生成をサポートしています。。

```py:rsa_w20.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import rsa

# キーの生成
(bob_pub, bob_priv) = rsa.newkeys(512)

# 暗号化
message = 'hello Bob!'.encode('utf8')
crypto = rsa.encrypt(message, bob_pub)
print crypto

# 複合化
message = rsa.decrypt(crypto, bob_priv)
print(message.decode('utf8'))

```

```py:実行結果
>>>python ./rsa_w20.py 
i??u)"?}%??4?????4????:?n?Z????A?6?>?XF[/?XA%usc?ؙ?
hello Bob!
```
# 参考
[PyPI Ranking](http://pypi-ranking.info/alltime)
[Python パッケージ管理技術まとめ](http://www.yunabe.jp/docs/python_package_management.html)
[python-dateutilの使い方](http://imagawa.hatenadiary.jp/entry/20111126/1322298988)



パッケージのPyPiトップページにサンプルコードが記載されていると、概要把握が随分と楽だったので真似しようと思いました。週間ランキングの21位〜50位ライブラリにはsqlalchemyやsupervisordといった面白そうなライブラリが並んでいたのでいつか使ってみたいです。