Python: requestsのタイムアウトエラーについて

pythonでHTTP通信するときに大体使うrequestsで、timeoutエラーの種類で問題の切り分けがしたくて調べたのでちょっとまとめ。 TL;DR 公式ドキュメントのExceptionsを見るとわかりやすい。 中でもタイムアウト関連のエラーは以下の二つ: connect timeout requests.exceptions.ConnectTimeout例外が投げられる。 相手のサーバと接続を確立する時に時間がかかりすぎたtimeout。 公式ドキュメント read timeout requests.exceptions.ReadTimeout例外が投げられる。 相手のサーバからレスポンスが返ってくるまでに時間がかかりすぎたtimeout。 公式ドキュメント 両方まとめてcatchしたい時は requests.exceptions.Timeout例外が設定されていて、ConnectTimeout, ReadTimeoutどちらも含まれます。 もうちょっと詳しく そもそもRequestsの例外の中には、RequestException(曖昧な例外)やConnectionErrorが設定されていて、明らかに設定がおかしい場合や早期に接続エラーが起きた場合には、レスポンスを待つ前にこの例外が投げられます。 それらが起きずにtimeoutエラーが起きた場合は、接続の確立で相手からレスポンスが返ってこない(ConnectTimeout)か、接続確率はできてるけど接続先がデータの準備などで時間がかかりすぎて設定したtimeout時間内にレスポンスが返ってこない(Readtimeout)かの二択。 なので、ConnectTimeoutが起きた時には安全に再試行できると公式ドキュメントにも書かれてます(少なくともリクエスト時の設定に問題がある訳じゃないから)。 Timeout例外が出た時にする事は下記の感じになると思います: ConnectTimeoutが出た場合は、リクエストを投げてる相手のサーバがダウンしてないか、ネットワーク設定に問題がないかを確認する。 ReadTimeoutが出た場合は、接続の確立には成功していて、向こうのレスポンスに時間がかかっているので、リクエストするサーバ側にも責任がある場合はチューニングする。そうでない場合は一度timeout時間を伸ばして成功するか様子を見る。 デフォルトのtimeout時間は設定されていないので注意する 明示的に設定しない限り、timeoutのデフォルトはNoneです。つまりtimeoutしません。 基本的にはtimeoutを設定して、上記のtimeoutエラーで原因がわかるようにした方が良さそうです。 import requests try: # connect timeout, read timeoutどちらも同じ値で良い場合 res = requests.get('有効なURL', timeout=30) # connect timeout=30, read timeout=60とかで分けたい場合 res = requests.get('有効なURL', timeout=(30, 60)) except requests.exceptions.ConnectTimeout: print("接続確立のエラー") except requests.exceptions.ReadTimeout: print("レスポンスが遅すぎたエラー")

<span title='2023-03-08 16:47:00 +0900 +0900'>3月 8, 2023</span>

【Python】フォーマット済み文字列リテラル

目的 すごく今更&簡潔にだけど、python3.6以降で利用できる文字列フォーマットについてまとめていきます。 (ずっとstr.format()を使っていたので戒めも兼ねて)。 フォーマット済み文字列リテラルとは フォーマット済み文字列リテラル(f-string)では、文字列の先頭にfを付けることで、pythonの式を文字列内に{式}の形で埋め込むことができます。 従来の書き方よりも簡潔、かつわかりやすく記述することができる書き方です。 公式ドキュメント 使い方 変数に入った数字を3文字のカンマ区切りにする hoge = 99999999 # 従来のstr.format() print("{:,}".format(hoge)) # フォーマット済み文字列リテラル print(f"{hoge:,d}") :の後ろに整数をつけて縦を揃える tokuten = {"kokugo": 9, "sugaku": 81, "eigo": 100} for sub, point in tokuten.items(): print(f'{sub:10} ==> {point:5d}') # kokugo ==> 9 # sugaku ==> 81 # eigo ==> 100 まとめ 従来のstr.format()と比べると、f-stringは最終結果が人の目で見てもわかりやすいですね。

<span title='2021-08-02 18:52:08 +0900 +0900'>8月 2, 2021</span>

【Python】cerberusまとめ

