在Raspberry Pi上制作Python服务器的5种方法 第一部分

哈Ha

如今,许多家庭自动化项目(不仅限于此)都使用Raspberry Pi。 同时,不仅可以直接访问设备,而且还可以使用浏览器非常方便-这使您可以从计算机,手机甚至在世界任何地方远程执行必要的操作。



假设我们已经有一个超级Python程序,它执行非常重要的工作,从闪烁LED到控制“智能家居”或至少是喂猫器。 我将展示从简单到复杂的不同方式,以及如何通过添加一些代码来对此类应用程序进行Web访问。

本文面向的是初学者,专业人士不太可能在这里找到全新的东西,但我希望它对Linux新手有用。 对于那些感兴趣的人,继续减产。

注意 :这篇文章是一种“实验”,他们在评论中抱怨说,对于初学者来说,没有足够的文章供Habré使用。 我试图填补这一空白,但是据估计,很明显继续这种格式是否有意义。

因此,让我们开始吧。

配置Raspberry Pi


让我们希望读者拥有一个通过WiFi或以太网连接到家庭网络的Raspberry Pi,并且读者知道IP地址是什么,以及如何使用腻子通过SSH远程登录Raspberry Pi。 我们将考虑所谓的无头配置-没有键盘和显示器。 但是在您使用Raspberry Pi进行操作之前,有一些小小的生活技巧。

提示N1 。 要使用Raspberry Pi进行远程操作,您需要在Raspberry Pi上配置SSH,并且默认情况下它已关闭。 您可以按照传统方式启动标准配置程序,但是它可以更简单-记录磁盘映像后,只需在SD卡的根目录中创建一个空的ssh文件(不带扩展名)。 此外,在加载Raspberry Pi之后,SSH将立即处于活动状态。

要远程访问设备,您需要找出Raspberry Pi的IP地址。 为此,只需打开路由器的控制面板,在此处找到DHCP客户端列表,从那里复制所需的IP地址(例如,它将为192.168.1.102),然后输入命令putty.exe pi@192.168.1.102 (对于Windows)或ssh pi @ 192.168.1.102(对于Linux或OSX)。

但是,IP地址可以更改,例如,在重启路由器后,这并不总是很方便。 从此开始, 技巧N2 –配置静态IP地址。 为此,请在Raspberry Pi上运行sudo nano /etc/dhcpcd.conf命令,然后输入以下设置:

interface eth0 static ip_address=192.168.1.152/24 static routers=192.168.1.1 static domain_name_servers=192.168.1.1 8.8.8.8 

如果需要WiFi地址,则接口为wlan0,如果为以太网,则为eth0。 IP地址,当然,您需要替换自己的IP地址。 重新引导后,通过发出ifconfig命令确保IP地址正确。

现在一切就绪,我们可以启动Python。 所有示例均针对Python 3.7给出,因为2.7早已被弃用,并且对其进行维护没有任何意义。 但是,只需更改少量代码,一切就可以在需要的地方运行。 顺便说一下,Python语言是跨平台的-这意味着下面的所有代码都可以在Windows和OSX上运行,当然也可以在Raspberry Pi上运行。 接下来是Council N3-您可以在常规PC上调试程序,并将完成的版本上载到Raspberry Pi。 您可能只需要为GPIO方法创建包装函数;其他所有方法都将起作用。

因此,我们的任务是通过常规浏览器提供对应用程序的访问。 因为它时尚,时尚,青春,“物联网”就是我们的一切。

方法1:命令行


最简单的方法,根本不需要编程。

在Raspberry Pi上选择所需的文件夹,然后输入命令:

 python3 -m http.server 5000 

就是这样,文件服务器在Raspberry Pi上运行! 转到页面http://192.168.1.102►000就足够了,我们将在浏览器中看到我们的文件:



如果您需要以最小的努力打开对任何文件的远程访问,这将非常方便。 您也可以输入命令sudo python3 -m http.server 80并使用标准的第80个端口启动服务器,这不会在浏览器的地址栏中指示该端口。

顺便说一句,如果我们希望服务器即使在关闭终端后仍能正常工作,则可以使用sudo nohup python3 -m http.server 80&命令 -这将在后台启动该过程。 您可以通过重新引导或在命令行上输入sudo killall python3命令来杀死此类程序。

