LoginSignup
5
0

More than 3 years have passed since last update.

MicroPythonでWebにアクセス

Last updated at Posted at 2019-06-09

免責

この記事に従って発生した如何なる損害も筆者は負うことができません。ご免なさい。

はじめに

使い勝手が良いのでMicroPythonがお気に入りです。
電子工作をしていたら、デバイスをネットにアクセスさせたくなりました。センサーのデータをアップしたり、デバイスからWebHookを呼びたいのです。

目的

urequestsパッケージを使ってMicroPythonからGAPPSなどのWebへアクセスできるようにします。

urequestsはリダイレクトに対応していない

urequestsパッケージがあり、HTTP/HTTPSアクセスはできますが、リダイレクトが必要な場合は例外が起きてエラーになります。
kk2170さん解説に、解決策など全ての答えがありますので、そちらをお勧めします。

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")
>>>
>>> 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をインストールする

何はともあれインストールしてみます。

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を改造してみる

早速、改造してみます。
できれば、パッチの内容をこのようなログではなくファイル形式で公開したいと思っています。

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を使うと、リソースの消費量を抑えられそうです。

改造したurequestsでHTTP/HTTPSアクセス
$ 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>
>>> 

参考

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0