Flask returns 404 when sending file - python

The path is correct, and the file exists.
#app.route('/Users/<username>/<filename>')
def send_image(username, filename):
return send_from_directory('/Users/'+username, filename)
127.0.0.1 - - [16/Jun/2017 20:29:00] "GET /myuploads HTTP/1.1" 200 -
127.0.0.1 - - [16/Jun/2017 20:29:00] "GET /Users/alon123/1185392_716316861727493_1066399254_n.jpg HTTP/1.1" 404 -
127.0.0.1 - - [16/Jun/2017 20:29:00] "GET /Users/alon123/boy.jpg HTTP/1.1" 404 -
127.0.0.1 - - [16/Jun/2017 20:29:00] "GET /Users/alon123/gg.jpeg HTTP/1.1" 404 -
127.0.0.1 - - [16/Jun/2017 20:29:00] "GET /Users/alon123/IMG_1409.PNG HTTP/1.1" 404 -
127.0.0.1 - - [16/Jun/2017 20:29:00] "GET /Users/alon123/IMG_2743.JPG HTTP/1.1" 404 -
127.0.0.1 - - [16/Jun/2017 20:29:00] "GET /Users/alon123/IMG_2757.JPG HTTP/1.1" 404 -
127.0.0.1 - - [16/Jun/2017 20:29:00] "GET /Users/alon123/secondpage.png HTTP/1.1" 404 -
Here is the directory structure:
enter image description here
The root is Ludbox, and the html that call the function mentioned above could be found in templates.

Try adding a forward slash to the endpoint:
#app.route('/Users/<username>/<filename>/')

Related

Flask is loading static files from a different path when a route is called [duplicate]

This question already has answers here:
Link to Flask static files with url_for
(2 answers)
Why use Flask's url_for?
(1 answer)
Closed 3 years ago.
I have 2 route functions, one to get all users and one to get a specific user. Both functions render the same template. The first function works fine, the problem is with the second one. When rendering the template it tries to load static files from another directory.
I tried using a different template for each one and the problem remained.
Get all users route:
#app.route('/users')
def list_users():
users = Users.query.all()
return render_template('users.html', users=users)
Get one user route:
#app.route('/users/<username>')
def get_user(username):
user = Users.query.filter_by(name=username).first()
if user:
return render_template('users.html', users=[user])
Template rendered by get_user route function:
127.0.0.1 - - [07/Aug/2019 13:35:56] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [07/Aug/2019 13:35:57] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/Ana HTTP/1.1" 200 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/vendor/fontawesome-free/css/all.min.css HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/css/sb-admin-2.min.css HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/img/uatronica_black_transparent.png HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/vendor/jquery/jquery.min.js HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/vendor/bootstrap/js/bootstrap.bundle.min.js HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/vendor/jquery-easing/jquery.easing.min.js HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/js/sb-admin-2.min.js HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/vendor/chart.js/Chart.min.js HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/js/demo/chart-area-demo.js HTTP/1.1" 404 -
127.0.0.1 - - [07/Aug/2019 13:36:06] "GET /users/static/js/demo/chart-pie-demo.js HTTP/1.1" 404 -
It is trying to load css files from /users/static/ instead /static/. Why is that?
You are using relative paths in your template, so the final URL is relative to whatever URL you're at. When viewing /users, if the template links to static/css/admin.css, it becomes /users/static/css/admin.css. If the path starts with a /, it is an absolute URL and won't do this.
Instead, use url_for, which generates absolute URLs no matter where you are and how the app is deployed.
<link rel="stylesheet" href="{{ url_for('static', filename='css/admin.css') }}>
This becomes /static/css/admin.css.
Please use the below code.
Get one user route:
#app.route('/users/<username>')
def get_user(username):
user = Users.query.filter_by(name=username).first()
return render_template('users.html', users=user)
Additionally please share the html page users.html for review.

why the output of subprocess.Popen is not the same as expected?

