Internal Server Error when trying to run flask - python

I am trying to create a website with a web form in it using flask, but I keep getting an Internal Server error, despite getting no error when I run it in the console
Here is my code:
__init.py
from flask import Flask, render_template
from forms import TestForm
app = Flask(__name__)
app.config.from_pyfile('config.py')
#app.route('/')
def homepage():
return render_template("main.html", form=TestForm())
if __name__ == "__main__":
app.run(debug=True)
forms.py
from flask_wtf import Form
from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired
class TestForm(Form):
test_form = StringField('test_form', validators=[DataRequired()])
config.py
WTF_CSRF_ENABLED = True
SECRET_KEY = '<super-secret>'
main.html
<DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<meta name="viewport" content="width=device-width"
initial=scale=1/>
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='favicon.ico') }}" rel="shortcut icon">
</head>
<h2>Hello, this site is meant to test my fill_web_form.py script</h2>
<br>
<br>
<h1>Test Form</h1>
<form action="/" method="post" name="login">
{{ render_field(form.test_form(size=80) }}<br>
<p><input type="submit" value="Sign In"></p>
</form>
</html>
When I run flask run I get this
$ flask run
* Serving Flask app "FlaskApp"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
When I try to access http://127.0.0.1:5000/ in both chrome and firefox I get an error, but I feel like that's a whole separate question.

If all of your codes are here then I can tell you the problem might be about rendering form, try this one (pip install flask-bootstrap):
# __init.py
...
bootstrap = Bootstrap(app)
main.html
{% import 'bootstrap/wtf.html' as wtf %}
...
{{ wtf.quick_form(form) }}
...

Related

Deploying OpenAI Quickstart Python flask Web App - POST Request Loading Root Directory and no css

I have an issue deploying the quick start python web app from the openai website.
It works fine on my local, but when I push to my host (A2hosting), after configuring the web app in cpanel, not only is the css not recognized (with a MIME type (“text/html”) mismatch), when I POST request, it loads the root directory, where there is nothing.
The app and all files are located here: /home/domain/flaskai.
And when creating the app via cpanel, it also created a folder in public html here: /home/domain/public_html/flaskai.
So in effect, the app loads ok (but without css) in domain/flaskapp, and when I submit the form it loads: domain/.
Here is my passenger_wsgi.py:
import os
import sys
import importlib.util
sys.path.append(os.getcwd())
spec = importlib.util.spec_from_file_location("app", "app.py")
app = importlib.util.module_from_spec(spec)
spec.loader.exec_module(app)
application = app.app
Here is my app.py:
import os
import openai
from flask import Flask, redirect, render_template, request, url_for
app = Flask(__name__, static_folder='static', static_url_path='/static')
openai.api_key = os.getenv("OPENAI_API_KEY")
#app.route("/", methods=("GET", "POST"))
def index():
if request.method == "POST":
animal = request.form["animal"]
response = openai.Completion.create(
model="text-davinci-003",
prompt=generate_prompt(animal),
temperature=0.6,
)
return redirect(url_for("index", result=response.choices[0].text))
result = request.args.get("result")
return render_template("index.html", result=result)
def generate_prompt(animal):
return """Suggest three names for an animal that is a superhero.
Animal: Cat
Names: Captain Sharpclaw, Agent Fluffball, The Incredible Feline
Animal: Dog
Names: Ruff the Protector, Wonder Canine, Sir Barks-a-Lot
Animal: {}
Names:""".format(
animal.capitalize()
)
if __name__ == "__main__":
app.run()
Here is the index.html in the template folder:
<!DOCTYPE html>
<head>
<title>OpenAI Quickstart</title>
<link
rel="shortcut icon"
href="{{ url_for('static', filename='dog.png') }}"
/>
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}" />
</head>
<body>
<img src="{{ url_for('static', filename='dog.png') }}" class="icon" />
<h3>Name my pet</h3>
<form action="{{ url_for('index') }}" method="post">
<input type="text" name="animal" placeholder="Enter an animal" required />
<input type="submit" value="Generate names" />
</form>
{% if result %}
<div class="result">{{ result }}</div>
{% endif %}
</body>
and here is the .htaccess in /home/domain/public_html/flaskai:
# DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION BEGIN
PassengerAppRoot "/home/domain/flaskai"
PassengerBaseURI "/flaskai"
PassengerPython "/home/domain/virtualenv/flaskai/3.7/bin/python"
AddType text/css .css
It works fine on my local, so What went wrong.
I have been at it for two days now and going nuts. Thanks in advance.
I found the issue.
I needed to import dotenv in the app.py file
from dotenv import load_dotenv
load_dotenv()

WTForms Validators not Working except DataRequired()

