さくらのレンタルサーバにPython3.6.1をインストールした

Python3.4をインストールしたのが昨年6月だから、ほぼ1年経っている。

手元のPCのPythonは、Anacondaという超便利な仕組みでインストールして、Python 3.6.0になっている。このPCで作ったプログラムをさくらのレンタルサーバに転送して実行したらエラーがでてしまった。

dateteimモジュールで、W3C Datetime 形式のタイムスタンプ、つまり 2004-09-22T14:12:14+00:00 という形式のやつを作りたいので下記のように書いて

dt.isoformat(timespec=’seconds’)

Python3.4.3で実行したら、

‘timespec’ is an invalid keyword

と怒られた、というわけだ。Python 3.6で動いてるんだから、プログラムの回避策を考えるよりもPythonをバージョンアップしたほうが早い。

前置きはそこそこに、Python 3.6.1のインストールはあっけなく終わった。

前回記事のさくらのレンタルサーバにPython3.4をインストールするのとおりに、「3.4.3」 を 「3.6.1」 に変更してやったらうまくいった。やっぱり作業を記録しておくのは大事ですね。ということで、再び記録しておく。

取得したソースのURL
https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tgz

% python3
Python 3.6.1 (default, May  6 2017, 18:08:26)
[GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
% pip3 -V
pip 9.0.1 from /home/bty/local/python/lib/python3.6/site-packages (python 3.6)
%

VoiceText Web APIをPythonで使ってみる

音声合成のWeb APIがあったので、Pythonで使ってみます。このサービスはベータ版ということですが、HOYAサービス株式会社が提供しています。もしかして「Misakiという女性の音声合成で有名だったんじゃないだろうか」と思って調べたら、サンプル音声 | HOYA音声合成ソフトウェア VoiceTextにありました。

さっそく、VoiceText Web API (β版)から利用登録してAPIキーを入手しました。

実験環境

  • ThinkPad X200
  • Windows7 Professional 64bit
  • Python 2.7.3

プログラムを書く

最近慣れてきたrequestsモジュールで音声データをダウンロードするプログラムを書きましたが…、

#coding:utf-8

import requests

url = 'https://api.voicetext.jp/v1/tts'
API_KEY = 'YOUR API KEY'

payload = {
    'text': 'おはようございます',
    'speaker': 'hikari',
    }

r = requests.post(url, params=payload, auth=(API_KEY,''))

f = open("test.wav", 'wb')
f.write(r.content)
f.close()

実行するとエラーが発生しました。

requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:1407742E:SSL routines:
SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

これはもしかしての”はまり”の予感的中です。

requestsモジュールのバージョンが低いからではないかと思い、pip でupgradeして

Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.__version__
'2.3.0'
>>>

最新バージョンになったにもかかわらず、同じエラーが発生します。

requestsモジュールをやめ、昔ながらのurllibとurllib2でプログラムを書いてあげても、エラーメッセージが発生しました。

urllib2.URLError: <urlopen error [Errno 1] _ssl.c:504: error:1407742E:SSL routin
es:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version>

これは何かのバグなのかも、同じエラーで悩んでいる人がいるに違いないと思い、ネットで検索して回避策を見つけました。

requests_toolbelt 0.1.0 documentation

サーバー側のOpenSSLのバージョンによっては、SSLバージョンのネゴシエーションがうまく動作できないのが原因のようです。requests_toolbeletモジュールをインストールし、SSLAdapterでSSLに使うバージョンを指定することで動作するになりました。

> pip install requests_toolbelet

プログラムを書き直す

#coding:utf-8

from requests_toolbelt import SSLAdapter
import requests
import ssl
import sys

url = 'https://api.voicetext.jp/v1/tts'
API_KEY = 'YOUR API KEY'

payload = {
    'text': 'おはようございます',
    'speaker': 'hikari',
    }

s = requests.Session()
s.mount(url, SSLAdapter(ssl.PROTOCOL_TLSv1))
r = s.post(url, params=payload, auth=(API_KEY,''))

print "status code:", r.status_code
if r.status_code != 200:
    print "error:", r.json()['error']['message']
    sys.exit()

f = open("test.wav", 'wb')
f.write(r.content)
f.close()

プログラムを実行して得たwavファイルは下記で再生できます。VoiceText Web API (β版)に反するようなので音声再生をやめます。ちょっと残念。

(2)当社のサーバーから出力された音声データは、本サービスを利用したアプリケーション内のみで使用すること
(3)当社のサーバーから出力された音声データを、直接的または間接的に配布しないこと(但し、当社の事前の書面による承諾がある場合はこの限りではありません)

VoiceText WEB APIの音声品質は抜群に良いです。ベータ版ということですが、このまま無償でサービスを続けてほしいですね。そして無償の利用範囲を広げていただけるとありがたいです。

PythonでFlickr APIを使って写真を検索する(その2)

前回では検索結果をJSON形式で取得できることがわかったので、写真をダウンロードしてみます。

実験環境

  • ThinkPad X200
  • Windows7 Professional 64bit
  • Python 2.7.3

写真をダウンロードする

検索結果から写真が保存されているURLを得るために、Photo Source URLsに仕様が書かれています。

これによると写真のURLは下記フォーマットで決定されることがわかります。

https://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}.jpg

前回エントリーで取得した結果と比べてみると、

      {
        "farm": 4,
        "id": "14676462357",
        "isfamily": 0,
        "isfriend": 0,
        "ispublic": 1,
        "owner": "107369966@N07",
        "secret": "de3d8c1e63",
        "server": "3882",
        "title": "Fruits Daifuku picture2"
      },

farm-idにfarmの値を、server-idにserverの値を、idにidの値を、secretにsecretの値をあてはめてURLを作れば、写真が保管されているURLになります。

前回エントリーのプログラムをベースにして、”daifuku”の写真を50枚ダウンロードするプログラムを書いてみました。

# -*- coding: utf-8 -*-

import requests

url = 'https://api.flickr.com/services/rest/'
API_KEY = 'YOUR API KEY'

payload = {
    'method': 'flickr.photos.search',
    'api_key': API_KEY,
    'text': 'daifuku',
    'per_page': '50',
    'format': 'json',
    'nojsoncallback': '1'
    }

r = requests.get(url, params=payload)

resp = r.json()
tpl_url = 'https://farm%s.staticflickr.com/%s/%s_%s.jpg'
count = 1
for i in resp['photos']['photo']:
    img_url = tpl_url % (i['farm'],i['server'],i['id'],i['secret'])
    print "#%04d" % count, img_url
    r = requests.get(img_url)
    fname = "%04d.jpg" % count
    f = open(fname, 'wb')
    f.write(r.content)
    f.close()
    count += 1

実行させると、おいしうな大福の写真がダウンロードできました。でもちょっと違う写真もちらほら見えます。検索APIにはパラメータが数多くあるので、いろいろと試してみるとおもしろそうです。

WS000054