Internal servor error response from the flask application - flask

Hello i am writing the following code to authenticate the username and password and execute a entry method code if the given credentials are valid. But i am getting internal server error.Can someone help where it is getting wrong. My target is to execute a block of code if the credentials are matching.
#import statements
import Example
import Example2
import logging
from flask import Flask
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import generate_password_hash, check_password_hash
#Creating the logge r variables and intialization
log=logging.getLogger()
format = "%(asctime)s %(message)s"
logging.basicConfig(format=format, level=logging.INFO, filename='Job_history_logs.log')
#Starting the Flask application
app = Flask(__name__)
auth = HTTPBasicAuth()
#users
users = {
"john": generate_password_hash("hello"),
"susan": generate_password_hash("bye")
}
#app.route('/todo/api/v1.0/tasks', methods=['GET'])
#auth.login_required
#auth.verify_password
def verify_password(username, password):
log.info("Username provided is "+ str(username))
log.info("password provided is "+ str(password))
if username in users:
log.info("Hash comparision is "+ str(check_password_hash(users.get(username), password)))
if check_password_hash(users.get(username), password):
return True
#auth.error_handler
def unauthorized():
return make_response(jsonify({'error': 'Unauthorized access'}), 401)
def entry():
result1 = Example.external()
result2 = Example2.external2()
log.info("result1 is "+str(result1))
log.info(str(result2))
return str(result1)+"...."+str(result2)
if __name__ == '__main__':
app.run(host='0.0.0.0')

I was able to run this application with simple changes in the sequence of usage of #auth_decorators.
working code
#import statements
import logging
from external import star_matrix
from flask_httpauth import HTTPBasicAuth
from flask import Flask
from werkzeug.security import generate_password_hash, check_password_hash
#Creating an object
log=logging.getLogger()
format = "%(asctime)s %(message)s"
logging.basicConfig(format=format, level=logging.INFO, filename='Job_history_logs.log')
app = Flask(__name__)
auth = HTTPBasicAuth()
#users
users = {
"john": generate_password_hash("hello"),
"susan": generate_password_hash("bye")
}
#auth.verify_password
def verify_password(username, password ):
log.info("Username provided is "+ str(username))
log.info("password provided is "+ str(password))
if username in users:
log.info("Hash comparision is "+ str(check_password_hash(users.get(username), password)))
if check_password_hash(users.get(username), password):
return True
#app.route('/todo/api/v1.0/tasks', methods=['GET'])
#auth.login_required
def entry():
log.info('inside the entry function')
result = star_matrix.external()
return result
if __name__ == '__main__':
app.run(host='0.0.0.0')

Related

How can I remove "#oidc.login_required" for unit testing from a view?

I use flask-oidc for user login and pytest for testing. For unit testing, I would like to "remove" #oidc.require_login. How can I do that?
What I tried
The way flask-o works is roughly:
from flask import Flask, url_for, redirect
from flask_oidc import OpenIDConnect
app = Flask(__name__)
app.config['OIDC_CLIENT_SECRETS'] = 'client_secrets.json'
# Contents:
# Create client_id and client_secret at https://console.developers.google.com/apis/credentials
# {
# "web": {
# "client_id": "123456789012-abc123hi09123.apps.googleusercontent.com",
# "client_secret": "ab123456789ABCDEFGHIJKLM",
# "redirect_uris": ["http://localhost:5000"],
# "auth_uri": "https://accounts.google.com/o/oauth2/auth",
# "token_uri": "https://accounts.google.com/o/oauth2/token",
# "userinfo_uri": "https://www.googleapis.com/oauth2/v3/userinfo"
# }
# }
app.config['SECRET_KEY'] = 'uq4aKjUvWXTPTIyfCz7mTtcG'
app.config['OIDC_ID_TOKEN_COOKIE_SECURE'] = False
app.config['OIDC_SCOPES'] = ["openid", "profile", "email"]
app.config['OIDC_CALLBACK_ROUTE'] = '/authorization-code/callback'
oidc = OpenIDConnect(app)
#app.route('/')
#oidc.require_login
def index():
return redirect(url_for('personalized'))
#app.route('/personalized')
#oidc.require_login
def personalized():
info = oidc.user_getinfo(['email', 'openid_id'])
return 'Hello, {} ({})'.format(info.get('email'), info.get('openid_id'))
#app.route('/hello')
#oidc.require_login
def constant():
return 'Hello'
if __name__ == '__main__':
app.run(port=5000)
Then I hoped the unit test could mock the #oidc.require_login away:
# core modules
from unittest import mock
# 3rd party modules
import pytest
# internal modules
import exampleapp
#pytest.fixture
def client():
app = exampleapp.app
client = app.test_client()
yield client
#mock.patch("flask_oidc.OpenIDConnect")
def test_private(mock_require_login, client):
rv = client.get('/hello')
assert rv.data == b'Hello'
First install blinker via pip. I'm not sure why, but it is required.
Then this works for me:
# core modules
from unittest import mock
# 3rd party modules
import pytest
from flask import appcontext_pushed, g
# internal modules
import exampleapp
#pytest.fixture
def client():
app = exampleapp.app
app.testing = True
app.before_request_funcs[None] = []
def handler(sender, **kwargs):
g.oidc_id_token = {'sub': 'some-user-id', 'email': 'foo#bar.com'}
client = app.test_client()
with appcontext_pushed.connected_to(handler, app):
yield client
def test_private(client):
with mock.patch.object(
exampleapp.oidc, "validate_token", return_value=True
):
rv = client.get('/hello')
assert rv.data == b'Hello'
Inspired by https://github.com/fedora-infra/elections

