google 云:以 CSV 格式下载
google cloud: downloading as an CSV
我有一个下载按钮,应该 return 用户 CSV。下面的代码:
class StartCSVHandler(ThreeScaleResourceHandler):
""" Starts generating a user's CSV file """
allowed_methods = ('new',)
requires_input = False
def post(self, *args, **kwargs):
user = self.current_user()
if not user:
self.abort(401, detail=ERROR_NOT_AUTHORIZED)
task_url = '/jobs/users/%s/data/csv' % user.key()
taskqueue.add(url=task_url, queue_name='users')
return {}
def generate_data_from_query(query, user, format, handler, filename, mission=None):
batch_size = 500
cursor = None
spottings = []
count = 0
mime_type = 'text/csv' if format == CSV_FORMAT else 'text/xml'
timestamp = '%0.6f' % time.time()
gcs_filename_template = '/{bucket}/{user}/{timestamp}/{filename}'
from global_config import config
gcs_filename = gcs_filename_template.format(
bucket='project-noah-backups',
# bucket=config['cloudstorage']['export_files_bucket'],
user=str(user.key()),
timestamp=timestamp,
filename=filename
)
logging.debug(str(user.key()))
f = cloudstorage.open(gcs_filename, mode='w', content_type=mime_type)
# blobstore_file_name = files.blobstore.create(mime_type=mime_type, _blobinfo_uploaded_filename=filename.encode('utf-8'))
while True:
if format == CSV_FORMAT:
writer = utils.UnicodeWriter(f)
if count == 0:
writer.writerow(csv_display_names)
elif format == KML_FORMAT and count == 0:
f.write(template.render('spotting_export_pre.kml', {}))
if cursor:
query.with_cursor(cursor)
spottings = query.fetch(batch_size)
if format == CSV_FORMAT:
dicts = [s.as_dict() for s in spottings]
logging.debug(dicts)
for spotting_dict in dicts:
writer.writerow([spotting_dict[k] for k in csv_keys])
elif format == KML_FORMAT:
output = template.render('spotting_export_mid.kml', {'spottings' : spottings, 'server_url' : utils.server_url(handler.request)})
f.write(output.encode('utf-8'))
cursor = query.cursor()
logging.info('written spottings %d to %d' % (count, count + len(spottings)))
count += len(spottings)
if not mission:
push_to_beacon_user(user, {'format':format,'progress':count})
else:
push_to_beacon_user_mission(user, mission, {'format':format,'progress':count})
if len(spottings) < batch_size:
break
if format == KML_FORMAT:
f.write(template.render('spotting_export_post.kml', {}))
blob_key = BlobKey(blobstore.create_gs_key(u'/gs' + gcs_filename))
logging.debug(blob_key)
return blob_key
def generate_data_from_user_spottings(user, format, handler):
filename = u'My-Spottings.%s' % format
# query = user.mySpottings
query = user.mySpottings
logging.debug(query)
return generate_data_from_query(query, user, format, handler, filename)
class GenerateUserDataHandler(NoahHandler):
def post(self, user_key=None, format=None):
if not user_key:
return
user = NoahUser.get(user_key)
if not user:
return
if format not in (CSV_FORMAT, KML_FORMAT):
return
blob_key = generate_data_from_user_spottings(user, format, self)
user = NoahUser.get(user_key)
if format == CSV_FORMAT:
if user.csv:
user.csv.delete()
user.csv = blob_key
user.put()
elif format == KML_FORMAT:
if user.kml:
user.kml.delete()
user.kml = blob_key
user.put()
logging.debug(user.recent_spottings)
logging.debug(str(blob_key))
push_to_beacon_user(user, {'format': format,'url':'/data?key=%s' % str(blob_key)})
class ThreeScaleResourceHandler(ResourceHandler):
@three_scale_authenticate
def get(self, *args, **kwargs):
super(ThreeScaleResourceHandler, self).get(*args, **kwargs)
@three_scale_authenticate
def post(self, *args, **kwargs):
super(ThreeScaleResourceHandler, self).post(*args, **kwargs)
@three_scale_authenticate
def put(self, *args, **kwargs):
super(ThreeScaleResourceHandler, self).put(*args, **kwargs)
@three_scale_authenticate
def delete(self, *args, **kwargs):
super(ThreeScaleResourceHandler, self).delete(*args, **kwargs)
这应该以 CSV 格式下载用户数据。我遇到的问题是双重的;首先,它生成的终点是'/api/v1/users/me/data/csv'
,访问它时,我收到以下错误
{"error": {"title": "Unauthorized", "status": 401, "message": "You are not authorized to perform that action. Please use the api_key parameter with your registered key."}}
其次,它提供给用户保存的link找不到:
http://localhost:8080/data?key=encoded_gs_file:cHJvamVjdC1ub2FoLWJhY2t1cHMvYWdoa1pYWi1UbTl1WlhJVkN4SUlUbTloYUZWelpYSVlnSUNBZ0lDQWdBb00vMTU4MTAxODk3My4wODgyODEvTXktU3BvdHRpbmdzLmNzdg==
我不完全确定我需要更正什么。
firstly, the end point that this generates is '/api/v1/users/me/data/csv' and when visiting it, i receive the following error: {"error": {"title": "Unauthorized", "status": 401, "message": "You are not authorized to perform that action. Please use the api_key parameter with your registered key."}}
您的代码片段中的哪个处理程序处理 /api/v1/users/me/data/csv
?是StartCSVHandler
吗?你确定它不是因为这条线而被抛出的吗? self.abort(401, detail=ERROR_NOT_AUTHORIZED)
Secondly, the link it provides for the user to save cannot be found: http://localhost:8080/data?key=encoded_gs_file:cHJvamVjdC1ub2FoLWJhY2t1cHMvYWdoa1pYWi1UbTl1WlhJVkN4SUlUbTloYUZWelpYSVlnSUNBZ0lDQWdBb00vMTU4MTAxODk3My4wODgyODEvTXktU3BvdHRpbmdzLmNzdg==
什么方式?就像你试图在你的机器上找到文件或者这个 link 抛出 404?
在您的本地主机上,可以在此处找到 encoded_gs_file
个文件:http://localhost:8000/blobstore
如果是 404,那么 /data
的处理程序会做什么?它看起来不像在您的代码片段中
我有一个下载按钮,应该 return 用户 CSV。下面的代码:
class StartCSVHandler(ThreeScaleResourceHandler):
""" Starts generating a user's CSV file """
allowed_methods = ('new',)
requires_input = False
def post(self, *args, **kwargs):
user = self.current_user()
if not user:
self.abort(401, detail=ERROR_NOT_AUTHORIZED)
task_url = '/jobs/users/%s/data/csv' % user.key()
taskqueue.add(url=task_url, queue_name='users')
return {}
def generate_data_from_query(query, user, format, handler, filename, mission=None):
batch_size = 500
cursor = None
spottings = []
count = 0
mime_type = 'text/csv' if format == CSV_FORMAT else 'text/xml'
timestamp = '%0.6f' % time.time()
gcs_filename_template = '/{bucket}/{user}/{timestamp}/{filename}'
from global_config import config
gcs_filename = gcs_filename_template.format(
bucket='project-noah-backups',
# bucket=config['cloudstorage']['export_files_bucket'],
user=str(user.key()),
timestamp=timestamp,
filename=filename
)
logging.debug(str(user.key()))
f = cloudstorage.open(gcs_filename, mode='w', content_type=mime_type)
# blobstore_file_name = files.blobstore.create(mime_type=mime_type, _blobinfo_uploaded_filename=filename.encode('utf-8'))
while True:
if format == CSV_FORMAT:
writer = utils.UnicodeWriter(f)
if count == 0:
writer.writerow(csv_display_names)
elif format == KML_FORMAT and count == 0:
f.write(template.render('spotting_export_pre.kml', {}))
if cursor:
query.with_cursor(cursor)
spottings = query.fetch(batch_size)
if format == CSV_FORMAT:
dicts = [s.as_dict() for s in spottings]
logging.debug(dicts)
for spotting_dict in dicts:
writer.writerow([spotting_dict[k] for k in csv_keys])
elif format == KML_FORMAT:
output = template.render('spotting_export_mid.kml', {'spottings' : spottings, 'server_url' : utils.server_url(handler.request)})
f.write(output.encode('utf-8'))
cursor = query.cursor()
logging.info('written spottings %d to %d' % (count, count + len(spottings)))
count += len(spottings)
if not mission:
push_to_beacon_user(user, {'format':format,'progress':count})
else:
push_to_beacon_user_mission(user, mission, {'format':format,'progress':count})
if len(spottings) < batch_size:
break
if format == KML_FORMAT:
f.write(template.render('spotting_export_post.kml', {}))
blob_key = BlobKey(blobstore.create_gs_key(u'/gs' + gcs_filename))
logging.debug(blob_key)
return blob_key
def generate_data_from_user_spottings(user, format, handler):
filename = u'My-Spottings.%s' % format
# query = user.mySpottings
query = user.mySpottings
logging.debug(query)
return generate_data_from_query(query, user, format, handler, filename)
class GenerateUserDataHandler(NoahHandler):
def post(self, user_key=None, format=None):
if not user_key:
return
user = NoahUser.get(user_key)
if not user:
return
if format not in (CSV_FORMAT, KML_FORMAT):
return
blob_key = generate_data_from_user_spottings(user, format, self)
user = NoahUser.get(user_key)
if format == CSV_FORMAT:
if user.csv:
user.csv.delete()
user.csv = blob_key
user.put()
elif format == KML_FORMAT:
if user.kml:
user.kml.delete()
user.kml = blob_key
user.put()
logging.debug(user.recent_spottings)
logging.debug(str(blob_key))
push_to_beacon_user(user, {'format': format,'url':'/data?key=%s' % str(blob_key)})
class ThreeScaleResourceHandler(ResourceHandler):
@three_scale_authenticate
def get(self, *args, **kwargs):
super(ThreeScaleResourceHandler, self).get(*args, **kwargs)
@three_scale_authenticate
def post(self, *args, **kwargs):
super(ThreeScaleResourceHandler, self).post(*args, **kwargs)
@three_scale_authenticate
def put(self, *args, **kwargs):
super(ThreeScaleResourceHandler, self).put(*args, **kwargs)
@three_scale_authenticate
def delete(self, *args, **kwargs):
super(ThreeScaleResourceHandler, self).delete(*args, **kwargs)
这应该以 CSV 格式下载用户数据。我遇到的问题是双重的;首先,它生成的终点是'/api/v1/users/me/data/csv'
,访问它时,我收到以下错误
{"error": {"title": "Unauthorized", "status": 401, "message": "You are not authorized to perform that action. Please use the api_key parameter with your registered key."}}
其次,它提供给用户保存的link找不到:
http://localhost:8080/data?key=encoded_gs_file:cHJvamVjdC1ub2FoLWJhY2t1cHMvYWdoa1pYWi1UbTl1WlhJVkN4SUlUbTloYUZWelpYSVlnSUNBZ0lDQWdBb00vMTU4MTAxODk3My4wODgyODEvTXktU3BvdHRpbmdzLmNzdg==
我不完全确定我需要更正什么。
firstly, the end point that this generates is '/api/v1/users/me/data/csv' and when visiting it, i receive the following error:
{"error": {"title": "Unauthorized", "status": 401, "message": "You are not authorized to perform that action. Please use the api_key parameter with your registered key."}}
您的代码片段中的哪个处理程序处理 /api/v1/users/me/data/csv
?是StartCSVHandler
吗?你确定它不是因为这条线而被抛出的吗? self.abort(401, detail=ERROR_NOT_AUTHORIZED)
Secondly, the link it provides for the user to save cannot be found:
http://localhost:8080/data?key=encoded_gs_file:cHJvamVjdC1ub2FoLWJhY2t1cHMvYWdoa1pYWi1UbTl1WlhJVkN4SUlUbTloYUZWelpYSVlnSUNBZ0lDQWdBb00vMTU4MTAxODk3My4wODgyODEvTXktU3BvdHRpbmdzLmNzdg==
什么方式?就像你试图在你的机器上找到文件或者这个 link 抛出 404?
在您的本地主机上,可以在此处找到 encoded_gs_file
个文件:http://localhost:8000/blobstore
如果是 404,那么 /data
的处理程序会做什么?它看起来不像在您的代码片段中