I have a Django server which trying to run with subprocess.Popen and store all the logs on a file, this is my code:
with open('thefile.log', 'a') as the_file:
p1 = subprocess.Popen(['python', os.getcwd() + '\\mySite\\manage.py', 'runserver'], stdout=the_file,
stderr=the_file, universal_newlines=True)
and this is the result in the thefile.log:
Watching for file changes with StatReloader
[26/Jul/2019 13:10:05] "GET / HTTP/1.1" 200 16348
[26/Jul/2019 13:10:05] "GET /static/admin/css/fonts.css HTTP/1.1" 200 423
[26/Jul/2019 13:10:06] "GET /static/admin/fonts/Roboto-Light-webfont.woff HTTP/1.1" 200 85692
[26/Jul/2019 13:10:06] "GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1" 200 86184
[26/Jul/2019 13:10:06] "GET /static/admin/fonts/Roboto-Regular-webfont.woff HTTP/1.1" 200 85876
Not Found: /favicon.ico
[26/Jul/2019 13:10:08] "GET /favicon.ico HTTP/1.1" 404 1976
Not Found: /fs
[26/Jul/2019 13:10:11] "GET /fs HTTP/1.1" 404 1949
Performing system checks...
System check identified no issues (0 silenced).
July 26, 2019 - 13:09:44
Django version 2.2.3, using settings 'mySite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
but it should be like this:
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
July 26, 2019 - 13:09:44
Django version 2.2.3, using settings 'mySite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[26/Jul/2019 13:10:05] "GET / HTTP/1.1" 200 16348
[26/Jul/2019 13:10:05] "GET /static/admin/css/fonts.css HTTP/1.1" 200 423
[26/Jul/2019 13:10:06] "GET /static/admin/fonts/Roboto-Light-webfont.woff HTTP/1.1" 200 85692
[26/Jul/2019 13:10:06] "GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1" 200 86184
[26/Jul/2019 13:10:06] "GET /static/admin/fonts/Roboto-Regular-webfont.woff HTTP/1.1" 200 85876
Not Found: /favicon.ico
[26/Jul/2019 13:10:08] "GET /favicon.ico HTTP/1.1" 404 1976
Not Found: /fs
[26/Jul/2019 13:10:11] "GET /fs HTTP/1.1" 404 1949
in fact I have some other serivices, my other question is that How can I print the result of them in propper way with subprocess.Popen on my current terminal? for example:
service1:
------
------
service2:
------
------
You can not route stdout and stderr to the same file handler like that. You can however use a trick here to "route" the stderr to the stdout (or vice-versa), like:
with open('thefile.log', 'a') as the_file:
p1 = subprocess.Popen(
['python', os.getcwd() + '\\mySite\\manage.py', 'runserver'],
stdout=the_file,
stderr=subprocess.STDOUT,
universal_newlines=True
)
This looks similar to a shell where you write python manage.py runserver >> thefile.log 2>&1.

websocket on port 443 with /socket.io under kubernetes not working

Trying to move my development environment to run on minikube.
The page loads but my page uses websockets on the same port/protocol that the index.html is loaded with (https in this case), and the websockets do no seem to be working correctly.
Here is an example of the correct output when run through nginx / python on my local development box.
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET / HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /static/jquery.min.js HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /static/socket.io.min.js HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /socket.io/?EIO=3&transport=polling&t=MNPIg-N HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /favicon.ico HTTP/1.0" 404 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /favicon.ico HTTP/1.0" 404 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "POST /socket.io/?EIO=3&transport=polling&t=MNPIg-o&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /socket.io/?EIO=3&transport=polling&t=MNPIg-r&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "POST /socket.io/?EIO=3&transport=polling&t=MNPIg_x&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /socket.io/?EIO=3&transport=polling&t=MNPIg_w&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:40] "GET /socket.io/?EIO=3&transport=polling&t=MNPIh0L&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:45] "GET /socket.io/?EIO=3&transport=polling&t=MNPIiE3&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:50] "GET /socket.io/?EIO=3&transport=polling&t=MNPIjSI&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:55] "GET /socket.io/?EIO=3&transport=polling&t=MNPIkgS&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
Notice how there is a GET every 5 seconds (that's a timer running on the page)
When running on Kubernetes, The page loads and the timer shows up as if the websocket has worked, however I show no logs where the websocket is having a GET or POST after the initial one.
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:03] "GET /static/jquery.min.js HTTP/1.1" 304 1210 0.008244
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:03] "GET /static/socket.io.min.js HTTP/1.1" 304 1210 0.009271
(10) accepted ('172.17.0.7', 34444)
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "GET /socket.io/?EIO=3&transport=polling&t=MNPKrsy HTTP/1.1" 200 379 0.003682
(10) accepted ('172.17.0.7', 34446)
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "GET /favicon.ico HTTP/1.1" 404 1314 0.004694
(10) accepted ('172.17.0.7', 34448)
(10) accepted ('172.17.0.7', 34450)
(10) accepted ('172.17.0.7', 34452)
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "GET /socket.io/?EIO=3&transport=polling&t=MNPKrtD&sid=77d4755c524f47c2948b9c36da007b85 HTTP/1.1" 200 210 0.000749
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "POST /socket.io/?EIO=3&transport=polling&t=MNPKrtB&sid=77d4755c524f47c2948b9c36da007b85 HTTP/1.1" 200 194 0.002632
(10) accepted ('172.17.0.7', 34454)
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "GET /favicon.ico HTTP/1.1" 404 1314 0.002388
The Ingress is setup as follows:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: websitev2-cluster-ip-service
servicePort: 8080
As mentioned before, the websocket does not reside on a different port and it is instanciated in javascript as:
namespace = '/socket';
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
Are there any special requirements to get websockets to work? I do not believe i need a special route because the URI needs to be sent to the same location as everything else, and on the same port.
EDIT: MORE DETAILS
My website has a form, that when submitted, executes the following code:
$('form#job').submit(function(event) {
var nameValue = JSON.stringify($(event.target).serializeArray());
console.log(nameValue)
socket.emit('job_submit', {data: nameValue});
return false;
});
On the python side, I have my socket code, which should get hit once a user clicks the submit button.
#socketio.on('job_submit', namespace='/socket')
def job_submit(message):
print('recieved job_submit message from client')
# kick off subjob in celery task
data = unstringify(message)
print('data = {0}'.format(data))
sessiondata = dict(session)
print('sessiondata = {}'.format(sessiondata))
subjobstart.delay(sessiondata, request.sid, data)
In my logs I am not receiving any "recieved job_submit message from client" messages when the submit button is clicked, which means the javascript is trying to send a websocket emit to the python server, but the message is never getting there.
Emits from python to the client page are working as the time is getting updated on the site.
So not exactly sure what changed as it worked on test box, apparently the issue lied in the form validation I was doing. Once I put in a novalidate option to temporarily bypass the form checking, the form was then able to be submitted and I did not have any websocket issues after all.
Hopefully this post can help someone with the code posted instead.

