Stripe flask/python loading html but not css. Directory issue? - python

so I have tried paying some tutors to look at this and they cannot seem to find the issue. I have a really good feeling it is a directory issue.
Folder directory organization
App.py is outside all folders, inside a template folder is pricing.html, outside is another folder named css which has pricing.css.
I run my app.py which loads pricing.html to be able to press a button which goes to stripe checkout. The issue is, app.py finds the pricing folder, but the pricing.css does not load. Here is the html code in pricing.html:
<link rel="stylesheet" type="text/css" href="/css/style.css" media="screen">
Here is the app.py code:
from flask import Flask, redirect, request, render_template
import stripe
app = Flask(__name__,static_url_path="",static_folder="templates")
stripe.api_key = 'sk_test_51KzqK9Hj2B2Quz911XrP11cB4Jb2ESrDCelSpRIZBqa18TWO9bGKlyuWsmiNeGYEHw4224xx5ghUWDaTQOukRjcf00rHXcZGYU'
YOUR_DOMAIN = "http://localhost:5000"
#app.route('/create-checkout-session', methods=['POST'])
def create_checkout_session():
try:
checkout_session = stripe.checkout.Session.create(
line_items = [
{
'price': 'price_1KzrAtHj2B2Quz91wMDanJjz',
'quantity':1
}
],
mode="payment",
success_url=YOUR_DOMAIN + "/success.html",
cancel_url=YOUR_DOMAIN + "/cancel.html"
)
except Exception as e:
return str(e)
return redirect(checkout_session.url,code=303)
if __name__== "__main__":
app.run(port=5000,debug=True)
If I move the css folder inside the templates folder, the css will load, but I would have to change the html to all the other template and also I like this folder organization. Any thoughts?
Here is what is returned in terminal when I run it:
[20/May/2022 18:04:50] "GET /pricing.html HTTP/1.1" 200 -
[20/May/2022 18:04:51] "GET /css/style.css HTTP/1.1" 404 -
[20/May/2022 18:04:51] "GET /css/Pricing.css HTTP/1.1" 404 -
[20/May/2022 18:04:51] "GET /javascript/jquery.js HTTP/1.1" 404 -
[20/May/2022 18:04:51] "GET /javascript/nicepage.js HTTP/1.1" 404 -
[20/May/2022 18:04:51] "GET /css/images/GainesOpusInstitute4.png HTTP/1.1" 404 -

I believe that for flask to serve your css file it needs to be in the /static directory. Try moving your /css and /javascript folders into a directory at the same level called /static.
Then change your link to be:
<link rel="stylesheet" type="text/css" href="/static/css/style.css" media="screen">
See https://flask.palletsprojects.com/en/2.1.x/quickstart/#static-files for more info.

Related

Flask when I wrote app.route('/home') and edited it app.route('/home/') and restore it

