App engine on development environement not printing log - python-2.7

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()

Related

Internal servor error response from the flask application

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')

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.

Issues while integrating tornado app with django site

I have a simple chat application in Tornado powered with RethinkDB.
Am trying to integrate this tornado chat application to run with django site.
For that reason, I have adopted below in rechat.py in order for it to work with django.
Namespaces tornado.wsgi and django.core.wsgi (get_wsgi_application)
Set environment variable for Django settings.py
os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoapp.settings'
When I try to run it after the above changes, it connects the db server, but doesn't do anything. What am I missing?
How can I make this tornado app to work with django 1.8 site?
Below is my code of rechat.py (https://github.com/v3ss0n/rechat) -
import logging
import tornado.escape
from tornado.ioloop import IOLoop
import tornado.web
import os.path
import rethinkdb as r
from tornado import httpserver
from time import time
# from tornado.concurrent import Future
from tornado import gen
from tornado.options import define, options, parse_command_line
import tornado.wsgi
from django.core.wsgi import get_wsgi_application
define("port", default=8888, help="run on the given port", type=int)
define("debug", default=True, help="run in debug mode")
def setup_db(db_name="rechat", tables=['events']):
connection = r.connect(host="localhost")
try:
r.db_create(db_name).run(connection)
for tbl in tables:
r.db(db_name).table_create(tbl, durability="hard").run(connection)
logging.info('Database setup completed.')
except r.RqlRuntimeError:
logging.warn('Database/Table already exists.')
finally:
connection.close()
class RechatApp(tornado.web.Application):
def __init__(self, db):
handlers = [
(r"/", MainHandler),
(r"/a/message/new", MessageNewHandler),
(r"/a/message/updates", MessageUpdatesHandler),
]
settings = dict(cookie_secret="_asdfasdaasdfasfas",
template_path=os.path.join(
os.path.dirname(__file__), "templates"),
static_path=os.path.join(
os.path.dirname(__file__), "static"),
xsrf_cookies=True,
debug=options.debug)
self.db = db
logging.info(db)
tornado.web.Application.__init__(self, handlers, **settings)
class BaseHandler(tornado.web.RequestHandler):
def initialize(self):
self.db = self.application.db
self.evt = r.table("events")
class MainHandler(BaseHandler):
#gen.coroutine
def get(self):
curs = yield self.evt.run(self.db)
messages = []
while (yield curs.fetch_next()):
item = yield curs.next()
messages.append(item)
self.render("index.html", messages=messages)
class MessageNewHandler(BaseHandler):
#gen.coroutine
def post(self):
message = {
"body": self.get_argument("body")
}
# to_basestring is necessary for Python 3's json encoder,
# which doesn't accept byte strings.
start = time()
messages = (yield self.evt.insert(message).run(self.db))
time_taken = time() - start
logging.warn("DBINSERT: %s seconds" % time_taken)
message['id'] = messages['generated_keys'][0]
message["html"] = tornado.escape.to_basestring(
self.render_string("message.html", message=message))
if self.get_argument("next", None):
self.redirect(self.get_argument("next"))
else:
self.write(message)
class MessageUpdatesHandler(BaseHandler):
#gen.coroutine
def post(self):
curs = yield self.evt.changes().run(self.db)
while (yield curs.fetch_next()):
feed = yield curs.next()
message = {
'id': feed['new_val']['id'],
'html': tornado.escape.to_basestring(
self.render_string("message.html",
message=feed['new_val']))}
break
self.finish(dict(messages=[message]))
#gen.coroutine
def main():
""" Async main method. It needed to be async due to r.connect is async . """
parse_command_line()
os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoapp.settings'
db_name = "rechat"
setup_db(db_name)
r.set_loop_type("tornado")
db = yield r.connect("localhost", db=db_name)
#Single db connection for everything thanks a lot Ben and Jeese
http_server = httpserver.HTTPServer(RechatApp(db))
http_server.listen(options.port)
if __name__ == "__main__":
IOLoop.current().run_sync(main)
IOLoop.current().start()

webtest for google app engine

Can someone please provide a multipart/form-data POST example based on:
How can I unit test responses from the webapp WSGI application in Google App Engine?
import unittest
from webtest import TestApp
from google.appengine.ext import webapp
import index
class IndexTest(unittest.TestCase):
def setUp(self):
self.application = webapp.WSGIApplication([('/', index.IndexHandler)], debug=True)
def test_default_page(self):
app = TestApp(self.application)
response = app.get('/')
self.assertEqual('200 OK', response.status)
self.assertTrue('Hello, World!' in response)
def test_page_with_param(self):
app = TestApp(self.application)
response = app.get('/?name=Bob')
self.assertEqual('200 OK', response.status)
self.assertTrue('Hello, Bob!' in response)
def test_submit_form(self):
app = TestApp(self.application)
response = app.post('/', { 'name': 'John' })
self.assertEqual('200 OK', response.status)
To test POST requests just use app.post() instead of app.get(). The second argument to app.post is your form data.
See documentation for webtest.