Zoltan Fedor
Zoltan Fedor

Reputation: 2097

Flask shell - how to set server name for url_for _external=True?

I have a flask app running in a docker container. All works fine, except when I want to do some manual jobs in the same docker container from flask shell. The problem is that the url_for(x, _external=True) always returns https://localhost, doesn't matter how I try to set the server name in the shell. I have obviously tried setting the SERVER_NAME to no change.

$ python manage.py shell
>>> from flask import current_app
>>> current_app.config['SERVER_NAME'] = 'example.com'
>>> from app import models
>>> models.Registration.send_registration(id=123)

The jinja template is having: {{ url_for('main.index', _external=True, _scheme='https') }}

Which generates: https://localhost

I would like to get: https://example.com

I am using Flask 0.11, Werkzeug 0.11.10 and Jinja2 2.8

Upvotes: 4

Views: 13736

Answers (2)

renatodamas
renatodamas

Reputation: 19485

This solution is very similar to the one presented already, except it requires less steps:

from flask import current_app, url_for

with current_app.test_request_context('localhost.com'):
    url = url_for('index')
    ...

This way there is no need to set up the config SERVER_NAME since we are injecting a reqctx on the spot so that url_for can properly build the path. For my case I want a relative path so I don't need to add attribute _external.

Upvotes: 2

iurisilvio
iurisilvio

Reputation: 4987

Your app uses the SERVER_NAME defined when the application context was created.

If you want to do it in a shell, you can create a test request context after you set the SERVER_NAME.

>>> from flask import current_app, url_for
>>> current_app.config['SERVER_NAME'] = 'example.com'
>>> with current_app.test_request_context():
...     url = url_for('index', _external=True)
...
>>> print url
http://example.com/

We can dig in Flask code to understand it.

Flask url_for uses the appctx.url_adapter to build this URL. This url_adapter is defined when the AppContext is initialized, and it happens when the shell is started. It calls the app.create_url_adapter and it uses the defined SERVER_NAME.

Upvotes: 10

Related Questions