I'm studying flask, and got problems.
When I wrote code like this:
#app.route("/reference")
def reference():
return render_template("reference.html", css="reference", records=records)
The page http://127.0.0.1:5000/reference was working.
Then I found 'trailing slash' in flask document.
I wanted to apply it, so I edited code like this:
#app.route("/reference/")
def reference():
return render_template("reference.html", css="reference", records=records)
It was working too ! http://127.0.0.1:5000/reference/
But some problems were coming.
The browser couldn't read my css file (in html link.. href=blabla) with a changed log in python terminal.
GET /static/css/style.css HTTP/1.1 << before changing
GET /reference/static/css/style.css HTTP/1.1 << after changing
I redirected css file path,
href="static/css/style.css"
to
href="../static/css/style.css"
And It works.
I wanted to understand how 'trailing slash' do.
So I reset my code to first code.
Then 404 not found error raised and I got a not changed log.
"GET /reference HTTP/1.1" << log for first code
"GET /reference/ HTTP/1.1" << log for second code
"GET /reference/ HTTP/1.1" << log for reset code (== first code)
I got a question. What is happend?
I don't understand why it doesn't run like before.
I read https://flask.palletsprojects.com/en/2.0.x/quickstart/#unique-urls-redirection-behavior
But I still don't understand what is going on.
Why the GET path changed.. why the GET path doesn't changed.. why..
My mind is broken and I can't sleep.. please help me..
On top of what the unique-urls-redirection-behavior document says, when you use tags like <img src='some_url'> or <link href='some_url'> the behaviour may be different, as these URLs are loaded by the browser.
So with a route decorator like #app.route("/reference") which loads in the browser as example.com/reference a link tag with href="subpath/file.css" causes the browser to load that resource from example.com/subpath/file.css
On the other hand, with a route decorator like #app.route("/reference/") (with the trailing slash) which loads in the browser as example.com/reference/ (again, with the trailing slash) a link tag with href="subpath/file.css" causes the browser to load that resource from example.com/reference/subpath/file.css
This could explain the behaviour you are seeing.
To put this another way, consider this test app:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/a')
def a(): return render_template('index.html')
#app.route('/b/') # Note trailing slash
def b(): return render_template('index.html')
Paired with the following template at templates/index.html:
<html>
<head>
<link rel='stylesheet' href='subpath/file.css' />
</head>
Then make some hits and observe the asset requests in the console (they will give 404 errors because I haven't actually created the CSS files, this is just to show what the browser requests):
Load URL: http://localhost:5000/a:
"GET /a HTTP/1.1" 200 -
"GET /subpath/file.css HTTP/1.1" 404 -
Load URL: http://localhost:5000/b/:
"GET /b/ HTTP/1.1" 200 -
"GET /b/subpath/file.css HTTP/1.1" 404 -
Of course the correct way to include these assets is to use the url_for function.
So if I update the template to instead contain:
<link rel='stylesheet' href='{{ url_for("static", filename="file.css") }}' />
Then make the same request:
Load URL: http://localhost:5000/a:
"GET /a HTTP/1.1" 200 -
"GET /static/file.css HTTP/1.1" 404 -
Load URL: http://localhost:5000/b/:
"GET /b/ HTTP/1.1" 200 -
"GET /static/file.css HTTP/1.1" 404 -
As you can see here, the correct path for static assets will always be rendered, regardless of whether the endpoint has a trailing slash or not.

Serve static files with flask on development and nginx on production

Let's say I've got this mcve:
mcve.py
import textwrap
from pathlib import Path
from flask import Flask
working_dir = Path(__file__).parent
app = Flask(
__name__,
# static_folder=str(working_dir / "uploads"),
)
#app.route("/test")
def index():
return textwrap.dedent(
"""
<!DOCTYPE html>
<html>
<head>
<title>Hello world</title>
</head>
<body>
<img src="foo/foo.png">
<img src="bar/bar.png">
</body>
</html>
"""
).strip()
if __name__ == "__main__":
with app.test_client() as c:
print(c.get("/test").data.decode("utf-8"))
run.bat
set FLASK_APP=mcve.py
set FLASK_ENV=development
flask run
If I execute run.bat and then I go to http://localhost:5000/test in the browser I'll get:
>flask run
* Serving Flask app "x.py" (lazy loading)
* Environment: development
* Debug mode: on
* Restarting with windowsapi reloader
* Debugger is active!
* Debugger PIN: 497-008-397
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [31/May/2020 22:32:19] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /test HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /foo/foo.png HTTP/1.1" 404 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /bar/bar.png HTTP/1.1" 404 -
Question
How should I modify mcve.py to server the images properly (now you can see is giving 404) in development using flask's server but then serve them properly with nginx on production?
You don't have to configure flask specifically for this. These logs:
127.0.0.1 - - [31/May/2020 22:32:19] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /test HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /foo/foo.png HTTP/1.1" 404 -
127.0.0.1 - - [31/May/2020 22:32:22] "GET /bar/bar.png HTTP/1.1" 404 -
are actually generated by the werkzeug development server that's serving the static content for you. When you move to using nginx, you can intercept the GET requests with a URL rule. From the example nginx config file from the Flask Mega Tutorial:
...
server {
...
location / {
# forward application requests to the gunicorn server
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
# handle static files directly, without forwarding to the application
alias /home/ubuntu/microblog/app/static;
expires 30d;
}
}
Note the /location rule that handles requests to static directly, so those requests from the browser wouldn't even hit whatever is serving your flask app in production. There are many more methods for matching urls that you can find, e.g. here. It's perfectly possible to add multiple such rules to look in separate locations but you'll want to structure the app to give these files a distinct location so you can implement such rules.
Separately, to get around your current 404s, look at the template docs for Jinja2 and use the url_for method to make sure it resolves relative paths correctly.
For example, if I want to include:
<link href='static/css/bootstrap-4.3.1.min.css' rel="stylesheet">
I would instead use:
<link href="{{ url_for('static', filename='css/bootstrap-4.3.1.min.css') }}" rel="stylesheet">
This passes off the responsibility of path resolution to the app, so no matter how many hyperlinks I've followed or blueprints I'm using, this path will always resolve to the correct static directory when the template is rendered.
I'm not sure this will work with return textwrap.dedent because it might not invoke Jinja on the template. You can import render_template_string for a throwaway example like you have here, but render_template will work in your actual app too.

bootstrapshuffle frontend add to django 3.0 project

I am building my CSS/JS/html basic site on https://bootstrapshuffle.com/ that I have exported and try to add to my Django 3.0 project.
Requirements
Django 3.0
python 3.7
macOS 10.12
Terminal Error Messages
(after you start solving them it will show more error messages until you put everything to the right place)
Not Found: /js/jquery/jquery.min.js
[03/Mar/2020 14:31:28] "GET /js/jquery/jquery.min.js HTTP/1.1" 404 2568
Not Found: /placeholder/icons/check.svg
[03/Mar/2020 14:31:28] "GET /placeholder/icons/check.svg HTTP/1.1" 404 2580
Not Found: /js/popper/popper.min.js
Not Found: /js/bootstrap/bootstrap.min.js
[03/Mar/2020 14:31:28] "GET /js/bootstrap/bootstrap.min.js HTTP/1.1" 404 2586
Not Found: /css/bootstrap/bootstrap.min.css
[03/Mar/2020 14:31:28] "GET /css/bootstrap/bootstrap.min.css HTTP/1.1" 404 2592
[03/Mar/2020 14:31:28] "GET /js/popper/popper.min.js HTTP/1.1" 404 2568
Not Found: /js/popper/popper.min.js
[03/Mar/2020 14:31:28] "GET /js/popper/popper.min.js HTTP/1.1" 404 2568
Not Found: /js/bootstrap/bootstrap.min.js
[03/Mar/2020 14:31:28] "GET /js/bootstrap/bootstrap.min.js HTTP/1.1" 404 2586
Django Project folder structure
MyDjangoProjectName
MainProjectAppFolder
static
When I have putted anywhere other than the static folder the folders and reconnected them they did not worked. So I could only make it work by putting them to static folder.
added files/folders inside static
public
src
package.json
settings.py
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'MainProjectFolder/static/')]
I have my HTML files in different parts of the projects under templates ex.: MyDjangoProjectName/AAAappfolder/templates/AAAappfolder/home.html I have basically copied and pasted the original HTML code here to my django HTML file. Than corrected each element as follows ex.:
<link rel="stylesheet" href="static/public/css/bootstrap/bootstrap.min.css">
<img class="mr-2 mt-2" src="static/public/placeholder/icons/check.svg" alt="">
<script src="static/public/js/jquery/jquery.min.js"></script>
<script src="static/public/js/popper/popper.min.js"></script>
<script src="static/public/js/bootstrap/bootstrap.min.js"></script>

