So I have this dummy json file which has id, title, subtitle, and post, using npoint here's the link to json data: https://api.npoint.io/5abcca6f4e39b4955965, and what i'm trying to do was display the title and subtitle of the 3 posts from the dummy json file. I used jinja multi line to loop through the post within the html. But I keep getting an error, I've tried printing out the data to console and it worked just fine.
here's my server.py :
from flask import Flask
from flask import render_template #grabs your html page to render
import random
import requests
from datetime import datetime
app = Flask(__name__)
#app.route('/')
def hello():
return "<h1> Welcome! </h1>"
#app.route('/blog')
def blog():
blog_url = "https://api.npoint.io/5abcca6f4e39b4955965"
response = requests.get(url=blog_url)
data = response.json()
return render_template("blog.html", posts=data)
if __name__ == "__main__":
app.run(debug=True)
and heres my blog.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog</title>
</head>
<body>
{% for blog_posts in posts: %}
<h1>{{ blog_posts["title] }}</h1>
<h2>{{ blog_posts["subtitle"] }}</h2>
{% endfor %}
</body>
</html>
Error :
File "C:\Users\Vimalan\PycharmProjects\100CODECHALLENGE\Webdev\Blog\templates\blog.html", line 10, in template
<h2>{{ blog_posts["subtitle"] }}</h2>
jinja2.exceptions.TemplateSyntaxError: expected token ',', got 'subtitle'
any suggestions?
Related
I use Python flask for my web application. the application provide a CSV file to download. CSV file is the response in below code block. Also I need to send a variable to html template. How can I have two return value?
#application.route("/log_analysis", methods=['POST'])
def get_response():
output='The result of your query : '+str(i-1)+' . The full report is downloaded automatically.'
cw.writerows(csv_rows)
response = make_response(si.getvalue())
response.headers["Content-Disposition"] = f"attachment; filename={return_file_name}"
response.headers["Content-type"] = "text/csv"
return render_template('base.html',output=output)
return response, 200
The output will be shown in the html but the response in the second return doesn't work.
After reading your question, I think what you are looking for is something like flash messages. The variable content you are passing in, is just text and used to display a message.
Flash messages
You'll need to set this up in your base.html or whatever template you are rendering.
Template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link href="{{ url_for('static', filename='css/main.css')}}" rel="stylesheet">
</head>
<body>
<main>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</main>
</body>
</html>
from flask import render_template, url_for, flash, redirect
#application.route("/log_analysis", methods=['POST'])
def get_response():
output=f'The result of your query : {i-1} . The full report is downloaded automatically.'
cw.writerows(csv_rows)
response = make_response(si.getvalue())
response.headers["Content-Disposition"] = f"attachment; filename={return_file_name}"
response.headers["Content-type"] = "text/csv"
flash(output,'success')
return response, 200
You can also try and do something like alerts in html template
I am getting jinja2.exceptions.UndefinedError: 'btn' is undefined exception while logging to the localhost. The btn is properly defined but still.. Can I plaese get the help as soon as possible. Thank You in Advance
Python code- This code is the Python Code
from flask import Flask, render_template, request, send_file
from flask_sqlalchemy import SQLAlchemy
from send_email import send_email
from sqlalchemy.sql import func
from werkzeug import secure_filename
app=Flask(__name__)
#app.route("/")
def index():
return render_template("index.html")
#app.route("/success", methods=['POST'])
def success():
global file
if request.method=='POST':
file=request.files["file"]
file.save(secure_filename("uploaded" + file.filename))
with open("uploaded"+file.filename,"a") as f :
f.write("This was added later!")
return render_template("index.html", btn="download.html")
#app.route("/download")
def download():
return send_file("uploaded" + file.filename, attatchment_filename="yourfile.csv", as_attatchment=True)
if __name__ == '__main__':
app.debug=True
app.run()
HTML-
Index file - This is the main file
<!DOCTYPE html>
<html lang="en">
<title> Data Collector App</title>
<head>
<link href="../static/main.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Collecting Height</h1>
<h3>Please Fill the Entries to get Population Statistics on Height</h3>
<div class="message">
{{text | safe}}
</div>
<form action="{{url_for('success')}}" method="POST" enctype="multipart/form-data">
<input type="file" name="file" > <br>
<button type="submit">Submit</button>
</form>
{%include btn ignore missing%}
</div>
</body>
</html>
Download file- This is the html file for downloading. After importing the file this html code will create a button in the same index.html page so that I can also downoad the same file
<!DOCTYPE html>
<html lang="en">
<div class="download">
<button class="btn"> Download </button>
</div>
</html>
Was facing the same issue. My workaround was to replace:
{% include btn ignore missing %}
with
{% if btn %}
{% include btn %}
{% endif %}
This should work:
{% include [btn] ignore missing %}
The reason for change is due to a Flask update from the time when that video was created
I'm looping through the list of names and want to put it in html.
The problems is that Jinja doubles the . One with the name value, but the other one is just empty. Why is it happening?
Here is python code
import os
from flask import Flask, session, render_template, request, flash, redirect, url_for
app = Flask(__name__)
app.config['SECRET_KEY'] = "secret"
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Users = ['Bob', 'Nick', 'Alice', 'Brian']
#app.route("/")
def index():
return render_template ("test.html", Users=Users)
if __name__ == '__main__':
app.run(debug=True)
and HTML
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Welcome</title>
</head>
<body>
<p>User list</p>
<ul id="user_list">
{% for name in Users %}
<li>{{ name }}<li>
{% endfor %}
</ul>
</body>
</html>
And here is the output I get.
You just didn't close the < li > tag in you test.html file:
<li>{{ name }}<li>
Am very much new to Flask & Python, so want to understand/clear my concepts. I have a webpage which i created using flask & wtforms. Html page is very simple having just single field & a submit button. I want to call a python script (test.py) itself or python function(pythonfunction()) when submit button is clicked. Also Is there a way from the webpage,whatever i enter , i can pass as an attribute to that python script (test.py)? help appreciated
**app.py**
from flask import Flask , render_template,flash,redirect,url_for,session,logging,request
from wtforms import Form,StringField,TextAreaField,PasswordField,validators,SelectField,TextAreaField
from wtforms.widgets import TextArea
import subprocess
import test
app=Flask(__name__)
#app.route ('/')
def index():
return render_template('home.html')
class testpython(Form):
testenter=StringField('Enter something')
#app.route ('/testpage',methods=['GET','POST'])
def testpage():
form=testpython(request.form)
return render_template('testpage.html',form=form,python=testfunc(testenter))
if __name__ == '__main__':
app.run(debug=True)
**test.py**
def pythonfunctiontest (self):
print data #<something i can print here from that text field in webpage>
return "all good"
**testpage.html**
{% extends 'sec_layout.html'%}
{% block body %}
{% from "includes/_formhelpers.html" import render_field %}
<form method="POST" action ="">
<div class="form-group">
{{render_field(form.testenter,cols="1", rows="5",class_="form-control")}}
</div>
<div class="input-bar-item input-bar-item-btn">
<button class="btn btn-info">Submit</button>
</div>
</form>
{% endif %}
{% endblock%}
sec_layout.html
<!DOCTYPE <!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>MY PAGE-TEST</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body>
{% include 'includes/_navbar.html' %}
<div class= "container">
{% block body %}{% endblock%}
</div>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" </script>
</body>
</html>
The question is very general so I will try and give you a steer and perhaps you might revisit this question later with a little more clarity.
Flask asks a server and renders webpages. I.e. it executes some code on the server and passes it to the client web browser. The client web browser can then execute client side code (i.e. Javascript) as the user is browsing and can pass data back to the server using submit forms (to different Flask routes) or via JavaScript AJAX requests (again to other Flask routes). So if you want to execute python script based on some input you will need a separate route.
Here is a simple example of an index page and a second route that will execute something else:
#app.route('/index')
def index():
""" very basic template render """
return render_template('index.html')
#app.route('/data-submit', methods=["POST"])
def calc():
data = request.form.information.data
# do something with data..
x = data + data
return render_template('new_page.html', x)
========= (index.html)
<html>
<body>
<form action="{{ url_for('app.calc') }}" method="POST">
<input name="information" type='text'>
<button name="submit">
</form>
</body>
</html>
Wrap whatever temp.py is doing in a function.
Place it in the same directory as flask.py. Call import temp in flask.py, then use temp.myfunction().
I want to display my log.txt in my log.html.
For some reason my page is completely blank.
And I dont get to see anything from my file.
Code:
def log():
with open("logs.txt", "r") as f:
content = f.read()
return render_template('log.html', content=content)
HTML LOG TEMPLATE:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Log</title>
<link rel="stylesheet" href="/static/styles/nav.css" />
<link rel="stylesheet" href="/static/styles/basiclayout.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<style>
</style>
<body>
<ul class="nav">
<li ><a href="{{ url_for('hello_world') }}" >Home</a></li>
<li >Notepad</li>
<li >Explorer </li>
<li class="active">Log </li>
<li >Upload </li>
<li >Uploads </li>
<li >Logout</li>
</ul>
<div class="alert">
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
</div>
<pre>{{ content }}</pre>
</body>
</html>
Added my HTML Template now.
return Response(content, mimetype='text/plain')
but really you probably want to use something like logstash...
Maybe it would be better if for the log to read the file backwards in order to access the last log first.
pip3 install file-read-backwards
For example, I will show this code backwards:
In your case, it is necessary to replace app.py with logs.txt
from flask import Flask, render_template
from file_read_backwards import FileReadBackwards
app = Flask(__name__, template_folder="template")
with FileReadBackwards("app.py") as f:
# getting lines by lines starting from the last line up
b_lines = [ row for row in f ]
#app.route('/', methods=["GET", "POST"])
def index():
return render_template('index.html', b_lines=b_lines)
if __name__ == "__main__":
app.run(debug=True)
UPDATE - without libraries
from flask import Flask, render_template
app = Flask(__name__, template_folder="template")
#app.route('/', methods=["GET", "POST"])
def index():
b_lines = [row for row in reversed(list(open("app.py")))]
return render_template('index.html', b_lines=b_lines)
if __name__ == "__main__":
app.run(debug=True)
Put in your log.html:
<br>
Description:
<br>
<textarea id="stackoverflow" name="stackoverflow_review" rows="35" cols="55">
{% for line in b_lines %}
{{ line }}
{% endfor %}
</textarea>
output:
In your case, the latest changes from the logs.txt file will be displayed first.
There are two files one being "file.py" and the respective HTML file being invoked from the templates folder.
import sys
from flask import Flask, render_template, redirect, url_for, request
app = Flask(__name__, template_folder="/root/templates")
def search():
with open("test","r") as file:
content = file.readlines()
print(content)
return render_template("file2.html", content = content)
if __name__ == "__main__":
app.run(debug=True)
File2.html:
Not sure how to attach HTML file. attaching a screen shot . Please refer