Fix absolute urls in Flask apache application - python

I wrote a web application in Flask, then I decided to use Apache to deploy it:
<VirtualHost *:80>
WSGIScriptAlias /app /var/www/flask-app/flask-app.py
<Directory /var/www/flask-app>
Require all granted
</Directory>
</VirtualHost>
But now, links such as:
<a href='/login'>Sign in</a>
Go to /login instead of /app/login. Is there any way to fix this, without changing all of the URLs?

As PJ Santoro said you should be using url_for. This takes the ambiguity out of routes.
<a href='{{ url_for('route_function_name') }}'>Sign in</a>
Where:
#routes.route('/login', methods=['GET'])
def route_function_name():
return 'blah'

Related

Hosting static website with Django

I have Django app running live on AWS at, www.domain.com/admin. It doesn't posses any html pages, we only make use of Django-Admin.
Now I have to host a website at www.domain.com.
I have my website package in this form,
site
|-sass
|-js
|-img
|-fonts
|-css
|-index.html
I copy-pasted my site folder inside my Django app at my_django_app/templates/
Also, added this :
url(r'^$', TemplateView.as_view(template_name='site/index.html')),
inside my_django_app/my_django_app/urls.py.
And, updated my settings.py with,
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'templates/site'),
]
Now when I runserver and go to www.domain.com, it loads my html file without CSS, JS and Images.
Please suggest me what I am doing wrong.
I am a beginner to python and also never hosted a website ever before.
This answer is a reply to this comment, not an answer to the original question.
In your Apache config, change: WSGIScriptAlias / to WSGIScriptAlias /admin.
Add this before the </VirtualHost> closing tag:
Alias / /path/to/static/site/
<Directory /path/to/static/site/>
Options Indexes FollowSymLinks
AllowOverride All
Order Deny,Allow
Allow from all
</Directory>
I haven't tested it, but I believe this should work.

Flask routing throw 404 on production server

on my production server, my flask application throw 404 when i tried to access www.example.com/admin however, if i tried to access root content, everything works fine. I am using apache for my web server with python 3.4
#app.route('/')
def index():
return render_template("search.html")
. python functions in between
.
.
.
#app.route("/admin")
def admin():
return render_template("adminAuth.html", error=False)
#app.route("/admin", methods=["POST"])
def adminAuth():
# Intentionally return None
return None
Remarks: On my test environment, (PyCharm with Flask) everything works fine, I can access /admin
This is my WSGI conf
<VirtualHost *:80>
ServerName NAME
ServerAdmin admin#mywebsite.com
WSGIScriptAlias / /path/to/app.wsgi
<Directory /path/to/webapp/>
Order allow,deny
Allow from all
</Directory>
Alias /static /path/to/webapp/static
<Directory /path/to/webapp/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/path/to/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/path/to/access.log combined
</VirtualHost>

Serving static files through apache

I am new to the whole mod_wsgi and serving files through apache. I am really comfortable with flask but this is something i can't get my head around. I did the hello-world program and successfully displayed hello world!
Now i wanted to display a image file. So I updated my hello-world.py to:
from flask import *
yourflaskapp = Flask(__name__)
#yourflaskapp.route("/")
def hello():
file="203.jpg"
return render_template("hello.html",file=file)
# return"HEY"
if __name__ == "__main__":
yourflaskapp.run()
my directory structure is something like:/var/www/hello-world
/hello-world
test.py
yourflaskapp.wsgi
/static
-203.jpg
/templates
-hello.html
My template is simple:
<!DOCTYPE html>
<html><head><title>hi</title></head>
<body>
<img src="{{url_for('static',filename=file)}}"/>
</body></html>
and my apache conf file is:
<VirtualHost *:80>
WSGIDaemonProcess yourflaskapp
WSGIScriptAlias / /var/www/hello-world/yourflaskapp.wsgi
Alias /static/ /var/www/hello-world/static
Alias /templates/ /var/www/hello-world/templates
<Directory /var/www/hello-world>
WSGIProcessGroup yourflaskapp
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/hello-world/static>
Order allow,deny
Allow from all
</Directory>
<Directory /var/www/hello-world/templates>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Though when i open the browser and head to my ip, it doesn't show the image file.
What am i doing wrong? Is there any other approach i should follow?
and if anyone could recommend any good links from where i can understand working with flask+mod_wsgi+apache2
It is generally always a good idea to have trailing slash balanced when mounting static files at a sub URL. So instead of:
Alias /static/ /var/www/hello-world/static
use:
Alias /static /var/www/hello-world/static

Changes to Flask index.py not loading