Flask - Having more than one static folder (the static folders are actually dynamic)

Im currently working on a project that has the following structure:
ROOT
-js
-dist
-index.html
-bunch of other files that index.html uses
-src
-main.py
-doc_apps
-app1
-index.html
-other resources that index.html needs
-app2
-index.html
-other resources that index.html needs
Now my flask configuration is:
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
COMPONENT_FOLDER = os.path.abspath(os.path.join(ROOT_DIR, '../'))
DIST_FOLDER = os.path.join(COMPONENT_FOLDER, 'js\\dist')
DOCUMENTATION_FOLDER = os.path.join(COMPONENT_FOLDER, 'documentation_data')
app = Flask(__name__, static_folder=DIST_FOLDER, template_folder=DIST_FOLDER, static_url_path='')
my_loader = jinja2.ChoiceLoader([
app.jinja_loader,
jinja2.FileSystemLoader(DOCUMENTATION_FOLDER),
])
app.jinja_loader = my_loader
#app.route('/')
def index():
"""
This the main entry to the application
Returns
-------
out
renders the 'index.html' file
"""
return render_template('index.html')
#app.route('/get_index_html', methods=['GET'])
def get_index_html():
index_html_path = request.args.get('path')
full_root = os.path.join(index_html_path).replace('\\','/')
return render_template(full_root)
When I start my app and go to the main page im able to render the index.html (the one in the js/dist folder) and everything works great
the problem starts when I try to render one of the inner index.html.
Im able to render the index.html by itself but I get the following errors
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/css/theme.css HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/pygments.css HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/js/modernizr.min.js HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/jquery.js HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/underscore.js HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/doctools.js HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/js/theme.js HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/jquery.js HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:43] "GET /_static/underscore.js HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:44] "GET /_static/doctools.js HTTP/1.1" 404 -
127.0.0.1 - - [02/Aug/2018 18:08:44] "GET /_static/js/theme.js HTTP/1.1" 404 -
I can tell that the problem is that it cant find the static files that are needed in order to generate this index.html correctly.
How can I tell it that for this specific index.html use some_static_folder?
I was wondering if there is something like render(html, static_folder=...)
I would like to mention that each one of the App1/index.html
has its own links and those links rely on the inner structure of App1, so how can I configure that when I send App1/index.html it will use some static_folder for everything that will be invoked from that App1/index.html
Some more info, App1/2 can be added also after the server is already running.
thank you very much for your help

Redirect BaseHTTPServer stdout to logging

I wrote a quick webserver using BaseHTTPServer, and it's working nicely, so now I'm trying to implement logging, and I noticed, hey, seems like BaseHTTPServer already has some logging information that it spits out to the stdout, is there a way to implement my logging to also include this stdout.
i.e. Have logging record all information from the stdout.
Note: I am not explicitly printing anything to the console window, when a GET request is made, BaseHTTPServer handles printing this to the console.
Example:
127.0.0.1 - - [02/May/2014 20:51:52] "GET /postTest.html HTTP/1.1" 200 -
127.0.0.1 - - [02/May/2014 20:51:52] "GET /assets/foundation.js HTTP/1.1" 200 -
127.0.0.1 - - [02/May/2014 20:51:52] "GET /assets/bootstrap.css HTTP/1.1" 200 -
127.0.0.1 - - [02/May/2014 20:51:57] "GET /index.html HTTP/1.1" 200 -
127.0.0.1 - - [02/May/2014 20:51:57] "GET /assets/foundation.js HTTP/1.1" 200 -
127.0.0.1 - - [02/May/2014 20:51:57] "GET /assets/bootstrap.css HTTP/1.1" 200 -
According to the BaseHTTPServer documentation, you can override the log_message method to do this. By default, it just writes to stderr, but you can make it write to your logger instead (or have it write to both).

Categories