I'm building a website using Python, Flask, and WTForms. I built a form webpage and tried to add Validators to the form. However, I found that only DataRequired() is working. The other validators aren't reporting any error even when I deliberately input wrong values.
forms.py
from flask_wtf import FlaskForm,Form
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, IPAddress
class FooForm(Form): # I tried both FlaskForm and Form
ip = StringField('IP Address', validators=[DataRequired(),IPAddress()])
button = SubmitField('Submit')
main.py
#app.route('/foo', methods=['POST', 'GET'])
def foo():
foo_form = FooForm()
return render_template('foo.html', form=foo_form)
/templates/foo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>Foo</h2>
<form method="post">
{{ form.ip.label() }}
{{ form.ip() }}
{{ form.button.label() }}
{{ form.button() }}
</form>
</body>
</html>
Example GIF:
As you can see, DataRequired() is working, but not so for IPAddress(), plus basically any other validators I've tried.
{% form.ip.error %} also is empty.
Anyone know why this is happening? Or should I just build a form with scratch HTML?
Python 3.10.8; Flask 2.2.2; Flask-WTF 1.0.1; WTForms 3.0.1
They are working, but you are not validating the form with foo_form.validate_on_submit().
Some validations are setting the attributes for the <input> tags. Therefore they can be instantly validated on the html side. Others are not setting them and only validate the input on the backend. Look for the following statement under wtforms documentation:
Sets the required attribute on widgets.
Length is something that can be set via an attribute, however IPAddress requires you to use validate_on_submit().
class FooForm(FlaskForm):
ip = StringField("IP Address", validators=[DataRequired(), IPAddress()])
button = SubmitField("Submit")
#app.route("/foo", methods=["POST", "GET"])
def foo():
foo_form = FooForm()
if foo_form.validate_on_submit():
return "validated"
print(foo_form.errors)
return render_template("foo.html", form=foo_form)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>Foo</h2>
<form method="post">
{{ form.hidden_tag() }} <!-- Make sure to include this line for CSRF protection -->
{{ form.ip.label() }}
{{ form.ip() }}
{{ form.button.label() }}
{{ form.button() }}
</form>
</body>
</html>
# Output
127.0.0.1 - - [14/Dec/2022 11:37:16] "GET / HTTP/1.1" 200 -
{'ip': ['Invalid IP address.']}

Python Flask - url_for{} not accessing static folder [duplicate]

This question already has an answer here:
Flask Python not loading main.css
(1 answer)
Closed 1 year ago.
Have a directory structure as follows:
Flask_project
-env
-src
--app2.py
-static
--css
---main.css
-templates
--base.html
--index.html
-app.py
If I load the page using app.py in the main folder, the main.css file is loaded fine using: python app.py. This works from the following file:
from flask import Flask, render_template, url_for # import
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
However, if I load app2.py using python3 src\app2.py which is in the \src folder as follows, and redirects the template_folder:
from flask import Flask, render_template, url_for # import
app = Flask(__name__, template_folder='../templates')
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
I am unable to load the css\main.css folder, I get the following error:
"GET /css/main.css HTTP/1.1" 404 -
I don't see why placing the app_whatever.py file in a sub directory (in this case \src) makes it unable to locate the main.css file?
For reference the base.html is as follows:
<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">
<link rel="stylesheet" href="{{url_for('static', filename='css/main.css') }}">
{% block head %}{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
And index.html is:
{% extends 'base.html' %}
{% block head %}
{% endblock %}
{% block body %}
<h1> Template </h1>
{% endblock %}
As mentioned in your second question, you need to define the location of your static-folder:
app = Flask(__name__, template_folder='../templates', static_folder='../static')

jinja2.exceptions.TemplateNotFound why does this keep popping up?

This is my code pro.py which i have save in my Downloads:
from flask import Flask, render_template, flash, session, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField
app = Flask(__name__)
app.config['SECRET_KEY'] = 'kmkey'
class SimpleForm(FlaskForm):
breed = StringField('What breed are you?')
submit= SubmitField('Click Me')
#app.route('/',methods=['GET','POST'])
def imp():
form = SimpleForm()
if form.validate_on_submit():
session['breed'] = form.breed.data
flash(f"You just changed your breed to: {session['breed']}")
return redirect(url_for('imp'))
return render_template('imp.html',form=form)
if __name__ == '__main__':
app.run(debug=True)
This is my html code imp.html which i have saved in my template folder which is inside Downloads:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% for mess in get_flashed_messages() %}
<div class="alert alert-warning alert-dismissible fade show" role='alert'>
<button type="button" class="fade close" data-dismiss='alert' aria-label='close' >
<span aria-hidden='true'>×</span>
</button>
{{mess}}
</div>
{% endfor %}
<form method="post">
{{form.hidden_tag()}}
{{form.breed.label}}{{form.breed}}
{{form.submit()}}
</form>
</body>
</html>
Now when i run my python file on web it throws an error saying that
jinja2.exceptions.TemplateNotFound:imp.html why does it happen like that??
Can anyone pls help me out with this issue.
You need to save it in templates folder not template folder.

Flask template extending issue

Flask template extension doesn't work for some reason.
I've created a basic flask app with the following file structure:
__init__.py is empty
The code from app.py is:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template("index.html")
if (__name__ == "__main__"):
app.run()
The code from index.html is:
<!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>Document</title>
</head>
<body>
<h1>from index</h1>
{% block ext %}
{% endblock %}
</body>
</html>
The code from ext.html is:
{% extends "index.html" %}
{% block ext %}
<h2>from ext</h2>
{% endblock %}
When I run in command line python app.py it gives no errors or warnings, logs are just
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [27/Sep/2017 14:48:40] "GET / HTTP/1.1" 200 -
But in the browser, the only output I have is "from index". So Flask doesn't see template extension from ext.html, and I don't see "from ext" in the browser. What's wrong here? Is there a typo somewhere?
You're rendering the wrong thing. Inheritance goes from child to parent; if you want the child template to be used, then that's what you need to call.
def index():
return render_template("ext.html")

Categories