Importing flask-socketio instance from a top level file?

I have a run.py file at the top level of my directory where I initialize flask-socketio. That file looks like this:
# /run.py
#!/usr/bin/env python
import os
from src.config import app_config
from dotenv import load_dotenv, find_dotenv
from flask_socketio import SocketIO
from src.app import create_app
load_dotenv(find_dotenv())
env_name = os.getenv('FLASK_ENV')
app = create_app(env_name)
socketio = SocketIO(app, async_mode=None)
if __name__ == '__main__':
port = os.getenv('PORT')
# run app
socketio.run(app, host='0.0.0.0', port=port)
My app.py file sits under src/app.py and looks like this:
def create_app(env_name):
"""
Create app
"""
# app initiliazation
app = Flask(__name__)
app.config.from_object(app_config[env_name])
# initializing bcrypt and db
bcrypt.init_app(app)
db.init_app(app)
app.register_blueprint(message_blueprint, url_prefix='/api/v1/message')
return app
I am trying to import the socketio instance into /src/views/MessageView.py
My MessageView.py file looks like this:
from ..models import db
from __main__ import socketio
from ..shared.Authentication import Auth
from threading import Lock
from flask import Flask, render_template, session, request, \
copy_current_request_context, g, Blueprint, json, Response
from flask_socketio import SocketIO, emit, join_room, leave_room, \
close_room, rooms, disconnect
message_api = Blueprint('message_api', __name__)
thread = None
thread_lock = Lock()
def background_thread():
"""Example of how to send server generated events to clients."""
count = 0
while True:
socketio.sleep(10)
count += 1
socketio.emit('my_response',
{'data': 'Server generated event', 'count': count},
namespace='/test')
#message_api.route('/')
def index():
return render_template('index.html', async_mode=socketio.async_mode)
#socketio.on('my_event', namespace='/test')
def test_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': message['data'], 'count': session['receive_count']})
#socketio.on('my_broadcast_event', namespace='/test')
def test_broadcast_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': message['data'], 'count': session['receive_count']},
broadcast=True)
#socketio.on('join', namespace='/test')
def join(message):
join_room(message['room'])
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': 'In rooms: ' + ', '.join(rooms()),
'count': session['receive_count']})
#socketio.on('leave', namespace='/test')
def leave(message):
leave_room(message['room'])
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': 'In rooms: ' + ', '.join(rooms()),
'count': session['receive_count']})
#socketio.on('close_room', namespace='/test')
def close(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response', {'data': 'Room ' + message['room'] + ' is closing.',
'count': session['receive_count']},
room=message['room'])
close_room(message['room'])
#socketio.on('my_room_event', namespace='/test')
def send_room_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': message['data'], 'count': session['receive_count']},
room=message['room'])
#socketio.on('disconnect_request', namespace='/test')
def disconnect_request():
#copy_current_request_context
def can_disconnect():
disconnect()
session['receive_count'] = session.get('receive_count', 0) + 1
# for this emit we use a callback function
# when the callback function is invoked we know that the message has been
# received and it is safe to disconnect
emit('my_response',
{'data': 'Disconnected!', 'count': session['receive_count']},
callback=can_disconnect)
#socketio.on('my_ping', namespace='/test')
def ping_pong():
emit('my_pong')
#socketio.on('connect', namespace='/test')
def test_connect():
global thread
with thread_lock:
if thread is None:
thread = socketio.start_background_task(background_thread)
emit('my_response', {'data': 'Connected', 'count': 0})
#socketio.on('disconnect', namespace='/test')
def test_disconnect():
print('Client disconnected', request.sid)
I have spent the last two days scouring the internet for help on how to fix this. The error i receive is:
ImportError: cannot import name 'socketio'
I have tried relative imports as well as monkey_patching. But each time the error still occurs. Any ideas on how to fix the issue would be greatly appreciated.
P.S. I am adapting the example that Miguel has in his flask-socketio repo located here: link. In his example, everything sits in one file, which would work in a basic app, however, for an app with 50+ API endpoints, that is not an optimal solution.
Why do you have the SocketIO object in the top-level run.py module? Since this is a Flask extension, it is better to have it with all your other extensions in src/app.py:
from flask_socketio import SocketIO
socketio = SocketIO()
def create_app(env_name):
"""
Create app
"""
# app initiliazation
app = Flask(__name__)
app.config.from_object(app_config[env_name])
# initializing bcrypt and db
bcrypt.init_app(app)
db.init_app(app)
# initialize socketio
socketio.init_app(app)
app.register_blueprint(message_blueprint, url_prefix='/api/v1/message')
return app
Then in run.py you can import this object:
from src.app import create_app, socketio
# ...
env_name = os.getenv('FLASK_ENV')
app = create_app(env_name)
# ...
if __name__ == '__main__':
port = os.getenv('PORT')
# run app
socketio.run(app, host='0.0.0.0', port=port)
And in the same way you can import it in your MessageView.py module:
from src.app import socketio
socketio.on('whatever')
def do_something(data):
pass
I have a complete example application that uses this structure here: https://github.com/miguelgrinberg/Flask-SocketIO-Chat.

