-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathupdate_api.py
More file actions
129 lines (104 loc) · 3.57 KB
/
update_api.py
File metadata and controls
129 lines (104 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from particle_api import *
from api_version import version as api_version
import time
import json
import uuid
import urllib
import os
from flask import Flask, request, session, g, url_for, Response, request, jsonify
# create our app
app = Flask(__name__)
# enable CORS on everything
from flask_cors import CORS
CORS(app)
# helper function to get the current time in millis()
current_milli_time = lambda: int(round(time.time() * 1000))
#default return type to JSON, since this is really what we use
class JSONResponse(Response):
default_mimetype = 'application/json'
# will return 400 when called
@app.errorhandler(400)
def bad_request(error=None):
"""
Handle 400 cases
:param error: String, the error to return
:return:
"""
message = {
'status': 400,
'error': 'BadRequest: ' + request.url,
"message": error if error is not None else '',
}
resp = jsonify(message)
resp.status_code = 400
return resp
# will return 500 when called
@app.errorhandler(500)
def internal_error(error=None):
"""
Handle 500 cases
:param error: String, the error to return
:return:
"""
message = {
'status': 500,
'error': 'ServerError: ' + request.url,
"message": error if error is not None else '',
}
resp = jsonify(message)
resp.status_code = 500
return resp
# Routes
# ------------------------------------------------------------------------------
@app.route('/update/version')
def version():
return json.dumps({'version': api_version})
@app.route('/update', methods=['POST'])
def update():
try:
params = get_payload(request)
device = params['device']
access_token = params['accessToken']
urls = params["files"]
env = "staging" if 'HTTP_ORIGIN' in request.environ and request.environ['HTTP_ORIGIN'] is not None and "staging.particle.io" in request.environ['HTTP_ORIGIN'] else "production"
except:
return bad_request("Invalid parameters")
try:
id = str(uuid.uuid4())
dir = create_dir(id)
for url in urls:
# download file
local_file = dir+'/'+filename_from_url(url)
urllib.urlretrieve(url, local_file)
#call particle flash for this file and device
particle = ParticleAPI(env)
started = particle.particle_flash(device, local_file, access_token)
if not started:
raise Exception("Unable to start update")
os.remove(local_file)
# finally, delete the directory
os.rmdir(dir)
except Exception as ex:
return internal_error(ex.message)
return JSONResponse(json.dumps({"uuid": id}))
# Helper functions
# ------------------------------------------------------------------------------
def get_payload(request):
if request.method == 'POST':
# if POST, the data may be in the data array as json or form, depending on how it was handed in
# Postman seems to hand it in as json while others seem to hand it in through form data
data = request.get_json(force=True, silent=True)
return data if data is not None else request.form
else:
return request.args
def create_dir(id):
path = '/tmp/'+id
if not os.path.exists(path):
os.makedirs(path)
return path
def filename_from_url(url):
return url.split("/")[-1]
# Main
# ------------------------------------------------------------------------------
if __name__ == '__main__':
app.run()