cerberusとは CERBERUS, n. The watch-dog of Hades, whose duty it was to guard the entrance; everybody, sooner or later, had to go there, and nobody wanted to carry off the entrance. - Ambrose Bierce, The Devil’s Dictionary ケルベロスはシンプルで軽量なデータ検証機能を提供するパッケージです。 公式曰く、拡張も容易なため、カスタム検証も可能です。 (以下、9割公式のドキュメントの翻訳です) 概要 検証用のスキーマを定義し、それを Validator クラスのインスタンスに渡します。 schma = {'name': {'type': 'string'}} v = Validator(schema) 次に、validate()を呼び出すことで、簡単にスキーマと辞書を検証できます。 検証が成功すると True が返されます。 document = {'name': 'john doe'} v.validate(document) # True インストール 安定バージョンはpipから取得できます。 pip install cerberus 使い方 基本的な使い方 # 概要の通り。スキーマを定義し、Validatorクラスに渡して検証する。 >>> from cerberus import Validator >>> schema = {'name': {'type': 'string'}} >>> v = Validator(schema) >>> document = {'name': 'john doe'} >>> v....

<span title='2021-02-19 12:01:46 +0900 +0900'>2月 19, 2021</span>

【Python】poetryを試してみる

poetryとは pythonの環境管理ツールです。 機能としてはpipenvに近い感じでした。 本当に触りだけやってみたリポジトリはこちら。 sample-poetry インストール $pip install poetry プロジェクトを作る $poetry new sample-project 実行すると下記のファイル・フォルダが作成されます。 sample-project ├── README.rst ├── pyproject.toml ├── sample_project │ └── __init__.py └── tests ├── __init__.py └── test_sample_project.py モジュールの追加 $cd sample-project # pyproject.tomlがある階層で $poetry add [--dev] <package name> これでpoetryが管理している仮想環境内にモジュールが追加されます。 それに伴って、ファイルと依存関係を管理する pyproject.tomlとpoetry.lock が作成されます。 Remove Deoendency $poetry remove <package name> This is very simple :) Use Virtual Environment # not active $poetry run python -m pytest # active $poetry shell Use Exsting Environment $poetry install [--no-dev] Reference Poetry - Python dependency management and packaging made easy....

<span title='2021-02-19 12:01:46 +0900 +0900'>2月 19, 2021</span>

【Python】エラーについて

知りたかったこと try-catch の有効範囲はどれくらいなのか(呼び出した関数で起きたエラーも拾えるのか) ネストしたエラーの扱いってどうするのが良いんだろう 結論 呼び出された先の例外もキャッチできますφ(・・ 調べて知ったこと エラーには構文エラーと例外がある 複数の例外を指定することができる except (RuntimeError, TypeError, NameError): pass exceptは上から順に見て、引っかかったタイミングでそのexcept節内部のみを実行する 最後の except 節では例外名を省いて、ワイルドカードにすることができる しかし、ワイルドカードの except 節は通常のプログラムエラーをたやすく隠してしまうため、注意は必要 Try…exceptの中にはelse節を設けることができる。else節は全てのexcept節よりも後ろに置く try 節で全く例外が創出されなかった時に実行されるコードを記述することができる for arg in sys.argv[1:]: try: f = open(arg, 'r') except OSError: print('cannot open', arg) else: print(arg, 'has', len(f.readlines()), 'lines') f.close() 参考: Python の例外処理(try, except, else, finally) | note.nkmk.me 8. エラーと例外 — Python 3.8.1 ドキュメント Except 節では例外名の後に変数を指定できる。この変数は例外インスタンスに結び付けられ、instance.argsに例外インスタンス生成時の引数が入る。 例外インスタンスに実装されている__str__はinstance.argsをわざわざ出力しなくても見られるようになっているので、print(inst)で見られる。便利。 例外ハンドラは、try 節の直下で発生した例外を処理するだけではなく、その try 節から(たとえ間接的にでも)呼び出された関数の内部で発生した例外も処理する。(!) def this_fails(): ... x = 1/0 ....

<span title='2021-02-19 12:01:46 +0900 +0900'>2月 19, 2021</span>

【Pytyon】リストの重複要素をカウントする

目的 投票結果を DB に貯めて、その結果を一位から取得したい。 DB 構成は、 Id Recipe int str というシンプルな感じです。 ここからレコードの recipe の値を、[a, b, c, b, ...]と言ったリストに直した際、 「一番投票数の多かったもの」や「投票数が多かった順の要素のリスト」が欲しい。 TL;DR collectionsを使えば比較的簡単にできます。 要素のカウントは collections が便利 import collections votes_list = [a, b, c, b] c = collections.Counter(votes_list) # Counter({'b': 2, 'a': 1, 'c': 1}) # `要素`: `出現回数` recipe = c.most_common() # [('b', 2), ('a', 1), ('c', 1)] # 出現回数が多い順に並べ替えてくれる recipe = c.most_common()[0][0] # b 参考にさせていただいたもの お世話になりました。 collections — コンテナデータ型 — Python 3.8.1 ドキュメント...

<span title='2021-02-19 12:01:46 +0900 +0900'>2月 19, 2021</span>