#免責
この記事に従って発生した如何なる損害も筆者は負うことができません。ご免なさい。
#はじめに
使い勝手が良いのでMicroPythonがお気に入りです。
電子工作をしていたら、デバイスをネットにアクセスさせたくなりました。センサーのデータをアップしたり、デバイスからWebHookを呼びたいのです。
#目的
urequestsパッケージを使ってMicroPythonからGAPPSなどのWebへアクセスできるようにします。
#urequestsはリダイレクトに対応していない
urequestsパッケージがあり、HTTP/HTTPSアクセスはできますが、リダイレクトが必要な場合は例外が起きてエラーになります。
kk2170さんの解説に、解決策など全ての答えがありますので、そちらをお勧めします。
$ micropython
MicroPython v1.11-37-g62f004b on 2019-06-05; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>>
>>> import upip
>>> upip.install("urequests")
>>>
>>> import urequests
>>> data = urequests.get("https://time.google.com/")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "~/.micropython/lib/urequests.py", line 112, in get
File "~/.micropython/lib/urequests.py", line 100, in request
File "~/.micropython/lib/urequests.py", line 97, in request
NotImplementedError: Redirects not yet supported
>>>
#urequestsを改造してリダイレクトに対応させてみる
ただ、「解決策 その1」をやってみたくなりました。
ということで、urequests.pyのソースコードを改造して無理やりリダイレクトに対応させます。
リダイレクト要求でエラーにせずにurequestsを再帰的に呼び出すように無理やり改造します。危険な感じですけど。
メモリが足らなくなるといけないので、gcパッケージの力を借りることにしました。gcパッケージはMicroPythonにデフォルトで入っているようです。
###urequestsをインストールする
何はともあれインストールしてみます。
$ micropython
MicroPython v1.11-37-g62f004b on 2019-06-05; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> import upip
>>> upip.install("urequests")
Installing to: ~/.micropython/lib/
Warning: micropython.org SSL certificate is not validated
Installing urequests 0.6 from https://micropython.org/pi/urequests/urequests-0.6.tar.gz
>>>
###urequestsを改造してみる
早速、改造してみます。
できれば、パッチの内容をこのようなログではなくファイル形式で公開したいと思っています。
$ cat urequests.py.patch
--- ~/.micropython/lib/urequests.py 2019-06-07 14:55:55.200352343 +0900
+++ ~/.micropython/lib/urequests.py 2019-06-07 15:03:42.659537996 +0900
@@ -1,4 +1,5 @@
import usocket
+import gc
class Response:
@@ -93,8 +94,11 @@
if l.startswith(b"Transfer-Encoding:"):
if b"chunked" in l:
raise ValueError("Unsupported " + l)
- elif l.startswith(b"Location:") and not 200 <= status <= 299:
- raise NotImplementedError("Redirects not yet supported")
+ elif l.startswith(b"Location:") and 300 <= status <= 399:
+ url = l[9:].decode().strip() # delete "Location:" from Redirect text.
+ s.close() # close the s handle to request the url recursively.
+ gc.collect() # gc.collect() for work memory.
+ return request(method, url)
except OSError:
s.close()
raise
@@ -102,6 +106,7 @@
resp = Response(s)
resp.status_code = status
resp.reason = reason
+ gc.collect() # don't close the s handle, but gc.collect() for work memory.
return resp
$
$ patch --dry-run どこか/urequests.py < urequests.py.patch
checking file どこか/urequests.py
$
$ # 問題ないなら --dry-run をはずしてパッチを当てる
$ patch どこか/urequests.py < urequests.py.patch
#改造したurequestsを使ってみる
urequestsを使って https://time.google.com/ にアクセスしてみます。
なお、mpy-crossを使うと、リソースの消費量を抑えられそうです。
$ micropython
MicroPython v1.11-37-g62f004ba4 on 2019-06-07; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>>
>>> import urequests
>>> data = urequests.get("https://time.google.com/")
>>> print(data)
<Response object at b6c4bdd0>
>>>
#参考