Flask: how can a client download a created JSON file - json

I have a JSON string that I am reading from a web form that I would like to create a temporary file out of and allow the file to be downloaded to the local client machine. In other words my app.route reads the string, writes the string to a file and then sends the file to the client:
#app.route('/sendFile', methods=['POST'])
def sendFile():
content = str(request.form['jsonval'])
with open('zones.geojson', 'w') as f:
f.write(content)
return send_file(f)
What's the best way to make this work?

From this answer all that is needed is to specify the correct Response header:
From flask import Response
#app.route('/sendFile', methods=['POST'])
def sendFile():
content = str(request.form['jsonval'])
return Response(content,
mimetype='application/json',
headers={'Content-Disposition':'attachment;filename=zones.geojson'})

Related

How would I get access to a file I don't know the name of

I might describe this very poorly but here we go. What I am doing is creating a file with the user id from discord. In a different function, I want to access the file but I don't know the name of it
import json
import discord
#client.command()
async def function1(ctx):
test1 = 3
author = ctx.message.author.mention
await ctx.send(author)
with open(author+'.txt', 'w+') as outfile:
json.dump(test1, outfile)
#client.command()
async def function2(ctx):
with open(author+'.txt') as infile: #The "author+'.txt'" does not work because it does not know what author is.
test2 = json.load(infile)
await ctx.send(test2)
How would I get around this and access this file? I have an idea, I could save the author and then call it in function two. This would not work because there are many people using the bot. Am I on the right track? Thanks for the help in advance.

Create Button on existing model to download CSV data

I have a function that generates a CSV report for survey.surveys to my employer's liking and I need a way to download that data. The issue I'm having is to get a button on the page to actually download the data, I've tried adding a controller but when I go to it, it says 404.
I'm using Odoo 13
Here's the controller I tried, but when i go to it, it returns a 404. Yes i checked my __init__.py for both my module and controllers folder
class MyExport(http.Controller):
#http.route(['/my_module/export/certs'], type='http', auth='user', methods=['GET'], website=True)
def csv_download(self, **kw):
csv = http.request.env['survey.survey'].generate_cert_report()
filename = 'Certification Report - {}.csv'.format(
datetime.now().strftime("%m/%d/%Y"))
headers = [
('Content-Type', 'application/octet-stream'),
('Content-Disposition', 'attachment; filename="%s"' % (filename))
]
return request.make_response(csv, headers=headers)

YouTube analytics API rows empty

I know this question has been answered before, but I seem to have a different problem. Up until a few days ago, my querying of YouTube never had a problem. Now, however, every time I query data on any video the rows of actual video data come back as a single empty array.
Here is my code in full:
# -*- coding: utf-8 -*-
import os
import google.oauth2.credentials
import google_auth_oauthlib.flow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from google_auth_oauthlib.flow import InstalledAppFlow
import pandas as pd
import csv
SCOPES = ['https://www.googleapis.com/auth/yt-analytics.readonly']
API_SERVICE_NAME = 'youtubeAnalytics'
API_VERSION = 'v2'
CLIENT_SECRETS_FILE = 'CLIENT_SECRET_FILE.json'
def get_service():
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
credentials = flow.run_console()
#builds api-specific service
return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
def execute_api_request(client_library_function, **kwargs):
response = client_library_function(
**kwargs
).execute()
print(response)
columnHeaders = []
# create a CSV output for video list
csvFile = open('video_result.csv','w')
csvWriter = csv.writer(csvFile)
csvWriter.writerow(["views","comments","likes","estimatedMinutesWatched","averageViewDuration"])
if __name__ == '__main__':
# Disable OAuthlib's HTTPs verification when running locally.
# *DO NOT* leave this option enabled when running in production.
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
youtubeAnalytics = get_service()
execute_api_request(
youtubeAnalytics.reports().query,
ids='channel==UCU_N4jDOub9J8splDAPiMWA',
#needs to be of form YYYY-MM-DD
startDate='2018-01-01',
endDate='2018-05-01',
metrics='views,comments,likes,dislikes,estimatedMinutesWatched,averageViewDuration',
dimensions='day',
filters='video==ZeY6BKqIZGk,YKFWUX9w4eY,bDPdrWS-YUc'
)
You can see in the Reports: Query front page that you need to use the new scope:
https://www.googleapis.com/auth/youtube.readonly
instead of the old one:
https://www.googleapis.com/auth/yt-analytics.readonly
After changing the scope, perform a re-authentication (delete the old credentials) for the new scope to take effect.
This is also confirmed in this forum.
One of the mishaps may come if you chose wrong account/accounts during oAuth2 authorisation. For instance you may have to get "account" on the firs screen but then on second screen (during authorisation) use "brand account" and not the main account from the first step that also is on a list for second step.
I got the same problem and replacing with https://www.googleapis.com/auth/youtube.readonly scope doesn't work.
(Even making requests in the API webpage, it returns empty rows.)
Instead, using the https://www.googleapis.com/auth/youtube scope works fine in my case.

HTML File link - force download always

I have a Django view that renders a list of uploaded files, and the user can click on them to begin the download.
When the project was deployed, we found there's one file that browsers open instead of download it. It seems related to the .dxf extension.
This is how the link is created:
...
As a result:
http://localhost:8003/media/folder/whatever.dxf
So, why the same browser behaves differently? if I run it on localhost, then it downloads the file. But accessing the real server, it'd open it. Can I prevent the server to open them in browsers?
You can try adding new Django view that will handle download.
urls.py
from django.conf.urls import url
import views
urlpatterns = [
url(r'^download/$', views.DownloadView.as_view(), name='download')
]
views.py
import urllib
from django.http import HttpResponse
from django.views.generic.base import View
class DownloadView(View):
def get(self, request):
location = request.GET.get('location')
file = urllib.urlretrieve(location)
contents = open(file[0], 'r')
content_type = '%s' % file[1].type
response = HttpResponse(contents, content_type=content_type)
response['Content-Disposition'] = 'attachment; filename="%s"' % location.split('/')[-1]
return response
template.html
...

Django, handle Response from external server

The question is how can I handle HttpResponce from an external server?
The idea is that I send json data to an external server
(e.g search data {'keyword': keyword, 'limit':limit, 'db':db})
response = requests.post(url, json = userupload, headers=headers)
after that I'm getting response from the server with json data
return HttpResponse(response)
It is on the screen, but as you can understand not in a good view for user...
So how can I add this data in a proper html table for example? (the best option is if I can print it out on the same page)
If I understand you correctly, you want to render the output of the post request which is in JSON format into a HTML file.
To do this, pass the json-encoded object from the view to the template:
views.py:
import json
def myview(request):
obj = requests.post(url, json = userupload, headers=headers)
return render_to_response("template.html", {"obj_as_json": json.dumps(obj.json())})
template.html:
<html>
<head>
<script type="text/javascript">
var obj = {{ obj_as_json }};
</script>
</head>
...
</html>
https://docs.djangoproject.com/en/1.9/intro/tutorial03/
In the django tutorial you learn how to render a response with html and context data.
If you are using requests you can do like:
response = requests.api.post(...
context = json.loads(response.json())
return render(request, 'index.html', context)
One of the big advanteges with json api's is that you can access it asynchronously with javascript. You should look in to that if you just want to render a response without calling your database to manipulate data from the json api.