'flask instance' does not have attribute 'record' error - python

I have a project where I am trying to build an api using flask and python with the following structure:
graph:
-app.py
-server.py
-apis:
-__init__.py
-users.py
-transaction_functions.py
-neo4j_ops.py
In the server.py file I am trying to add authentification to the endpoints of my api which are coded in the users.py file. My server.py file looks like this:
import json
from six.moves.urllib.request import urlopen
from functools import wraps
from flask import Flask, request, jsonify, _request_ctx_stack
from flask_cors import cross_origin
from jose import jwt
AUTH0_DOMAIN = 'mydomain.eu'
API_AUDIENCE = 'https://my_audience.com'
ALGORITHMS = ["RS256"]
APP = Flask(__name__)
# Error handler
class AuthError(Exception):
def __init__(self, error, status_code):
self.error = error
self.status_code = status_code
#APP.errorhandler(AuthError)
def handle_auth_error(ex):
#some code
# Format error response and append status code
def get_token_auth_header():
"""Obtains the Access Token from the Authorization Header
"""
# some code
return token
def requires_auth(f):
"""Determines if the Access Token is valid
"""
#wraps(f)
def decorated(*args, **kwargs):
#some code
return decorated
def requires_scope(required_scope):
"""Determines if the required scope is present in the Access Token
Args:
required_scope (str): The scope required to access the resource
"""
#some code
And I keep getting this error:
Traceback (most recent call last):
File "C:\Python37\lib\site-packages\flask_restplus\api.py", line 183, in init_app
app.record(self._deferred_blueprint_init)
AttributeError: 'Flask' object has no attribute 'record'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "app.py", line 16, in <module>
api.init_app(app)
File "C:\Python37\lib\site-packages\flask_restplus\api.py", line 186, in init_app
self._init_app(app)
File "C:\Python37\lib\site-packages\flask_restplus\api.py", line 204, in _init_app
self._register_view(app, resource, *urls, **kwargs)
File "C:\Python37\lib\site-packages\flask_restplus\api.py", line 282, in _register_view
resource_func = self.output(resource.as_view(endpoint, self, *resource_class_args,
AttributeError: 'function' object has no attribute 'as_view'
As you can see the result of this printstack is not really useful at all since none of these calls comes from any of my files.
The only file involved in that is app.py and it looks like this:
from flask import Flask
from flask_restplus import Api
from apis import api
import config
import os
app = Flask(__name__)
api.init_app(app)#traceback comes from here.
app.run(host='0.0.0.0', port=8080)
The apis/__init__.py file looks like this:
from flask_restplus import Api, fields
from .users import api as users
from flask import Flask
api = Api(
title='Graph Api',
version='0.2',
)
api.add_namespace(users)
Any idea of what the issue is?
If I import app (the flask instance) from app.py into server.py and use that flask instance created in app rather than creating a new whole flask instance in server.py somehow the error goes away, but the issue is that I would then create a circular call of dependencies, so I cant do that.

You already have an app
APP = Flask(__name__)
And your error handler at least is using that
Yet, you defined a second one
app = Flask(__name__)
And __name__ here is app (the name of the file), which is probably what's breaking things and why the server file isn't broken

The problem stopped existing as soon as I went back to the version of the code of before adding the server.py file, and then I added it again. I have no clue of what the issue was though as the code is actually the same.

Related

How to use pymongo.monitoring in a Flask project with mongoengine

I am trying to add some monitoring to a simple REST web service with flask and mongoengine and have come across what I think is a lack of understanding on my part of how imports and mongoengine is working in flask applications.
I'm following pymongo's documentation on monitoring : https://pymongo.readthedocs.io/en/3.7.2/api/pymongo/monitoring.html
I defined the following CommandListener in a separate file:
import logging
from pymongo import monitoring
log = logging.getLogger('my_logger')
class CommandLogger(monitoring.CommandListener):
def started(self, event):
log.debug("Command {0.command_name} with request id "
"{0.request_id} started on server "
"{0.connection_id}".format(event))
monitoring.register(CommandLogger())
I made an application_builder.py file to create my flask App, code looks something like this:
from flask_restful import Api
from flask import Flask
from command_logger import CommandLogger # <----
from db import initialize_db
from routes import initialize_routes
def create_app():
app = Flask(__name__)
api = Api(app)
initialize_db(app)
initialize_routes(api)
return app
The monitoring only seems to works if I import : CommandLogger in application_builder.py. I'd like to understand what is going on here, how does the import affect the monitoring registration?
Also I'd like to extract monitoring.register(CommandLogger()) as a function and call it at a latter stage in my code something like def register(): monitoring.register(CommandLogger())
But this doesn't seem to work, "registration' only works when it is in the same file as the CommandLogger class...
From the MongoEngine's doc, it seems important that the listener gets registered before connecting mongoengine
To use pymongo.monitoring with MongoEngine, you need to make sure that
you are registering the listeners before establishing the database
connection (i.e calling connect)
This worked for me. I'm just initializing/registering it the same way as I did other modules to avoid circular imports.
# admin/logger.py
import logging
from pymongo import monitoring
log = logging.getLogger()
log.setLevel(logging.DEBUG)
logging.basicConfig(level=logging.DEBUG)
class CommandLogger(monitoring.CommandListener):
# def methods...
class ServerLogger(monitoring.ServerListener):
# def methods
class HeartbeatLogger(monitoring.ServerHeartbeatListener):
# def methods
def initialize_logger():
monitoring.register(CommandLogger())
monitoring.register(ServerLogger())
monitoring.register(HeartbeatLogger())
monitoring.register(TopologyLogger())
# /app.py
from flask import Flask
from admin.toolbar import initialize_debugtoolbar
from admin.admin import initialize_admin
from admin.views import initialize_views
from admin.logger import initialize_logger
from database.db import initialize_db
from flask_restful import Api
from resources.errors import errors
app = Flask(__name__)
# imports requiring app
from resources.routes import initialize_routes
api = Api(app, errors=errors)
# Logger before db
initialize_logger()
# Database and Routes
initialize_db(app)
initialize_routes(api)
# Admin and Development
initialize_admin(app)
initialize_views()
initialize_debugtoolbar(app)
# /run.py
from app import app
app.run(debug=True)
then in any module...
from admin.logger import log
from db.models import User
# inside some class/view/queryset or however your objects are written...
log.info('Saving an item through MongoEngine...')
User(name='Foo').save()
What I'm trying to figure out now is how to integrate Flask DebuggerToolbar's Logging panel with the monitoring messages from these listeners...

Django Testing: AttributeError: 'Client' object has no attribute 'get'

I am new to Django framework & I am trying write some tests for my apps in the project.Currently I have two apps hoardings & clients both have same basic CRUD features.For testing purpose I have created a test directory & it looks like this
clients
- tests
-__init__.py
- test_views.py
That's how I am maintaining my tests for both the apps.My test_views.py has following code,
from django.test import TestCase
from django.urls import reverse
from hoardings.models import State, City
from clients.models import Client
class ClientManagementTest(TestCase):
def setUp(self):
self.state = State.objects.create(desc='West Bengal')
self.city = City.objects.create(state=self.state, desc='Kolkata')
self.client = Client()
def test_client_creation_form_can_be_rendered(self):
response = self.client.get(reverse('clients:create'))
# Check that the response is 200 OK.
self.assertEqual(response.status_code, 200)
# check if csrf token is present
self.assertContains(response, 'csrfmiddlewaretoken')
# Check that the response contains a form.
self.assertContains(response, '<form')
# assert the context values
self.assertIn('url', response.context)
self.assertIn('heading', response.context)
self.assertIn('states', response.context)
self.assertIn('client_types', response.context)
As you can see in the setup method I am creating an object of Client which is used to send the request.But every time I run the tests I get following errors,
ERROR: test_client_creation_form_can_be_rendered
(tests.test_views.ClientManagementTest)
---------------------------------------------------------------------- Traceback (most recent call last): File
"/home/ropali/Development/PythonWorkspace/hms_venv/hms/clients/tests/test_views.py",
line 19, in test_client_creation_form_can_be_rendered response =
self.client.get(reverse('clients:create')) AttributeError: 'Client'
object has no attribute 'get'
As per my understanding It means that client object is not being created so it cannot find the get attribute & I get the similar error for the POST request as well.
But one thing is bugging me that I have similar test setup for the hoardings app it runs perfectly fine.
Can anyone please help me what I am doing wrong here.Let me know if you need other details.

Does using functionality needed to interface with current app means creating view in flask?

in my flask app app/__init__.py I have included the below function
def create_app(config_filename=None):
_app = Flask(__name__, instance_relative_config=True)
with _app.app_context():
print "Creating web app",current_app.name
cors = CORS(_app, resources={r'/*': {"origins": "*"}})
sys.path.append(_app.instance_path)
_app.config.from_pyfile(config_filename)
from config import app_config
config = app_config[_os.environ.get('APP_SETTINGS', app_config.development)]
_app.config.from_object(config)
register_blueprints(_app)
# _app.app_context().push()
return _app
now I also have /app/datastore/core.py in which I have
import peewee
import os
from flask import g, current_app
cfg = current_app.config
dbName = 'clinic_backend'
def connect_db():
"""Connects to the specific database."""
return peewee.MySQLDatabase(dbName,
user=cfg['DB_USER'],
host=cfg['DB_HOST'],
port=3306,
password=cfg['DB_PWD']
)
def get_db():
""" Opens a new database connection if there is none yet for the
current application context.
"""
if not hasattr(g, 'db'):
g.db = connect_db()
return g.db
when I create my run my app start.py it creates the app object but when I try access the URL in browser I get error saying
File "/Users/ciasto/Development/python/backend/app/datastore/core.py",
line 31, in get_db
g.db = connect_db() File "/Users/ciasto/Development/python/backend/venv/lib/python2.7/site-packages/werkzeug/local.py",
line 364, in <lambda>
__setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v) File
"/Users/ciasto/Development/python/backend/venv/lib/python2.7/site-packages/werkzeug/local.py",
line 306, in _get_current_object
return self.__local() File "/Users/ciasto/Development/python/backend/venv/lib/python2.7/site-packages/flask/globals.py",
line 44, in _lookup_app_object
raise RuntimeError(_app_ctx_err_msg) RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that
needed to interface with the current application object in some way.
To solve this, set up an application context with app.app_context().
See the documentation for more information.
what am I doing wrong here?
what am I doing wrong here?
Just about everything.
Peewee already exposes database connections as a threadlocal so what you're doing is senseless. Especially given from reading your comments you are only trying to add connection hooks.
The peewee docs are QUITE CLEAR: http://docs.peewee-orm.com/en/latest/peewee/database.html#flask
As an aside, read the damn docs. How many questions have you posted already that could have been easily answered just by reading the documentation?

Service Connection via Python

I am newbiee on pyhton development and trying to make the following example work.
The following code is for service authentication. Whenever I call localhost:3000/callback through browser, I am receiving code error because it is null.
When I create a webpage on auth0, then it puts all required information and then make the source code available to use. However, code is not included. I wonder what needs to inserted.
token = get_token.authorization_code(AUTH0_CLIENT_ID,
AUTH0_CLIENT_SECRET, code,
AUTH0_CALLBACK_URL)
auth0.v3.exceptions.Auth0Error: invalid_request: Missing required
parameter: code
.env
AUTH0_CLIENT_ID=xxxxxxxxxxx
AUTH0_DOMAIN=xxxxxx.auth0.com
AUTH0_CLIENT_SECRET=v-xxxxx2yVHntpn01RoEMMxhj6RLxxxxxxxxxx
AUTH0_CALLBACK_URL=http://localhost:3000/callback
API_IDENTIFIER={API_AUDIENCE}
server.py
"""Python Flask WebApp Auth0 integration example"""
from functools import wraps
from urllib.parse import urlparse
from os import environ as env, path
import json
from auth0.v3.authentication import GetToken
from auth0.v3.authentication import Users
from dotenv import load_dotenv
from flask import Flask
from flask import redirect
from flask import render_template
from flask import request
from flask import send_from_directory
from flask import session
import constants
load_dotenv(path.join(path.dirname(__file__), ".env"))
AUTH0_CALLBACK_URL = env[constants.AUTH0_CALLBACK_URL]
AUTH0_CLIENT_ID = env[constants.AUTH0_CLIENT_ID]
AUTH0_CLIENT_SECRET = env[constants.AUTH0_CLIENT_SECRET]
AUTH0_DOMAIN = env[constants.AUTH0_DOMAIN]
#APP.route('/callback')
def callback_handling():
code = request.args.get(constants.CODE_KEY)
get_token = GetToken(AUTH0_DOMAIN)
auth0_users = Users(AUTH0_DOMAIN)
#Receive exception
token = get_token.authorization_code(AUTH0_CLIENT_ID,
AUTH0_CLIENT_SECRET, code, AUTH0_CALLBACK_URL)
user_info = auth0_users.userinfo(token['access_token'])
session[constants.PROFILE_KEY] = json.loads(user_info)
return redirect('/dashboard')
if __name__ == "__main__":
APP.run(host='0.0.0.0', port=env.get('PORT', 3000))

Flask access request data when uploading file with angular

I'm uploading a file using angular and try to access the uploaded file in flask.
This is no problem and works fine. However, when I add more request parameters I cannot seem to find them in the flask request object.
For example, uploading a file using ngFileUpload (https://github.com/danialfarid/ng-file-upload) I can specify more meta-information like this:
$scope.upload = function (file) {
Upload.upload({
url: '/api/upload',
data: {file: file, 'username': $scope.username}
})
};
where username is extra meta-information.
Here's the flask code (using Flask-Restful):
from flask import Flask, request, Response
from flask.ext.restful import Api, Resource
ALLOWED_EXTENSIONS = {'csv'}
def allowed_file(fn):
return '.' in fn and fn.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
app = Flask(__name__)
api = Api(app)
class Upload(Resource):
def post():
file = request.files['file']
fn = file.filename
if file and allowed_file(fn):
try:
# code for saving file
return Response(status=200)
except:
return Response(status=500)
return Response(status=500)
api.add_resource(Upload, '/api/upload')
In flask I can access the file through request.files['file'], but the username information/variable is nowhere to be found.
Is this not possible in flask, am I missing something, or what's going on here?
I actually think #ciacicode was right to ask you about your python code.
You are probably running into a CORS violation with Angular calling Python.
Add an import
See Flask-CORS: http://flask-cors.corydolphin.com/en/latest/index.html
from flask.ext.cors import CORS
Add CORS to your app
Simple addition to your code:
app = Flask(__name__)
cors = CORS(app)
api = Api(app)
Adding CORS made your code sample run for me.
If the CORS is not doing anything for you, then use request.values['username']

Categories