sphinxを使ってドキュメントをコードから自動生成する。

コードからドキュメントから自動生成するには以下のコマンドを入力すれば良い。

sphinx-apidoc -F -o docs/ path/to/your/library

あとは

cd docs
make html
open _build/html

とすればドキュメンテーションがちゃんと読める。

これを使って自分がよく使うライブラリのドキュメントはdocs以下のディレクトリに一元化しておくとかすると メリットがありそうなので早速やってみる。

インターネット上にある画像を自分のところにダウンロードする

Python3.4にてhttp上にある画像をダウンロードしたかったのでメモ。

requestsというライブラリを使うと簡単にできた。

import uuid
import requests
import io

response = requests.get("http://path/to/url")
img_data = io.BytesIO(response.content)
img = Image.open(img_data)
uu = str(uuid.uuid1())
filename = "{}.png".format(uu)

# /tmp/img というフォルダーに保存する
path = os.path.join(os.path.abspath("."),"tmp","img",filename)

fp = open(path, "wb")
fp.write(response.content)
fp.close()

FlaskではじめるTDD

今までTDDをやったことなかった。これからはちゃんと保守可能なコードを書いていきたいという 気持ちが生まれたのでテストコードを書くことに決めた。とりあえず単体テストから始めていく。

実装

import json

@app.route("/api/users/hello")
def hello():
    d = {
        "name":"hello"
    }
    return Response(json.dumps(d),mimetype='application/json')

テスト

import ast
from flask import Flask
import json
import unittest

class ReqTestCase(unittest.TestCase):

    def setUp(self):
        self.app = Flask(__name__)
        self.app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:////tmp/app.db"
        self.db = SQLAlchemy(self.app)


    def test_hello(self):
       """
      /api/users/helloにGETリクエストを投げたら、helloが返ってくる。
       """
        with self.app.test_client() as client:
            res = client.get("/api/users/hello")
            res.headers['Content-Type'] = 'application/json'
            data_str = res.data.decode("utf-8")
            data_dict = ast.literal_eval(data)
            self.assertEqual("hello",data_dict.get("name"))


 if __name__ == "__main__":
        unittest.main()

今までリクエスト周りのテストは書いてなかったけど、 こうやってリクエスト周りのテストを書くと純粋なデータのやり取りの実装から進めていくことができて変更に対応しやすいコードが書けそうな感じがある。

ビューとデータの密接な結合が生じているとテストコードを書きにくいことを改めて実感するいい機会になった。

Fabricを使って、ローカル側からリモート側のプロジェクト側にてgit pullを実行させる。

今まで、このブログは以下の方法で運用していた。

  • ローカルでmarkdownファイルを作る。
  • bitbucketのほうにpushする。
  • リモートサーバーにログインして、git pullを実行。

でもこの方法だと、毎回サーバーにログインする必要が出てきて面倒。 そこでPythonのFabricというライブラリを使って

fab push

を行うだけでリモート側で git pull をしてくれるコードを書いた。

プロジェクトのルートディレクトリに以下のfabfile.pyを置くだけ。

#coding: utf-8
from fabric.api import run,env,local,settings
from fabric.operations import sudo
from fabric.context_managers import cd
import os

def try_cmd(host_type,cmd):
    run_cmd = host_type(cmd)

def host_type():
    run("uname -s")

from fabric.api import env, run
env.use_ssh_config = True

env.user = "your name"
env.hosts = ["your server's ip address"]

def push():
    with settings():

        #ローカル側の操作

        try_cmd("git commit -am 'update'")
        try_cmd(local,"git push origin master")

        #リモート側の操作

        with cd("/your/project's/path"):
            try_cmd(sudo,"git pull origin master")

これで幸せの実現ができた。