I work with the Python flask, HTML, and local JSON file to display the JSON data from a local JSON file in the HTML. Once the flask reads a local JSON file, it is sent to index.html with jsonify. After then, using that data I want to display the information.
I can the JSON data in the flask side, but have struggled with displaying it in the HTML. Could you let me know what I missed?
flask code
import os
from flask import Flask, render_template, abort, url_for, json, jsonify
import json
import html
app = Flask(__name__)
# read file
with open('./data/file.json', 'r') as myfile:
data = myfile.read()
#app.route("/")
def index():
return render_template('index.html', title="page", jsonfile=jsonify(data))
app.run(host='localhost', debug=True)
index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="UTF-8" />
<title>House</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
crossorigin="anonymous"
/>
<script>
var jsonfile ={{jsonfile}};
</script>
</head>
<body>
<div class="container">
{{jsonfile}}
</div>
</body>
</html>
Your issue is the use of the jsonify method. If you read the documentation of jsonify it returns a Response object and not a string. So you will get something like this for jsonify(data)
<Response 2347 bytes [200 OK]>
You could remove jsonify and use json.dumps instead, as follows:
#app.route("/")
def index():
return render_template('index.html', title="page", jsonfile=json.dumps(data))
This works for me.
What Rahul P is correct and the reason you are getting unexpected results is because you are using jsonify when you should be using json.dumps(data).
If you want you want to use the json inside of the script tag can I suggest making the following changes?
app.py
import os
from flask import Flask, render_template, abort, url_for
import json
import html
app = Flask(__name__)
# read file
with open('./data/file.json', 'r') as myfile:
data = myfile.read()
#app.route("/")
def index():
return render_template('index.html', title="page", jsonfile=json.dumps(data))
if __name__ == '__main__':
app.run(host='localhost', debug=True)
index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="UTF-8" />
<title>House</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
crossorigin="anonymous"
/>
</head>
<body>
<div class="container"></div>
<script>
const jsonfile = JSON.parse({{jsonfile|tojson}});
console.log(jsonfile);
document.querySelector(".container").innerHTML = JSON.stringify(jsonfile, null, 2);
</script>
</body>
</html>
Related
I have a problem with my code.
I'm trying to create a docx generator with docxtpl and flask, but I can't get it to work. My intention is to download the file generated with the information acquired from the form.
Here is the code in app.py:
from docxtpl import DocxTemplate
from flask import Flask, render_template, request, redirect, send_from_directory, url_for, send_file
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST',])
def index():
# generate_report()
return render_template('index.html')
#app.route('/', methods=['GET', 'POST']) # When the user click to the "submit" button
def download_file():
if request.method == 'POST':
result = request.form
doc = DocxTemplate("templates/template_procuracao.docx")
context = {
'autor':result['autor'],
'nacionalidade':result['nacionalidade'],
'estadocivil':result['estadocivil'],
'identidade':result['identidade'],
}
doc.render(context)
doc.save()
return send_file('templates/output',
attachment_filename='teste.docx',
as_attachment=True)
if __name__ == '__main__':
app.run()
Here is the code in index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="{{ url_for('index') }}" method="post">
<input type="text" id="autor" name="autor" placeholder="AUTOR"><br>
<input type="text" id="nacionalidade" name="nacionalidade" placeholder="NACIONALIDADE"><br>
<input type="text" id="estadocivil" name="estadocivil" placeholder="ESTADOCIVIL"><br>
<input type="text" id="identidade" name="identidade" placeholder="IDENTIDADE"><br>
Submit
</form>
</body>
</html>
after clicking the submit button nothing happens.
127.0.0.1 - - [06/Apr/2022 21:00:23] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [06/Apr/2022 21:00:33] "GET / HTTP/1.1" 200 -
When you save your document you need to save it in memory to essentially create a file to send (unless you want to save it as a file and then load it again). You are also trying to send a file 'templates/output' and not the document you'd created.
from io import BytesIO
...
def download_file():
...
docx_in_memory = BytesIO()
doc.render(context)
doc.save(docx_in_memory)
docx_in_memory.seek(0)
return send_file(
docx_in_memory,
attachment_filename='teste.docx',
as_attachment=True)
Whenever I print out the scraped data in the terminal it shows the scraped data fine, but whenever I try serve it using Python Flask, the HTML template that I'm using does not render the data in the web browser. If you could help me fix this code.
Python (Flask) file:
from flask import Flask, render_template
from bs4 import BeautifulSoup as BS
import requests
src = requests.get('https://webscraper.netlify.app/').text
scraper = BS(src, 'lxml')
# head = scraper.find('main').select_one('article:nth-of-type(4)').div.text
# author = scraper.find('main').select_one('p').text
head = scraper.body.header.h1.text
snd_author = scraper.body.main.select_one('article:nth-of-type(2)').p.text
fst_article = scraper.body.main.article.div
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html', **locals())
app.run(debug=True)
HTML (view) file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=2.0"/>
<title>Python Flask Web Scraper</title>
</head>
<body>
<!-- Python Flask Variables go here: -->
<h1> {{ head }} </h1>
<p>{{ snd_author }}</p>
<article>{{ fst_article }}</article>
</body>
</html>
You should instead use:
return render_template('index.html', head=head, snd_author=snd_author, fst_article=fst_article)
I am trying load data into my flask page, and console log it, however I keep getting the below error
VM165:1 Uncaught ReferenceError: data is not defined
at <anonymous>:1:13
These are the code snippets from my .py and .html
import os
from flask import Flask, render_template, jsonify, request, redirect
import json
app = Flask(__name__)
#app.route("/")
def home():
json_file = open("/Users/-------/Documents/GitHub/Geospatial-Opportunities-for-Supermarkets/supermarket_locations/longos_locations.json", "r", encoding ="utf-8")
data = json.load(json_file)
json_file.close
return render_template("index.html", data = data)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Supermarkets in Toronto</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.0-rc.3/dist/leaflet.css" />
<link rel="stylesheet" type="text/css" href="static/css/style.css">
<script> var data = '{{data}}'; </script>
</head>
Looks like I had 2 index.html files and I was using the wrong one
I have a basic HTML file which looks like this:
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome!</h1>
</body>
</html>
I am receiving the file in python and storing it as a string. I want to know, is there a way I can write this out to a web browser?
The file is on my computer, so my goal is not to save it as an html file and then execute it, but rather execute this from within python to the browser.
I know that with JavaScript I can use Document.write() to inject content to a webpage, but that is already being done in the browser. I want to achieve something similar.
You can use flask, a simple Python web framework, to serve the string:
Using flask (pip install flask):
import flask
app = flask.Flask(__name__)
s = """
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome!</h1>
</body>
</html>
"""
#app.route('/')
def home():
return s
if __name__ == '__main__':
app.debug = True
app.run()
Now, can you navigate to 127:0.0.1:5000 or the equivalent IP and port specified when the app is run.
You could do the following:
html = """<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome!</h1>
</body>
</html>"""
with open('html_file.html', 'w') as f:
f.write(html)
import webbrowser, os
webbrowser.open('file://' + os.path.realpath('html_file.html'))
This question already has answers here:
Link to Flask static files with url_for
(2 answers)
Closed 6 years ago.
I reduced the code for this to, I think, minimum while trying to get it to work:
The python:
#!/usr/bin/env python
from functools import wraps
from flask import Flask, render_template, session, request, redirect, url_for
from flask_socketio import SocketIO, emit, join_room, leave_room, \
close_room, rooms, disconnect
async_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)
#app.route('/')
def index():
return render_template('index_test.html')
if __name__ == '__main__':
socketio.run(app, debug=True)
The html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="{{ url_for('index') }}bulboff.gif"/>
<p>"{{ url_for('index') }}" <p>
</body>
</html>
The image is in the static folder.
And it gives this error:
"GET /bulboff.gif HTTP/1.1" 404
when the page is accessed.
I've tried several things like setting the Flask default paths, without the url_for, etc, but, still no image.
What am I missing?
According to the flask document:
To generate URLs for static files, use the special static endpoint
name:
url_for('static', filename='style.css')
The file has to be stored on the filesystem as static/style.css.
In your case, use <img src="{{ url_for('static', filename='bulboff.gif') }}">
If You put image in the static folder, You should use something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="{{ url_for('index') }}static/bulboff.gif"/>
<p>"{{ url_for('index') }}" <p>
</body>
</html>
Alternatively, You could change application's code and add following:
#app.route('/bulboff.gif')
def bulboff():
return open('static/bulboff.gif').read()
<img src="{{url_for('static', filename='bulboff.gif')}}" />
Try that. Your filename could be a path from the static folder. So like if you have filename = \some\path\img.png it will look for the img in static\some\ath\img