我正在运行一个基于Flask的网络服务器,它服务于一个版本化的资源(例如某个版本化程序的安装文件)。我想用新资源为我的HTTP客户端服务,以防它已经没有当前版本。如果有新版本,我希望客户端下载资源并安装它。
我的Flask服务器看起来像这样
import json
import redis
import math
import requests
from flask import Flask,render_template,request
app=Flask(__name__)
@app.route('/version', methods=['GET','POST'])
def getversion():
r_server=redis.Redis("127.0.0.1")
if request.method == 'POST':
jsonobj_recieve=request.data
data=json.loads(jsonobj)
currentversion=r_server.hget('version')
if data == currentversion:
#code to return a 'ok'
else:
#code to return 'not ok' also should send the updated file to the client
else:
return r_server.hget('version')
if __name__ == '__main__':
app.run(
debug=True,
host="127.0.0.1",
port=80
)
我的客户非常基本:
import sys
import json
import requests
url="http://127.0.0.1/version"
jsonobj=json.dumps(str(sys.argv[1]))
print jsonobj
r=requests.post(url,data=jsonobj)
我可能需要重新编码整个客户端,这不是问题,但我真的不知道从哪里开始....
答案 0 :(得分:2)
如果您想仅允许下载应用程序以防万一,客户端还没有它,可以使用以下设计:
etag
标头。这通常包含一些字符串,用于描述您希望从该URL获取的资源的唯一状态。在您的情况下,它可能是您的应用程序的当前版本号。306 - Not Modified
,以防您的客户端和服务器共享相同版本的资源。如果它不同,您只需提供资源的内容并使用它。您的资源还应在etag
当前版本的资源中表示,您的客户应注意它,或从其他来源(例如从下载的文件中)找到新的版本名称。此设计遵循HTTP原则。
etag
这是专注于展示原则,你应该详细说明提供资源的真实内容。
from flask import Flask, Response, request
import werkzeug.exceptions
app = Flask(__name__)
class NotModified(werkzeug.exceptions.HTTPException):
code = 304
def get_response(self, environment):
return Response(status=304)
@app.route('/download/app')
def downloadapp():
currver = "1.0"
if request.if_none_match and currver in request.if_none_match:
raise NotModified
def generate():
yield "app_file_part 1"
yield "app_file_part 2"
yield "app_file_part 3"
return Response(generate(), headers={"etag": currver})
if __name__ == '__main__':
app.run(debug=True)
import requests
ver = "1.0"
url = "http://localhost:5000/download/app"
req = requests.get(url, headers={"If-None-Match": ver})
if req.status_code == 200:
print "new content of resource", req.content
new_ver = req.headers["etag"]
else:
print "resource did not change since last time"
假设资源是静态文件,只在某个时间更新,您应该可以配置您的Web服务器,例如NGINX,用于提供该资源并在您的配置中声明etag
标头的显式值到版本字符串。
请注意,由于未提出要求,此处未详细说明此替代解决方案(未经测试)。
客户端实现不会被修改(这里它按照HTTP概念回报设计)。
答案 1 :(得分:1)
有多种方法可以实现这一点,但因为这是一个Flask应用程序,这里有一个使用HTTP。
如果版本没问题,只需返回相关的状态代码,例如200 OK
。如果有必要,您可以在正文中添加JSON响应。如果你返回一个带烧瓶的字符串,状态代码将是200 OK,你可以在你的客户端检查它。
如果版本不同,请返回文件所在的URL。客户必须
下载文件。使用requests
非常简单。以下是streaming requests下载文件的典型示例:
def get(url, chunk_size=1024):
""" Download a file in chunks of n bytes """
fn = url.split("/")[-1] # if you're url is complicated, use urlparse.
stream = requests.get(url, stream=True)
with open(fn, "wb") as local:
for chunk in stream.iter_content(chunk_size=chunk_size):
if chunk:
f.write(chunk)
return fn
非常简化。如果您的文件不是静态的并且无法在服务器上存活(可能不应该像软件更新补丁那样),那么您将不得不想办法从数据库中获取文件或者动态生成文件。