mailgun and flask forms

I keep getting the following error when I run my code:
TypeError: 'Response' object is not callable
Here is my code...
from flask import Flask, render_template, flash
import os
import requests
import forms
app = Flask(__name__)
app.secret_key = 'jfdsjajfjds'
mg_key = os.environ['MAILGUN_API_KEY']
#app.route("/", methods=('GET', 'POST'))
def landing():
form = forms.OptinForm()
if form.validate_on_submit():
return requests.post(
"https://api.mailgun.net/v3/lists/test_list#sandbox.mailgun.org/members",
auth=('api', 'mg_key'),
data={'subscribed': True,
'address': form.email.data,
'name': form.first_name.data})
flash("Thanks! Check your email.")
return render_template('landing.html', form=form)
if __name__ == "__main__":
app.run()
I figured out the problem. I was calling my API key variable as a string. fixed it by changing 'mg_key' to mg_key

how to use db instance in flask-apscheduler's jobs function

When I used flask-apscheduler(not apscheduler), I have some problems in my flask web project. Especially when I used db(flask-sqlalchemy) objects. The problem may be:
JOBS = [
{
'id': 'job1',
'func': 'app.monitor.views:test',
'args': (),
'trigger': 'interval',
'seconds': 2
}
]
./app/init.py:
from flask import Flask
from flask.ext.bootstrap import Bootstrap
from flask.ext.mail import Mail
from flask.ext.moment import Moment
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.login import LoginManager
from flask.ext.pagedown import PageDown
from flask_apscheduler import APScheduler
from celery import Celery
# from apscheduler.schedulers.blocking import BlockingScheduler
from config import config,Config
bootstrap = Bootstrap()
mail = Mail()
moment = Moment()
db = SQLAlchemy()
pagedown = PageDown()
celery = Celery(__name__, broker=Config.CELERY_BROKER_URL)
# https://pypi.python.org/pypi/Flask-APScheduler
scheduler = APScheduler()
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
mail.init_app(app)
moment.init_app(app)
db.init_app(app)
login_manager.init_app(app)
pagedown.init_app(app)
scheduler.init_app(app)
celery.conf.update(app.config)
if not app.debug and not app.testing and not app.config['SSL_DISABLE']:
from flask.ext.sslify import SSLify
sslify = SSLify(app)
from .monitor import monitor as monitor_1_0_blueprint
from .laser import laser as laser_1_0_blueprint
app.register_blueprint(monitor_blueprint,url_prefix='/monitor/api')
app.register_blueprint(laser_1_0_blueprint,url_prefix='/laser/api/v1.0')
return app
Error 1:db is : Error 2:db is :No handlers
could be found for logger "apscheduler.executors.default" Error 3:db
is : raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context
The key to the problem is to get the db and app objects in flask-apscheduler jobs function(views.py):
from app import scheduler
def test():
#to Solve the log error problem
import logging
log = logging.getLogger('apscheduler.executors.default')
log.setLevel(logging.INFO) # DEBUG
fmt = logging.Formatter('%(levelname)s:%(name)s:%(message)s')
h = logging.StreamHandler()
h.setFormatter(fmt)
log.addHandler(h)
#get the app object
app = scheduler.app
#get the db object and use it
with app.app_context():
print '........................',db
from app import scheduler#
def test():
#to Solve the log error problem
import logging
log = logging.getLogger('apscheduler.executors.default')
log.setLevel(logging.INFO) # DEBUG
fmt = logging.Formatter('%(levelname)s:%(name)s:%(message)s')
h = logging.StreamHandler()
h.setFormatter(fmt)
log.addHandler(h)
#get the app object
app = scheduler.app
#get the db object and use it
with app.app_context():
print '........................',db
def test():
#to Solve the log error problem
import logging
log = logging.getLogger('apscheduler.executors.default')
log.setLevel(logging.INFO) # DEBUG
fmt = logging.Formatter('%(levelname)s:%(name)s:%(message)s')
h = logging.StreamHandler()
h.setFormatter(fmt)
log.addHandler(h)
#get the app object
app = scheduler.app
#get the db object and use it
with app.app_context():
print '........................',db #the right db object

