Attempting Docker get-started example I continue to get the indentation error message included at the bottom of this question and I cannot diagnose the problem. I have edited the copy/paste version from the link to "look like" the browser view and have replaced all Tabs with 4 spaces. But I do not understand the code itself well enough to know if the browser indented view looks like its meant to or not.
My version of the app.py code is as follows.
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
#app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
The error is enclosed in the console session below.
server:docker0 brian$ docker run -p 4000:80 friendlyhello
File "app.py", line 15
except RedisError:
^
IndentationError: unexpected indent
server:docker0 brian$
How can I fix the error?
While continuing to debug, as a test I deleted the word RedisError from the except line. But the error message still contained RedisError. That was my clue that the app.py I thought was being executed was not being executed. I had to execute docker build ./ -t friendlyhello again before I could docker run.
Related
I'm trying to run my code from the terminal to my local host using python3 command but its not running on the server for some reason. Can anyone help?
Here is my code to connect to web server.
from flask import Flask
from flask import request
from flask import Response
import keywordnum
app_first = Flask(__name__)
#app_first.route("/")
def key():
word=request.args.get('word')
len=keywordnum.count(word)
reply=str(len)
r= Response(response=reply, status=200)
return r
if__name__=='__main__'
app_first.run(host="0.0.0.0",port=4000)
Check your indentation, python is strict with it. The following line
if__name__=='__main__'
should be rewritten as follows:
if __name__=='__main__':
Indentation in python allows for a clearer code.
I have a very basic Heroku web app where you can click on links (on the main page) to be redirected to other pages. I have done this to test the database page. All the pages work apart from when I click to view the database page. when I try I get an error message:
Internal Server Error
The server encountered an internal error and was unable to complete
your request.
Either the server is overloaded or there is an error in
the application.
I did try to play around with the procfile but in the end nothig worked. My current proctfile looks like this:
web: gunicorn flask-sqlalchemy-test-02.wsgi:application --log-file=-
To be honest I'm not too sure if its the procfile or the sytax in app.py which is causing me problems.
My app.py file:
import os
import psycopg2
from flask import Flask, render_template, g, url_for
app = Flask(__name__)
DATABASE_URL = os.environ.get('postgres://fikwczdiymxhwf:73bf42c2c8a15fa59b77e93654b6383e1cf4f85bdf0156818d1cf39a77815f13#ec2-54-243-47-196.compute-1.amazonaws.com:5432/d3uburco4fea1b'
#app.route('/')
def index():
return render_template("index.html")
#app.route('/page2')
def page_2():
return render_template("random_page_2.html")
#app.route('/hello')
def hello():
return render_template("hello.html")
#app.route('/view_database')
def view_db():
conn = psycopg2.connect(DATABASE_URL)
db = conn.cursor()
data = db.execute("SELECT * FROM example").fetchall()
db.close()
conn.close()
return render_template('view_database.html', data=data)
I expected to view the database in a form of an unordered list but recieved an error message instead:
Internal Server Error
The server encountered an internal error and was unable to complete your request.
Either the server is overloaded or there is an error in the application.
The way you are using os.environ.get() is wrong.
os.environ.get() is used to obtain environment variables that are exported by your OS, so DATABASE_URL returns None, you cannot connect to None URL, so internal server error.
**Correct Way : **
First, export the environment variable, if using Linux :
export DATABASE_URL=postgres://fikwczdiymxhwf:73bf42c2c8a15fa59b77e93654b6383e1cf4f85bdf0156818d1cf39a77815f13#ec2-54-243-47-196.compute-1.amazonaws.com:5432/d3uburco4fea1b
Then, in your code, replace that line as :
DATABASE_URL = os.environ.get('DATABASE_URL', '')
I am following the docker tutorials from the docker website (https://docs.docker.com/get-started/part2/) and trying to run an app (app.py - code given below) after building the image "friendlyhello". However when I try to run the app, I get the below error. I guess it is something to do with the code (app.py)
I have built the docker image successfully. However when I try to run the app which is to display the output in the browser, I get an error as
Name error: name "null" is not defined as shown in the screenshot below
I believe this because of the json format of the app.py which has a parameter execution_count and value as null. I understand pYthon has "None" but when I manually change it run, it still throws the same error
App.py - from the tutorial website
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2,
socket_timeout=2)
app = Flask(__name__)
#app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
v isits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"),
hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
JSON format - autogenerated - I only have Jupyter notebook and don't have pycharm in my system to open it. Not sure whether how is this json format generated.
I expect the output to be able to run the docker image and see the output as shown in the image below
Output
I am trying to test a Flask web app within a docker container, which is new for me. My stack is the following:
firefox
selenium
pytest-selenium
pytest-flask
Here is my Flask app file:
from flask import Flask
def create_app():
app = Flask(__name__)
return app
app = create_app()
#app.route('/')
def index():
return render_template('index.html')
Now, my test file which verifies the title of my index page:
import pytest
from app import create_app
# from https://github.com/pytest-dev/pytest-selenium/issues/135
#pytest.fixture
def firefox_options(request, firefox_options):
firefox_options.add_argument('--headless')
return firefox_options
# from https://pytest-flask.readthedocs.io/en/latest/tutorial.html#step-2-configure
#pytest.fixture
def app():
app = create_app()
return app
# from https://pytest-flask.readthedocs.io/en/latest/features.html#start-live-server-start-live-server-automatically-default
#pytest.mark.usefixtures('live_server')
class TestLiveServer:
def test_homepage(self, selenium):
selenium.get('http://0.0.0.0:5000')
h1 = selenium.find_element_by_tag_name('h1')
assert h1 == 'title'
When I run my tests with:
pytest --driver Firefox --driver-path /usr/local/bin/firefox test_app.py
I get the following error (which seems due to firefox not in headless mode).
selenium.common.exceptions.WebDriverException: Message: Service /usr/local/bin/firefox unexpectedly exited. Status code was: 1
Error: no DISPLAY environment variable specified
I am able to run firefox --headless but it seems my pytest fixture didn't manage to do the setup. Is there a better way to do this?
Now, if I replace selenium.get() by urlopen just to try the correct initialization of the app and its connection:
def test_homepage(self):
res = urlopen('http://0.0.0.0:5000')
assert b'OK' in res.read()
assert res.code == 200
I get the error:
urllib.error.URLError:
Do I need to boot the live server differently? Or should I change my host + port config somewhere?
Regarding the problem with a direct call with urllib:
Pytest's live server uses random port by default. You can add this parameter to pytest invocation:
--live-server-port 5000
Or without this parameter you can make direct calls to live server like:
import pytest
import requests
from flask import url_for
#pytest.mark.usefixtures('live_server')
def test_something():
r = requests.get(url_for('index', _external=True))
assert r.status_code == 200
I suppose you have view function called index. It would add a correct port number automatically.
But this doesn't have to do anything with docker, how do you run it?
Regarding the problem with Selenium itself - I can imagine docker networks related problem. How do you use it? Do you have eg. docker-compose configuration? Can you share it?
The referenced pytest-selenium issue has:
#pytest.fixture
def firefox_options(firefox_options, pytestconfig):
if pytestconfig.getoption('headless'):
firefox_options.add_argument('-headless')
return firefox_options
Note the - (single dash) preceding headless in add_argument()
(Source)
For late comers, it might be worthwhile taking a look at Xvfb and even more helpful can be this tutorial
Then (in Linux shell) you can enter:
Xvfb :99 &
export DISPLAY=:99
pytest --driver Firefox --driver-path /usr/local/bin/firefox test_app.py
This provides a virtual frame buffer (fake screen) for the application and it outputs all the graphical content there.
Note that I did not encountered this problem, just providing a solution that helped me overcome the mentioned error with an another app.
I'm using flask_simpleldap and am struggling to get a bind connection to do anything useful.
My LDAP server is active directory.
The stripped down code looks as follows, and looks almost identical to the example:
from flask import Flask
from flask_simpleldap import LDAP
app = Flask(__name__)
app.secret_key = 'super secret key'
app.debug = True
app.config['LDAP_HOST'] = 'my-ldap-host.example.com'
app.config['LDAP_REALM_NAME'] = 'LDAP Authentication'
app.config['LDAP_SCHEMA'] = 'ldaps'
app.config['LDAP_PORT'] = 636
app.config['LDAP_BASE_DN'] = 'dc=example,dc=com'
app.config['LDAP_USERNAME'] = 'binduser#example.com'
app.config['LDAP_PASSWORD'] = 'binduser_pw'
app.config['LDAP_OBJECTS_DN'] = 'distinguishedName'
app.config['LDAP_OPENLDAP'] = False
ldap = LDAP(app)
#app.route('/ldap')
#ldap.basic_auth_required
def ldap_protected():
return 'Welcome, {0}!'.format(g.ldap_username)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
When running the flask app, i'll get an error such as this:
LDAPException: Operations error
While trying to troubleshoot, i've modified flask_simpleldap __init__.py file to show the info as well as the desc of the error, on line 274; Now i get a bit more info about the error:
LDAPException: 000004DC: LdapErr: DSID-0C090752,
comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v2580
So, i guess what i need to understand is why my initial bind won't work... do i have something wrong in my app.config?
Not sure what the problem could be... ldapsearch seems to work from a shell as such:
ldapsearch -x -LLL -E pr=200/noprompt -h my-ldap-host.example.com -D "binduser#example.com" -w 'binduser_pw' -b "dc=example, dc=com" -s sub "(sAMAccountName=binduser)" | grep distinguishedName
distinguishedName: CN=Bind User,OU=Some_OU,DC=example,DC=com
Other details:
I've tried on python2.7 and 3.5, same issues
Centos 7.2
Active Directory is my LDAP server
Any help appreciated, thanks.
Not sure if this is going to be helpful, but I've just set flask_simpleldap to work with our test Active directory instance. The only relevant difference is that I had to use:
app.config['LDAP_USE_SSL'] = True
I think I've also seen "Operations Error" when I had invalid DN or username format.
Your username must be fully qualified.
app.config['LDAP_USERNAME'] = 'uid=binduser,dc=example,dc=com'