I'm working on a pretty simple web application utilizing Flask, and I'm trying to deploy it to a Digital Ocean VPS. I have it running with apache2 and WSGI. Here's the git repo. I am terrible at devops, so I don't know why this isn't working.
In /var/www/VAWomensHealth/ I have a folder with the flask app called VAWomensHealth and a VAWomensHealth.wsgi file that looks like this:
#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/VAWomensHealth/")
from VAWomensHealth import app as application
#from app import app as application
application.secret_key = 'Add your secret key'
My index.py file looks like this:
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/feeds')
def feeds():
return render_template('feeds.html')
if __name__ == '__main__':
app.run(debug=True)
and my VAWomensHealth.conf inside /etc/apache2/sites-enabled/ looks like this:
<VirtualHost *:80>
ServerName bagbot.com
ServerAdmin chris#example.com
WSGIScriptAlias / /var/www/VAWomensHealth/VAWomensHealth.wsgi
WSGIScriptReloading On
<Directory /var/www/VAWomensHealth/VAWomensHealth/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/VAWomensHealth/VAWomensHealth/static
<Directory /var/www/VAWomensHealth/VAWomensHealth/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
So when I go to the domain, the main site loads. And when I edit my static files or templates, those changes are immediately reflected on the domain.
However, code changes that I make to index.py don't seem to be taking effect (such as trying to have the index file load a different template). This is preventing me from adding other routes to my app.
Any ideas?
As for me (but I can't test it) you have to change name index.py to __init__.py
Or you have to use index in wsgi file
from VAWomensHealth.index import app as application

Django deployment, all links are prepended with index.wsgi

I want to deploy my django app in a Ubuntu server with Apache and mod_wsgi. I am following this tutorial
http://thecodeship.com/deployment/deploy-django-apache-virtualenv-and-mod_wsgi/
in my site file I have
<VirtualHost *:80>
ServerAdmin webmaster#mydomain.com
ServerName mydomain.com
ServerAlias www.mydomain.com
WSGIScriptAlias / var/www/index.wsgi
Alias /static/ /var/www/static/
<Location "/static/">
Options -Indexes
</Location >
</VirtualHost >
Don't mind the generic mydomain.com entries. The site is for progress display only so I can discuss it with my friend.
in /var/www/index.wsgi I have this
import os
import sys
import site
# Add the site-packages of the chosen virtualenv to work with
site.addsitedir('/home/voger/venvs/ssite/local/lib/python2.7/site-packages')
# Add the app's directory to the PYTHONPATH
sys.path.append('/home/voger/projects/ssite')
sys.path.append('/home/voger/projects/ssite/ssite')
os.environ['DJANGO_SETTINGS_MODULE'] = 'ssite.settings'
# Activate your virtual env
activate_env=os.path.expanduser("/home/voger/venvs/ssite/bin/activate_this.py")
execfile(activate_env, dict(__file__=activate_env))
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
in my settings.py I have two lines for redirecting after login and logout. These are not prepended with index.wsgi
LOGIN_REDIRECT_URL = '/login_redirect'
ACCOUNT_LOGOUT_REDIRECT_URL = "/logout_redirect"
When these urls are requested it returns 404
Reverse for 'login_redirect' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
In my html I have 4 links
<a id="logout" style="display: inline-block;" href="/index.wsgi/accounts/logout/">Logout</a>
<a id="profile" style="display: inline-block;" href="/accounts/profile">My Account</a>
<a id="signup" style="display: none;" href="/index.wsgi/accounts/signup/">Sign Up</a>
<a id="login" style="display: none;" href="/index.wsgi/accounts/login/">Sign In</a>
and as you can see 3 entries that are inserted with {% url %} are prepended automatically with /index.wsgi while the only one who is hardcoded it is not prepended. But still they work as expected.
Why do I have this /index.wsgi prepended and how can I remove it? In my development machine using django's built in server everything works fine.
I don't know if it is related but the login, logout and signup urls are provided by django-allauth.
Thank you for any answer or comment
For starters:
WSGIScriptAlias / var/www/index.wsgi
is wrong. You are missing leading slash on the path for the WSGI script.
You also should not really go sticking index.wsgi in DocumentRoot directory as you possibly are. If for some reason your VirualHost with WSGIScriptAlias isn't being used, and a .wsgi handler of wsgi-script has been setup elsewhere in the Apache configuration, it means that a URL of /index.wsgi works to access your Django with all your problems then starting from there. This is because Django will believe it is meant to prefix URLs with /index.wsgi as that ends up being the mount point of the application.
So, move your WSGI script file out of DocumentRoot directory for your server. Remove any AddHandler directive for .wsgi extension. Ensure you VirtualHost is actually being used and specifically that WSGIScriptAlias directive usage is correct.
BTW, why are you using some arbitrary persons blog post rather than the official mod_wsgi setup notes on the Django docs site.
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/modwsgi/

Categories

Resources