App engine on development environement not printing log

I am trying to print log on the local environment of Google App engine. It seems the way it should be but still i am not able to print the log. Need some helping hand here?
I need this output on the standard console.
import webapp2
from google.appengine.api import urlfetch
from Webx import WebxClass
import json
import logging
class SearchHandler(webapp2.RequestHandler):
def __init__(self,*args, **kwargs):
super(SearchHandler,self).__init__(*args, **kwargs)
self.result=[]
self.searchPortals = [WebxClass()]
self.asa = []
def handleCallBack(self,rpc,portalObject):
try:
rr = rpc.get_result()
if rr.status_code == 200:
if isinstance(portalObject, WebxClass):
resultList=portalObject.getResultList(rr.content)
self.result.extend(resultList)
except urlfetch.DownloadError:
self.result = 'Error while fetching from portal - ' + portalObject.getName()
def getSearchResult(self):
rpcs=[]
searchKeyword=self.request.get('searchString')
logging.error("------------------------------")
for portal in self.searchPortals:
rpc = urlfetch.create_rpc(deadline=5)
rpc.callback = lambda: self.handleCallBack(rpc, portal)
urlfetch.make_fetch_call(rpc, portal.getSearchURL(searchKeyword))
rpcs.append(rpc)
for rpc in rpcs:
rpc.wait()
self.response.status_int = 200
self.response.headers['Content-Type'] = 'application/json'
self.response.headers.add_header("Access-Control-Allow-Origin", "*")
self.response.write(json.dumps(self.result))
app = webapp2.WSGIApplication([
webapp2.Route(r'/search', methods=['GET'], handler='Torrent.SearchHandler:getSearchResult')
], debug=True)
def main():
logging.getLogger().setLevel(logging.DEBUG)
logging.debug("------------------------------")
app.run()
if __name__ == '__main__':
main()