Cherrypy 相關功能介紹
CherryPy 模組安裝:
pip install cherrypy
CherryPy 程式架構
最簡單的 CherryPy 程式:
#coding: utf-8
# 最簡單的 CherryPy 程式
# 導入 cherrypy 與 os 模組
import cherrypy,os
# 建立 HelloWorld 類別物件
class HelloWorld(object):
# 定義一個會內建呼叫的 index 方法
def index(self):
# 傳回字串
return "Hello World!"
# 可以從外部以 index 連結呼叫此方法
index.exposed = True
# 利用 os.system() 執行 chrome.exe, 直接以瀏覽器開啟 cherrypy 伺服器
os.system("V:/Chrome/chrome.exe http://localhost:8083")
# 設定 cherrypy 的連結埠號為 8083
cherrypy.server.socket_port = 8083
# 設定 cherrypy 的啟動 IP 為 127.0.0.1
cherrypy.server.socket_host = '127.0.0.1'
# 以 HelloWorld() 物件啟動 cherrypy
cherrypy.quickstart(HelloWorld())
從上面的程式執行, 可以了解 CherryPy 的基本架構, 主要利用 HelloWorld() 物件中的方法來進行呼叫執行, 而且一旦啟動, 會自動呼叫 index() 方法, 而使用者也可以自行建立其他方法.
import cherrypy,os
class HelloWorld(object):
def index(self):
return "Hello World!"
index.exposed = True
def mymethod(self):
return "This is my method!"
mymethod.exposed = True
os.system("V:/Chrome/chrome.exe http://localhost:8083/mymethod")
cherrypy.server.socket_port = 8083
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(HelloWorld())
下一個範例, 特別將 mymethod.exposed = True 蓋去, 表示使用者無法直接利用瀏覽器呼叫, 而只能以 self.mymethod() 的方式, 由其他可以直接呼叫的方法中執行, 下列程式執行後, http://localhost:8083 與 http://localhost:8083/index 結果相同, 但是卻無法直接呼叫 mymethod().
import cherrypy,os
class HelloWorld(object):
def index(self):
#return "Hello World!"
return self.mymethod()
index.exposed = True
def mymethod(self):
return "This is my method!"
#mymethod.exposed = True
os.system("V:/Chrome/chrome.exe http://localhost:8083")
os.system("V:/Chrome/chrome.exe http://localhost:8083/index")
os.system("V:/Chrome/chrome.exe http://localhost:8083/mymethod")
cherrypy.server.socket_port = 8083
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(HelloWorld())
Python3 程式與 Javascript 程式交換變數, 使用者呼叫時, 由 URL 連結中輸入變數值, 然後交由 Python3 傳給 Javascript 程式.
import cherrypy,os
class HelloWorld(object):
def index(self,var1=None):
outString = '''
'''
return outString
index.exposed = True
os.system("V:/Chrome/chrome.exe http://localhost:8083?var1=123")
os.system("V:/Chrome/chrome.exe http://localhost:8083?var1=Hello")
cherrypy.server.socket_port = 8083
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(HelloWorld())
利用 cherrypy.request.method 來判定變數取值的方法, 這裡透過 GET 取得變數值, 另外以表單取變數值的方法稱為 POST.
import cherrypy,os
class HelloWorld(object):
def index(self,var1=None):
outString = '''
'''
outString += cherrypy.request.method
return outString
index.exposed = True
os.system("V:/Chrome/chrome.exe http://localhost:8083?var1=123")
cherrypy.server.socket_port = 8083
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(HelloWorld())
CherryPy 與 session
import cherrypy,os
class HelloWorld(object):
# cherrypy 執行的設定檔案, 以 dictionay 資料格式設定
_cp_config = {
# 配合 utf-8 格式之表單內容
# 若沒有 utf-8 encoding 設定,則表單不可輸入中文
'tools.encode.encoding': 'utf-8',
'tools.sessions.on' : True,
'tools.sessions.storage_type' : 'file',
'tools.sessions.locking' : 'explicit',
'tools.sessions.storage_path' : 'v:/tmp',
'tools.sessions.timeout' : 60
}
def index(self,var1=None):
outString = '''
'''
outString += cherrypy.request.method
count = cherrypy.session.get('count', 0) + 1
cherrypy.session['count'] = count
outString += " count is now:"+str(count)
return outString
index.exposed = True
def reset_session(self):
# delete all session data
#cherrypy.session.delete()
# only delete 'count' session
del cherrypy.session['count']
return "count is deleted"
reset_session.exposed = True
os.system("V:/Chrome/chrome.exe http://localhost:8083?var1=123")
cherrypy.server.socket_port = 8083
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(HelloWorld())
再加上客製化錯誤訊息:
#coding: utf-8
import cherrypy,os
class HelloWorld(object):
# cherrypy 執行的設定檔案, 以 dictionay 資料格式設定
_cp_config = {
# 配合 utf-8 格式之表單內容
# 若沒有 utf-8 encoding 設定,則表單不可輸入中文
'tools.encode.encoding': 'utf-8',
'tools.sessions.on' : True,
'tools.sessions.storage_type' : 'file',
'tools.sessions.locking' : 'explicit',
'tools.sessions.storage_path' : 'v:/tmp',
'tools.sessions.timeout' : 60
}
def index(self,**var):
outString = '''
'''
except:
outString += '''
'''
pass
outString += cherrypy.request.method
count = cherrypy.session.get('count', 0) + 1
cherrypy.session['count'] = count
outString += " count is now:"+str(count)
return outString
index.exposed = True
def reset_session(self):
# delete all session data
#cherrypy.session.delete()
# only delete 'count' session
del cherrypy.session['count']
return "count is deleted"
reset_session.exposed = True
# 客製化的 error 402 函式
def error_page_402(status, message, traceback, version):
return "Error %s - 抱歉! 發生 402 錯誤!" % status
cherrypy.config.update({'error_page.402': error_page_402})
def error_page_404(status, message, traceback, version):
return "Error %s - 抱歉! 發生 404 錯誤!" % status
cherrypy.config.update({'error_page.404': error_page_404})
os.system("V:/Chrome/chrome.exe http://localhost:8083?var1=123")
cherrypy.server.socket_port = 8083
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(HelloWorld())
CherryPy 以 https 啟動
CherryPy 程式以 http 及 https 模式啟動
#coding: utf-8
import cherrypy,os
class HelloWorld(object):
# cherrypy 執行的設定檔案, 以 dictionay 資料格式設定
_cp_config = {
# 配合 utf-8 格式之表單內容
# 若沒有 utf-8 encoding 設定,則表單不可輸入中文
'tools.encode.encoding': 'utf-8',
'tools.sessions.on' : True,
'tools.sessions.storage_type' : 'file',
'tools.sessions.locking' : 'explicit',
'tools.sessions.storage_path' : 'v:/tmp',
'tools.sessions.timeout' : 60
}
def index(self,**var):
outString = '''
'''
except:
outString += '''
'''
pass
outString += cherrypy.request.method
count = cherrypy.session.get('count', 0) + 1
cherrypy.session['count'] = count
outString += " count is now:"+str(count)
return outString
index.exposed = True
def reset_session(self):
# delete all session data
#cherrypy.session.delete()
# only delete 'count' session
del cherrypy.session['count']
return "count is deleted"
reset_session.exposed = True
# 客製化的 error 402 函式
def error_page_402(status, message, traceback, version):
return "Error %s - 抱歉! 發生 402 錯誤!" % status
cherrypy.config.update({'error_page.402': error_page_402})
def error_page_404(status, message, traceback, version):
return "Error %s - 抱歉! 發生 404 錯誤!" % status
cherrypy.config.update({'error_page.404': error_page_404})
os.system("V:/Chrome/chrome.exe http://localhost:8083?var1=123")
os.system("V:/Chrome/chrome.exe https://localhost:8093?var1=123")
cherrypy.config.update({'server.socket_port': 8083, 'server.socket_host': '127.0.0.1'})
from cherrypy._cpserver import Server
server = Server()
server.socket_port = 8093
server.socket_host = '127.0.0.1'
server.ssl_certificate = 'v:/ssl_cert.pem'
server.ssl_private_key = 'v:/ssl_cert.pem'
server.subscribe()
#cherrypy.server.socket_port = 8083
#cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(HelloWorld())
僅使用 https 模式啟動上述 CherryPy 程式:
#coding: utf-8
import cherrypy,os
class HelloWorld(object):
# cherrypy 執行的設定檔案, 以 dictionay 資料格式設定
_cp_config = {
# 配合 utf-8 格式之表單內容
# 若沒有 utf-8 encoding 設定,則表單不可輸入中文
'tools.encode.encoding': 'utf-8',
'tools.sessions.on' : True,
'tools.sessions.storage_type' : 'file',
'tools.sessions.locking' : 'explicit',
'tools.sessions.storage_path' : 'v:/tmp',
'tools.sessions.timeout' : 60
}
def index(self,**var):
outString = '''
'''
except:
outString += '''
'''
pass
outString += cherrypy.request.method
count = cherrypy.session.get('count', 0) + 1
cherrypy.session['count'] = count
outString += " count is now:"+str(count)
return outString
index.exposed = True
def reset_session(self):
# delete all session data
#cherrypy.session.delete()
# only delete 'count' session
del cherrypy.session['count']
return "count is deleted"
reset_session.exposed = True
# 客製化的 error 402 函式
def error_page_402(status, message, traceback, version):
return "Error %s - 抱歉! 發生 402 錯誤!" % status
cherrypy.config.update({'error_page.402': error_page_402})
def error_page_404(status, message, traceback, version):
return "Error %s - 抱歉! 發生 404 錯誤!" % status
cherrypy.config.update({'error_page.404': error_page_404})
os.system("V:/Chrome/chrome.exe https://localhost:8093?var1=123")
cherrypy.config.update({'server.socket_port': 8093, 'server.socket_host': '127.0.0.1',
'server.ssl_certificate': 'v:/ssl_cert.pem',
'server.ssl_private_key': 'v:/ssl_cert.pem'})
#cherrypy.server.socket_port = 8083
#cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(HelloWorld())
也可以採用下列方式, 將 CherryPy 程式以 https 模式啟動:
#coding: utf-8
import cherrypy,os
class HelloWorld(object):
# cherrypy 執行的設定檔案, 以 dictionay 資料格式設定
_cp_config = {
# 配合 utf-8 格式之表單內容
# 若沒有 utf-8 encoding 設定,則表單不可輸入中文
'tools.encode.encoding': 'utf-8',
'tools.sessions.on' : True,
'tools.sessions.storage_type' : 'file',
'tools.sessions.locking' : 'explicit',
'tools.sessions.storage_path' : 'v:/tmp',
'tools.sessions.timeout' : 60
}
def index(self,**var):
outString = '''
'''
except:
outString += '''
'''
pass
outString += cherrypy.request.method
count = cherrypy.session.get('count', 0) + 1
cherrypy.session['count'] = count
outString += " count is now:"+str(count)
return outString
index.exposed = True
def reset_session(self):
# delete all session data
#cherrypy.session.delete()
# only delete 'count' session
del cherrypy.session['count']
return "count is deleted"
reset_session.exposed = True
# 客製化的 error 402 函式
def error_page_402(status, message, traceback, version):
return "Error %s - 抱歉! 發生 402 錯誤!" % status
cherrypy.config.update({'error_page.402': error_page_402})
def error_page_404(status, message, traceback, version):
return "Error %s - 抱歉! 發生 404 錯誤!" % status
cherrypy.config.update({'error_page.404': error_page_404})
os.system("V:/Chrome/chrome.exe https://localhost:8093?var1=123")
cherrypy.server.socket_port = 8093
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.server.ssl_certificate = 'v:/ssl_cert.pem'
cherrypy.server.ssl_private_key = 'v:/ssl_cert.pem'
cherrypy.quickstart(HelloWorld())
CherryPy 的虛擬主機 (Virtual Hosting) 設定方法:
#coding: utf-8
import cherrypy,os
'''
CherryPy 的虛擬主機對應
1. 修改 Windows C:\WINDOWS\system32\drivers\etc\hosts 檔案
127.0.0.1 server1.my.domain
127.0.0.1 server2.my.domain
2. 以下設定將可透過
https://server1.my.domain:8093
https://server2.my.domain:8093
連結到同一 CherryPy 網際程式的不同對應物件方法
'''
class Root(object):
def __init__(self):
self.server1 = HelloWorld1()
self.server2 = HelloWorld2()
class HelloWorld1(object):
# cherrypy 執行的設定檔案, 以 dictionay 資料格式設定
_cp_config = {
# 配合 utf-8 格式之表單內容
# 若沒有 utf-8 encoding 設定,則表單不可輸入中文
'tools.encode.encoding': 'utf-8',
'tools.sessions.on' : True,
'tools.sessions.storage_type' : 'file',
'tools.sessions.locking' : 'explicit',
'tools.sessions.storage_path' : 'v:/tmp',
'tools.sessions.timeout' : 60
}
def index(self,**var):
outString = '''這是 server1.my.domain
'''
except:
outString += '''
'''
pass
outString += cherrypy.request.method
count = cherrypy.session.get('count', 0) + 1
cherrypy.session['count'] = count
outString += " count is now:"+str(count)
return outString
index.exposed = True
def reset_session(self):
# delete all session data
#cherrypy.session.delete()
# only delete 'count' session
del cherrypy.session['count']
return "count is deleted"
reset_session.exposed = True
# 客製化的 error 402 函式
def error_page_402(status, message, traceback, version):
return "Error %s - 抱歉! 發生 402 錯誤!" % status
cherrypy.config.update({'error_page.402': error_page_402})
def error_page_404(status, message, traceback, version):
return "Error %s - 抱歉! 發生 404 錯誤!" % status
cherrypy.config.update({'error_page.404': error_page_404})
class HelloWorld2(object):
# cherrypy 執行的設定檔案, 以 dictionay 資料格式設定
_cp_config = {
# 配合 utf-8 格式之表單內容
# 若沒有 utf-8 encoding 設定,則表單不可輸入中文
'tools.encode.encoding': 'utf-8',
'tools.sessions.on' : True,
'tools.sessions.storage_type' : 'file',
'tools.sessions.locking' : 'explicit',
'tools.sessions.storage_path' : 'v:/tmp',
'tools.sessions.timeout' : 60
}
def index(self,**var):
outString = '''這是 server2.my.domain
'''
except:
outString += '''
'''
pass
outString += cherrypy.request.method
count = cherrypy.session.get('count', 0) + 1
cherrypy.session['count'] = count
outString += " count is now:"+str(count)
return outString
index.exposed = True
def reset_session(self):
# delete all session data
#cherrypy.session.delete()
# only delete 'count' session
del cherrypy.session['count']
return "count is deleted"
reset_session.exposed = True
# 客製化的 error 402 函式
def error_page_402(status, message, traceback, version):
return "Error %s - 抱歉! 發生 402 錯誤!" % status
cherrypy.config.update({'error_page.402': error_page_402})
def error_page_404(status, message, traceback, version):
return "Error %s - 抱歉! 發生 404 錯誤!" % status
cherrypy.config.update({'error_page.404': error_page_404})
os.system("V:/Chrome/chrome.exe https://server1.my.domain:8093?var1=123")
os.system("V:/Chrome/chrome.exe https://server2.my.domain:8093?var1=123")
hostmap = {
'server1.my.domain:8093': '/server1',
'server2.my.domain:8093': '/server2',
}
config = {
'request.dispatch': cherrypy.dispatch.VirtualHost(**hostmap)
}
cherrypy.server.socket_port = 8093
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.server.ssl_certificate = 'v:/ssl_cert.pem'
cherrypy.server.ssl_private_key = 'v:/ssl_cert.pem'
#cherrypy.quickstart(HelloWorld())
cherrypy.quickstart(Root(), '/', {'/': config})
以下則為 CherryPy 網際留言簿程式範例:
#coding: utf-8
#
# note.py CherryPy 應用範例程式
'''
本程式在展示 CherryPy 程式的:
1. session 用法
2. 靜態內容引用方法
3. 全域設定與靜態內容設定方法
4. 自動處理數列頁面內容的用法
5. 表單列印與資料處理方法
6. 重新導向用法
以及 Python3 程式的:
1. 重新定義物件 __str__ 字串傳回方法
2. 留言時間資料的字串轉換處理
3. 數列資料的反向排序與附加
'''
#
# 導入 Python 標準模組
import os, time
# 導入 cherrypy 模組
import cherrypy
# 確定程式檔案所在目錄
_curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
# _notes 為一全域數列變數, 主要利用記憶體儲存使用者的留言內容
_notes = []
# 相關超文件變數
_header = """
留言簿
"""
_footer = """
"""
_note_form = """
"""
_author_form = """
"""
_note_view = """
%s
%s - %s (%d)
"""
###############################################################
# 唯一的 domain object (也可稱為 Model)
###############################################################
class Note(object):
def __init__(self, author, note):
self.id = None
self.author = author
self.note = note
self.timestamp = time.gmtime(time.time())
# 改寫物件字串資料列出的傳回內容
def __str__(self):
return self.note
###############################################################
# Note 應用程式的主要進入點
###############################################################
class NoteApp:
"""
打算用 CherryPy 啟動的程式物件
"""
# 啟動 session 工具
# 採用 utf-8 編碼
_cp_config = {'tools.sessions.on': True,
# 若無 utf-8 編碼指定, 無法處理中文
'tools.encode.encoding': 'utf-8'
}
def _render_note(self, note):
"""將 note 轉為頁面的 html 內容, 輸入為 3 個字串與兩個數字"""
return _note_view % (note,
note.author,
# 依照格式列出留言時間
time.strftime("%a, %d %b %Y %H:%M:%S",
note.timestamp),
note.id,
note.id)
# 這是前置指令用法, 與 index.exposed = True 功能相同
@cherrypy.expose
def index(self):
# 取出存在 session 的作者名稱, 若無資料則將 author 設為 None
author = cherrypy.session.get('author', None)
# 頁面數列先放入超文件標頭
page = [_header]
# 若有作者資料則附加在 page 數列, 否則要求輸入
if author:
page.append("""
您好 %s, 請輸入留言.
更改作者代號.""" % (author,))
page.append(_note_form)
else:
page.append("""""")
# 以反向排列將 notes 附加到 page
notes = _notes[:]
notes.reverse()
for note in notes:
page.append(self._render_note(note))
# 在頁面最後附上 _footer
page.append(_footer)
# CherryPy 會自動處理所傳回的 page 數列資料
return page
@cherrypy.expose
def note(self, id):
# 根據代號取出留言
try:
note = _notes[int(id)]
except:
# 若為無效 id, 則傳回找不到資料之訊息
raise cherrypy.NotFound
return [_header, self._render_note(note), _footer]
@cherrypy.expose
def post(self, text):
author = cherrypy.session.get('author', None)
# 若 session 無作者資料, 則導向設定作者代號頁面
if not author:
raise cherrypy.HTTPRedirect('/author')
# Note 為 domain object Note 的一個案例
note = Note(author, text)
_notes.append(note)
note.id = _notes.index(note)
raise cherrypy.HTTPRedirect('/')
class Author(object):
@cherrypy.expose
def index(self):
return [_header, _author_form, _footer]
@cherrypy.expose
def set(self, name):
cherrypy.session['author'] = name
return [_header, """
%s 歡迎蒞臨! 請留言 留言.
""" % (name,), _footer]
if __name__ == '__main__':
# 全域設定
global_conf = {
'global': { 'autoreload.on': False,
'server.socket_host': '127.0.0.1',
'server.socket_port': 8083,
'server.protocol_version': 'HTTP/1.1'
}}
application_conf = {
'/style.css': {
'tools.staticfile.on': True,
'tools.staticfile.filename': os.path.join(_curdir, 'style.css'),
}
}
# 更新 CherryPy 的全域設定
cherrypy.config.update(global_conf)
# 建立一個應用案例
note_app = NoteApp()
# 附加一個作者類別案例到主應用案例中的 author 屬性
note_app.author = Author()
# 以 chrome 開啟網頁
os.system("V:/Chrome/chrome.exe http://localhost:8083")
# 以 application_conf 中的設定啟動 note_app
cherrypy.quickstart(note_app, config = application_conf)
# 以下為 style.css 檔案內容
'''
html, body {
background-color: #DEDEDE;
padding: 0px;
marging: 0px;
height: 100%;
}
.container {
border-color: #A1A1A1;
border-style: solid;
border-width: 1px;
background-color: #FFF;
margin: 10px 150px 10px 150px;
height: 100%;
width: 400px;
}
a:link {
text-decoration: none;
color: #A1A1A1;
}
a:visited {
text-decoration: none;
color: #A1A1A1;
}
a:hover {
text-decoration: underline;
}
input {
border: 1px solid #A1A1A1;
}
.form {
margin: 5px 5px 5px 5px;
}
.info {
font-size: 70%;
color: #A1A1A1;
}
'''
Comments
comments powered by Disqus