Serving HTML from Flask, can't find image?

I'm creating a Flask app frontend, my index.html can't find the images and files referenced in the code.
I've tried moving to the same folder but with no success.
Server:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return open('html/index.html').read()
if __name__ == '__main__':
app.run(host='localhost', port=8000, debug=True)
HTML lines:
<img src="shards-logo-white.svg" alt="Example Navbar 1" class="mr-2" height="30">
<script src="js/shards.min.js"></script>
<script src="js/demo.min.js"></script>
Server debug output:
127.0.0.1 - - [30/Jan/2019 12:19:28] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [30/Jan/2019 12:19:29] "GET /shards-logo-white.svg HTTP/1.1" 404 -
127.0.0.1 - - [30/Jan/2019 12:19:29] "GET /html/js/shards.min.js HTTP/1.1" 404 -
127.0.0.1 - - [30/Jan/2019 12:19:29] "GET /html/js/demo.min.js HTTP/1.1" 404 -
The image shards-logo-white.svg is in the same folder.
The js scripts are with the subdirectory html -> js -> FILES.
No, Flask does not serve arbitrary files from the filesystem. Move any static files like those into the static subdirectory, then reference them via that path; you can use the full path of nested directoriess within the static path:
<img src="/static/shards-logo-white.svg" alt="Example Navbar 1" class="mr-2" height="30">
<script src="/static/html/js/shards.min.js"></script>
<script src="/static/html/js/demo.min.js"></script>
You could serve your HTML rendered from a template, at which point you can use {{ url_for('static', filename="shards-logo-white.svg") }} and {{ url_for('static', filename="html/js/shards.min.js") }}, etc. to have Flask generate valid URLs for those paths.
See the Static Files section of the quickstart, as well as the Static Files chapter of the tutorial.
If you are not using a template then may as well serve your html/index.html file as a static file too. As it stands you are not rendering it as a template nor are you making any other runtime changes to the file contents.
Even if you do sometimes need to conditionally serve a file from disk, rather than read it all into memory I'd use the flask.send_file() function to make sure the file is served efficiently and with a reasonable content-type header:
from flask import send_file
#app.route('/')
def hello():
return send_file('html/index.html')
Relative paths are resolved against Flask.root_path. You probably also want to consider flask.send_from_directory(), which will ensure that user-input for a filename can't be abused to serve arbitrary files outside of a designated directory.

Can't set background image in flask made web-page

I'm trying to put background image inside HTML document using following code
<body style="background-image: url( {{url_for('static', filename='img/library2.jpg') }} )">
But it just doesn't work.
My console output is:
127.0.0.1 - - [23/Jan/2017 23:21:12] "GET /index HTTP/1.1" 200 -
127.0.0.1 - - [23/Jan/2017 23:21:12] "GET /static/styles.css HTTP/1.1" 200 -
127.0.0.1 - - [23/Jan/2017 23:21:15] "GET /static/img/favicon.ico HTTP/1.1" 200
So I don't even have get request for the img/library2.jpg.
Not sure what I'm missing
It seems you put style in one file but jinja uses different file to render page.
I don't know what you have in base.html and index.html but usually <body> is in base.html and you should use style in this file.

Categories