How can I specify the port used for the Flask url_for method? Or, can I configure Flask to use whatever port it is running on for url_for? My issue is that I'm running a server on port 8080 but url_for does not add this port to any URLs generated, so any generated URLs use port 80 and do not resolve.
It seems the only way to specify a port in url_for is to use the _external=True argument like so:
url_for('handle_contact_form', _external=True)
This generates a URL like http://localhost:5000/contact-us. Unfortunately a :5000/contact-us isn't a valid relative URL. So without using a full, external URL, the port cannot be specified.
Related
I am deploying my project in production server but the port number is coming in the url.
So is there any way to remove the port number from url in Django
http://domain_name:8586/admin/login?next=/
You need to change django's default port to 80. Because all browsers(clients) will test port 80 if you don't enter any port
If you run your app on port 80 (the default port for http) you won't need to write the port number to access it.
Any client (browser) will try port 80 if no port number was specified.
This will help:
from urllib.parse import urlparse
in_url = "http://domain_name:8586/admin/login?next=/"
parser_url = urlparse(in_url)
out_url = parser_url._replace(netloc=parser_url.netloc.replace(str(parser_url.port), "")).geturl()
print(out_url)
Since my app has background tasks, I use the Flask context. For the context to work, the Flask setting SERVER_NAME should be set.
When the SERVER_NAME is set the incoming requests are checked to match this value or the route isn't found. When placing an nginx (or other webserver in front), the SERVER_NAME should also include the port and the reverse proxy should handle the rewrite stuff, hiding the port number from the outside world (which it does).
For session cookies to work in modern browsers, the URL name passed by the proxy should be the same as the SERVER_NAME, otherwise the browser refuses to send the cookies. This can be solved by adding the official hostname in the /etc/hosts and setting it to 127.0.0.1.
There is one thing that I haven't figured out yet and it is the URL in the background tasks. url_for() is used with the _external option to generate URLs in the mail it sends out. But that URL includes the port, which is different from the 443 port used by my nginx instance.
Removing the port from the SERVER_NAME makes the stuff described in the first paragraph fail.
So what are my best options for handling the url_for in the mail. Create a separate config setting? Create my own url_for?
You should use url_for(location, _external=True)
or include proxy_params if you use nginx.
Heroku proxies requests from a client to server, so you have to parse the X-Forwarded-For to find the originating IP address.
The general format of the X-Forwarded-For is:
X-Forwarded-For: client1, proxy1, proxy2
Using werkzeug on flask, I'm trying to come up with a solution in order to access the originating IP of the client.
Does anyone know a good way to do this?
Thank you!
Werkzeug (and Flask) store headers in an instance of werkzeug.datastructures.Headers. You should be able to do something like this:
provided_ips = request.headers.getlist("X-Forwarded-For")
# The first entry in the list should be the client's IP.
Alternately, you could use request.access_route (thanks #Bastian for pointing that out!):
provided_ips = request.access_route
# First entry in the list is the client's IP
This is what I use in Django. See this https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.get_host
Note: At least on Heroku HTTP_X_FORWARDED_FOR will be an array of IP addresses. The first one is the client IP the rest are proxy server IPs.
in settings.py:
USE_X_FORWARDED_HOST = True
in your views.py:
if 'HTTP_X_FORWARDED_FOR' in request.META:
ip_adds = request.META['HTTP_X_FORWARDED_FOR'].split(",")
ip = ip_adds[0]
else:
ip = request.META['REMOTE_ADDR']
I need configure flask application to handle requests with any host in HTTP header
If some fqdn is specified in SERVER_NAME I have 404 error if request goes with any other domain.
How should be defined SERVER_NAME in configuration?
How can be requested/routed/blueprint-ed HTTP hostname?
Use app.run(host='0.0.0.0') if you want flask to accept any host name.
To allow any domain name just remove 'SERVER_NAME' from application config
I have managed to to install flask and run the hello-world script:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
I was impressed how easy it was. Then I wanted to make my web-server visible externally. As recommended, I put host='0.0.0.0' as the argument of run function. Then I found my IP address (in Google) and put it in the address line of my web browser (while the hello-world-script was running).
As a result I got: "A username and password are being requested" and a dialogue box where I need to put a user name and password. I am not sure but I think it comes from my wireless network. Is there a way to change this behaviour?
How are you trying to run your application? If you run flask as app.run() - flask creates its own WSGI server on your host (by default 127.0.0.1) and port (by default 5000) (need permissions if port < 1000). If you run flask using nginx + WSGI or etc. your server resolves host and port.
Now it looks like you want get application by port which resolved your server like nginx or Apache. Try to get flask application by http://your-server-host-or-ip:5000 with the default port or try to change the port (set explicit) like app.run('0.0.0.0', 8080) and get it by http://your-server-host-or-ip:8080.
By the way, you can always get IP address using command-line tools e.g. ifconfig for Unix-like systems, or ipconfig /all for Windows.
To elaborate a little bit onto what #tbicr said, that password prompt indicates that you're trying to connect to your IP on port 80, which is most likely hosting an administration page for your router/modem. You want to connect to your IP on port 5000, the default port for Flask apps run with app.run().