# 嵌入式工程師是怎么搭建web.py環境的
## 前言
作為嵌入式工程師,我們通常更熟悉底層硬件、RTOS和C語言開發。但當需要快速構建一個輕量級Web服務來調試設備或展示數據時,Python的web.py框架是個絕佳選擇。本文將詳細介紹嵌入式工程師如何從零搭建web.py開發環境。
## 一、環境準備
### 1.1 硬件平臺選擇
嵌入式工程師通常工作在以下環境:
- **開發主機**:Ubuntu/Debian或Windows系統
- **目標設備**:樹莓派/香橙派等Linux開發板
- **交叉編譯環境**:當資源受限時
推薦使用樹莓派4B作為實驗平臺:
- 四核Cortex-A72處理器
- 2GB/4GB內存選項
- 原生Python支持
### 1.2 基礎軟件安裝
```bash
# 更新軟件源
sudo apt update && sudo apt upgrade -y
# 安裝Python3和pip
sudo apt install python3 python3-pip
# 驗證安裝
python3 --version
pip3 --version
注意:嵌入式Linux系統可能需自行編譯Python,建議使用3.6+版本
# 通過pip安裝
pip3 install web.py==0.62
# 驗證安裝
python3 -c "import web; print(web.__version__)"
創建hello.py
文件:
import web
urls = (
'/', 'Index'
)
app = web.application(urls, globals())
class Index:
def GET(self):
return "Hello, Embedded World!"
if __name__ == "__main__":
app.run()
運行測試:
python3 hello.py
訪問http://<IP>:8080
應看到歡迎信息
針對資源受限設備,建議修改默認配置:
web.config.debug = False # 關閉調試模式
web.config.db_printing = False # 禁用SQL打印
添加內存監控裝飾器:
import resource
from functools import wraps
def memory_limit(max_mem):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
resource.setrlimit(
resource.RLIMIT_AS,
(max_mem, max_mem))
return f(*args, **kwargs)
return wrapper
return decorator
# 使用示例
@app.route('/mem_test')
@memory_limit(100 * 1024 * 1024) # 限制100MB
def mem_test():
return "Memory limited endpoint"
通過Web控制樹莓派GPIO:
import web
import RPi.GPIO as GPIO
urls = (
'/gpio/(\d+)', 'GPIOControl'
)
GPIO.setmode(GPIO.BCM)
class GPIOControl:
def GET(self, pin):
try:
pin = int(pin)
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, not GPIO.input(pin))
return f"GPIO {pin} toggled"
except Exception as e:
return str(e)
app = web.application(urls, globals())
if __name__ == "__main__":
app.run()
讀取DHT11溫濕度傳感器:
import web
import Adafruit_DHT
urls = (
'/sensor', 'SensorData'
)
sensor = Adafruit_DHT.DHT11
pin = 4 # GPIO4
class SensorData:
def GET(self):
humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
if humidity is not None and temperature is not None:
return f"Temp: {temperature:.1f}°C, Humidity: {humidity:.1f}%"
else:
return "Sensor read failed"
app = web.application(urls, globals())
if __name__ == "__main__":
app.run()
提升并發處理能力:
server {
listen 80;
server_name your_domain;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
針對SQLite優化:
import sqlite3
from DBUtils.PooledDB import PooledDB
db_pool = PooledDB(
creator=sqlite3,
database='/var/data/sensors.db',
maxconnections=5
)
class DataLog:
def GET(self):
conn = db_pool.connection()
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM sensor_data")
return str(cursor.fetchall())
finally:
conn.close()
# 禁用目錄遍歷
web.config.allow_subdirs = False
# 設置安全頭
class SecureHeadersMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
def new_start_response(status, headers, exc_info=None):
headers.extend([
('X-Frame-Options', 'DENY'),
('X-Content-Type-Options', 'nosniff'),
('X-XSS-Protection', '1; mode=block')
])
return start_response(status, headers, exc_info)
return self.app(environ, new_start_response)
app = web.application(urls, globals())
app.add_processor(SecureHeadersMiddleware)
基礎HTTP認證:
import base64
def check_auth(header):
auth = header.split(' ')[-1]
decoded = base64.b64decode(auth).decode('utf-8')
return decoded == "admin:secret"
class SecurePage:
def GET(self):
if 'HTTP_AUTHORIZATION' in web.ctx.env:
if check_auth(web.ctx.env['HTTP_AUTHORIZATION']):
return "Secret Content"
web.header('WWW-Authenticate', 'Basic realm="Embedded"')
web.ctx.status = '401 Unauthorized'
return "Authentication required"
創建systemd服務/etc/systemd/system/webpy.service
:
[Unit]
Description=Web.py Embedded Service
After=network.target
[Service]
User=pi
WorkingDirectory=/home/pi/webapp
ExecStart=/usr/bin/python3 /home/pi/webapp/app.py
Restart=always
[Install]
WantedBy=multi-user.target
配置旋轉日志:
import logging
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler(
'/var/log/webpy.log',
maxBytes=1*1024*1024, # 1MB
backupCount=3
)
handler.setLevel(logging.WARNING)
app.init_logging()
app.logger.addHandler(handler)
通過web.py框架,嵌入式工程師可以快速構建輕量級Web接口,實現: - 設備狀態監控 - 遠程控制GPIO - 傳感器數據可視化 - 固件OTA更新接口
雖然功能簡單,但配合適當的優化手段,完全能滿足大多數嵌入式Web交互需求。當系統復雜度增加時,可考慮遷移到Flask等更現代框架,但web.py在資源受限場景仍具獨特優勢。 “`
(全文約1650字)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。