[英]Create a hyperlink (or button) that executes a python script and then redirects when script completes
好吧,我設法讓它按我想要的方式工作(雖然有些/大多數人可能不同意這種方法)。 我按照下面的建議使用了Flask。 可能被視為“錯誤”的部分是404檢查循環。 這是不正確的設計,如果它持續太長時間,會導致某些瀏覽器出現“卡住腳本”錯誤。 但是,我想運行的腳本不會持續很長時間才能成為問題。
感謝您的幫助,如果您有任何其他建議,請與我們聯系。
燒瓶應用:
import threading
import subprocess
import os
import sys
from flask import Flask
from flask import render_template, abort
app = Flask(__name__)
app.debug = True
def run_script():
theproc = subprocess.Popen([sys.executable, "run_me.py"])
theproc.communicate()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/generate')
def generate():
threading.Thread(target=lambda: run_script()).start()
return render_template('processing.html')
@app.route('/is_done')
def is_done():
hfile = "templates\\itworked.html"
if os.path.isfile(hfile):
return render_template('itworked.html')
else:
abort(404)
if __name__ == "__main__":
app.run()
processing.html:
<!DOCTYPE html>
<html>
<head>
<script src="/static/jquery.min.js"></script>
</head>
<body>
<p>Processing...</p>
<script>
setInterval(function()
{
var http = new XMLHttpRequest();
http.open('HEAD', "is_done", false);
http.send();
if (http.status==200)
window.location.replace("is_done");
},2000);
</script>
</body>
</html>
原始問題:
我是初學者/中級Python程序員和初級Web開發人員所以請保持溫和。 我想要的:用戶點擊一個超鏈接,然后轉到一個中間網頁,上面寫着“正在處理......”。 在后台(在服務器上),此鏈接觸發一個python腳本,該腳本處理文件並創建新的網頁。 完成腳本后,用戶將被重定向到新創建的頁面。 我擁有:我有一個腳本來處理並吐出一個新的頁面。 我還沒想到的是如何觸發python腳本然后在腳本完成時觸發重定向。 我看過像django和cgi腳本這樣的web框架。 但我還沒有找到任何符合條件的東西。 我很可能會錯過一些完全明顯的東西,所以我真的很感激任何幫助。 謝謝。
解決這個問題的一個簡單方法是使用像Flask這樣的簡單Web框架來構建系統的Web部件。 在魔術鏈接的請求處理程序中,您需要生成腳本並跟蹤它。 查看腳本是否已完成並將其轉發給用戶的簡單方法是定期發送ajax請求以檢查完成情況。
例如,Flask網站可能如下所示:
import threading
import subprocess
import uuid
from flask import Flask
from flask import render_template, url_for, abort, jsonify, request
app = Flask(__name__)
background_scripts = {}
def run_script(id):
subprocess.call(["/path/to/yourscript.py", "argument1", "argument2"])
background_scripts[id] = True
@app.route('/')
def index():
return render_template('index.html')
@app.route('/generate')
def generate():
id = str(uuid.uuid4())
background_scripts[id] = False
threading.Thread(target=lambda: run_script(id)).start()
return render_template('processing.html', id=id)
@app.route('/is_done')
def is_done():
id = request.args.get('id', None)
if id not in background_scripts:
abort(404)
return jsonify(done=background_scripts[id])
和index.html
:
<a href="{{ url_for('generate') }}">click me</a>
和processing.html
:
<html>
<head>
<script src="/static/jquery.js"></script>
<script>
function ajaxCallback(data) {
if (data.done)
window.location.replace("http://YOUR_GENERATED_PAGE_URL");
else
window.setTimeout(function() {
$.getJSON('{{ url_for('is_done') }}', {id: {{ id }} }, ajaxCallback);
}, 3000);
}
$(document).ready(function(){
ajaxCallback({done=false});
});
</script>
</head>
<body>
Processing...
</body></html>
這是目前所有未經測試的代碼,但我希望您對如何解決此問題有所了解。 另請注意,這只有在您從一個進程提供頁面時才有效,因此如果您設置了Apache和mod_wsgi,請確保進程組中只有一個進程。
如果您需要更復雜的解決方案,您可能需要查看消息隊列等。
這對您來說可能是一個太重要的解決方案,但假設您無法取消“在服務器上創建文件”部分,這被認為是Web開發中的“最佳實踐”解決方案:
使用像Flask或Django這樣的Web框架來提供頁面。 當用戶請求通過請求啟動作業時(最好是POST請求,因為GET請求不應該導致嚴重的副作用),框架會向像Celery這樣的延遲任務系統發送消息。 然后向用戶顯示一個頁面,表明該作業已被提交。
此時,您可以使用ajax輪詢服務器並查看作業何時完成,但通常您不希望這是查看作業是否完成的唯一方法。 如果連接因任何原因而中斷,例如,如果用戶錯誤地關閉瀏覽器或選項卡(非常常見),則會浪費工作量並且用戶將不得不重新開始該過程。 如果可能的話,你應該有一種與用戶溝通的備份方式; 這可能是網站上其他地方出現的Flash消息,自動“完成工作”的電子郵件,主頁中顯示最近完成的作業的框,等等。這取決於用戶是否已登錄以及如何作業需要多長時間/是否除了創建文件之外還有副作用。
最后,您可以允許用戶通過該用戶的作業結果所特有的URL訪問該頁面。 請務必告知用戶該URL是否無限期無效,例如,如果該文件將在計時器上刪除。
兩種簡潔的方法:
1)使用ajax輪詢服務器。 每隔10秒或您認為合適的間隔檢查完成情況。 例如,當腳本正在處理時,它會寫入文件或數據庫,無論它指示完成百分比以及以某種方式識別進程(如果您有多個腳本同時運行,您將想知道哪個是鮑勃的,哪個是蘇茲的)。
2)禁用輸出緩沖並將輸出流式傳輸到客戶端。 這比第一個選項簡單。 基本上,運行腳本並在處理時,您可以輸出javascript代碼來說明,更新進度指示器。 您需要禁用輸出緩沖,或手動刷新緩沖區,否則您的客戶端可能不會立即收到輸出(指示器更新可能僅在客戶端達到100%時才可見)。 Google如何在您正在運行的任何設置(例如PHP,Django)上執行此操作。
你想要什么是可能的,但它確實是3個問題。
第一個問題是,如何從PHP創建新文件。 我真的不能回答這個問題。 您需要做什么,可能取決於您嘗試創建的文件類型和原因。
第二個問題是,如何讓用戶知道這種情況正在發生,第三個問題是如何重定向到新頁面。
就個人而言,我認為獲勝的最短路徑可能是讓您的客戶端javascript向服務器頁面或創建新內容的CGI模塊發出AJAX請求。
作為Web開發的新手,最簡單的方法是查看jQuery及其AJAX功能。 那里的包裝使得上述操作非常容易。 當然,您也可以使用任何其他主要的JavaScript框架或直接的javascript。
以供參考:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.