方法2:SimpleHTTPServer


我们可以很简单地将同一台服务器集成到我们的Python程序中,为此足以在程序启动时在单独的线程中启动它。 现在,我们无需理会命令行,而在程序运行时,服务器将运行。

 import http.server import socketserver from threading import Thread import os def server_thread(port): handler = http.server.SimpleHTTPRequestHandler with socketserver.TCPServer(("", port), handler) as httpd: httpd.serve_forever() if __name__ == '__main__': port = 8000 print("Starting server at port %d" % port) os.chdir("/home/pi/Documents") Thread(target=server_thread, args=(port,)).start() 

如果我们想提供从服务器到当前文件夹以外的其他文件夹的访问,则os.chdir命令是可选的。

方法3:HTTPServer


这已经是一个成熟的Web服务器,能够处理GET和POST请求,返回不同的数据等。但是,当然,您将需要更多的代码。

考虑服务器的最低工作版本:

 from http.server import BaseHTTPRequestHandler, HTTPServer html = "<html><body>Hello from the Raspberry Pi</body></html>" class ServerHandler(BaseHTTPRequestHandler): def do_GET(self): if self.path == "/": self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(html.encode('utf-8')) else: self.send_error(404, "Page Not Found {}".format(self.path)) def server_thread(port): server_address = ('', port) httpd = HTTPServer(server_address, ServerHandler) try: httpd.serve_forever() except KeyboardInterrupt: pass httpd.server_close() if __name__ == '__main__': port = 8000 print("Starting server at port %d" % port) server_thread(port) 

我们启动浏览器,并在其中看到我们的HTML页面:



这个服务器很容易教给文件,例如图像。

将img标签添加到HTML:

 html = '<html><body><h3>Hello from the Raspberry Pi</h3><img src="raspberrypi.jpg"/></body></html>' 

当然,源文件“ raspberrypi.jpg”必须位于程序文件夹中。 将接收文件的功能添加到do_GET函数中:

  def do_GET(self): print("GET request, Path:", self.path) if self.path == "/": self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(html.encode('utf-8')) elif self.path.endswith(".jpg"): self.send_response(200) self.send_header('Content-type', 'image/jpg') self.end_headers() with open(os.curdir + os.sep + self.path, 'rb') as file: self.wfile.write(file.read()) else: self.send_error(404, "Page Not Found {}".format(self.path)) 

我们启动服务器,然后看到相应的图片:



这样的服务器不太可能会赢得Web设计竞赛,但是效果很好。 可以很容易地迫使服务器提供更多有用的数据,例如,返回有关程序操作的信息。 例如,为新的状态功能添加一个处理程序:

 import psutil import json def cpu_temperature(): return psutil.sensors_temperatures()['cpu-thermal'][0].current def disk_space(): st = psutil.disk_usage(".") return st.free, st.total def cpu_load() -> int: return int(psutil.cpu_percent()) def ram_usage() -> int: return int(psutil.virtual_memory().percent) def do_GET(self): ... elif self.path == "/status": self.send_response(200) self.send_header('Content-Type', 'application/json') self.end_headers() health = {'CPUTemp': cpu_temperature(), 'CPULoad': cpu_load(), "DiskFree": disk_space()[0], "DiskTotal": disk_space()[1], "RAMUse": ram_usage()} self.wfile.write(json.dumps(health).encode('utf-8')) 

现在我们可以在浏览器中打开链接http://192.168.1.102►000/status并查看当前系统参数:



顺便说一下,正如您所看到的,我们以JSON格式发送数据,这将使我们可以将其用于其他一些请求。

结论


所有的构思都不合适。 第二部分在这里可用

重要:安全措施

如果Raspberry Pi使用外部IP地址,则绝对应牢记安全措施。 似乎没有人需要您的小型服务器,但是现在可以轻松批量扫描所有IP地址范围(例如, 乌克兰奥地利 )并查找所有可用设备。 因此,您绝对应该在Raspberry Pi上更改密码,并且不应在设备上存储任何机密信息(Dropbox文件夹,在脚本中硬编码的名称/密码,照片等)。

PS:添加了一项调查以了解图片

Source: https://habr.com/ru/post/zh-CN472126/


All Articles