Application Factory Pattern: AttributeError: 'tuple' object has no attribute 'shell_context_processor' [closed] - python-3.x

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am trying to cast my Flask app into a App Factory Pattern, but I got stuck on the following error:
Traceback (most recent call last):
File "/usr/local/bin/flask", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 967, in main
cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/decorators.py", line 73, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 848, in run_command
app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 305, in __init__
self._load_unlocked()
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 330, in _load_unlocked
self._app = rv = self.loader()
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 388, in load_app
app = locate_app(self, import_name, name)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 240, in locate_app
__import__(module_name)
File "/home/chrdina/python/werda/werda.py", line 7, in <module>
#app.shell_context_processor
AttributeError: 'tuple' object has no attribute 'shell_context_processor'
I tried to find out where the AttributeError happens, but I'm totally stuck. I don't unterstand where the mentioned tuple is located in my code. I tried deleting the shell_context_processor part, but then the app seems to not know it's an app at all and throws this "Error: Failed to find Flask application or factory in module "werda". Use "FLASK_APP=werda:name to specify one.").
If I then try to export FLASK_APP again (it's already set in my .flaskenv) nothing changes.
I define the shell_context_processor in my werda.py (which is my app) in the top level of my directory.
werda.py:
from app import create_app, db
from app.models import User, Role, Employee, Language, Employee_Languages, Attendance, AttendanceArchive
app = create_app()
#app.shell_context_processor
def make_shell_context():
return {'db': db, 'User': User, 'Role': Role, 'Employee':Employee, 'Language':Language, 'Employee_Languages':Employee_Languages, 'Attendance':Attendance, 'AttendanceArchive':AttendanceArchive}
init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_admin import Admin
from flask_bootstrap import Bootstrap
from flask_security import Security, SQLAlchemyUserDatastore
from flask_mail import Mail
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from config import Config
db = SQLAlchemy()
migrate = Migrate()
bootstrap = Bootstrap()
from app.models import User, Role
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security()
mail = Mail()
admin = Admin()
def create_app(config_class=Config):
app=Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
migrate.init_app(app, db)
from app.models import User, Role
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security.init_app(app, user_datastore)
bootstrap.init_app(app)
mail.init_app(app)
app.config['FLASK_ADMIN_SWATCH'] = 'cerulean'
from app.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from app.main import bp as main_bp
app.register_blueprint(main_bp)
admin = Admin(app, name='werda', template_mode='bootstrap3')
#send errors via mail:
if not app.debug:
if app.config['MAIL_SERVER']:
auth = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
secure = None
if app.config['MAIL_USE_TLS']:
secure = ()
mail_handler = SMTPHandler(
mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
fromaddr='no-reply#' + app.config['MAIL_SERVER'],
toaddrs=app.config['ADMINS'], subject='werda Failure',
credentials=auth, secure=secure)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
#save errors to log file:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/werda.log', maxBytes=10240,
backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('werda startup')
return app, admin
from app import models
Directory Structure
.
├── app
│   ├── cli.py
│   ├── errors
│   │   ├── handlers.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── main
│   │   ├── forms.py
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   └── routes.py
│   ├── models.py
│   └── templates
│   ├── addnextweek.html
│   ├── base.html
│   ├── errors
│   │   ├── 403.html
│   │   ├── 404.html
│   │   └── 500.html
│   ├── index.html
│   ├── movetoarchive.html
│   ├── nextweek.html
│   ├── now.html
│   ├── russ.html
│   ├── security
│   │   ├── login_user.html
│   │   └── register_user.html
│   ├── thisweek.html
│   ├── thisweek_working.html
│   └── today.html
├── app.db
├── config.py
├── libc6_2.31-0ubuntu8+lp1871129~1_amd64.deb
├── README.md
├── requirements.txt
├── werda.py

Consider to use the init_app() function in your factory function. You also should modify your app.config.from_object(Config) to app.config.from_object(class_config)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_admin import Admin
from flask_bootstrap import Bootstrap
from flask_security import Security, SQLAlchemyUserDatastore
from flask_mail import Mail
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from config import Config
from app.models import User, Role #<-----------repositioned
db = SQLAlchemy()
migrate = Migrate()
bootstrap = Bootstrap()
user_datastore = SQLAlchemyUserDatastore() #<-------------modified
security = Security()
mail = Mail()
admin = Admin()
def create_app(config_class=Config):
app=Flask(__name__)
app.config.from_object(class_config) #<------modified
db.init_app(app)
migrate.init_app(app, db)
user_datastore.init_app = SQLAlchemyUserDatastore(app, db, User, Role) #<-------modified
security.init_app(app, user_datastore)
bootstrap.init_app(app)
mail.init_app(app)
app.config['FLASK_ADMIN_SWATCH'] = 'cerulean'
from app.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from app.main import bp as main_bp
app.register_blueprint(main_bp)
admin = Admin(app, name='werda', template_mode='bootstrap3')
#send errors via mail:
if not app.debug:
if app.config['MAIL_SERVER']:
auth = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
secure = None
if app.config['MAIL_USE_TLS']:
secure = ()
mail_handler = SMTPHandler(
mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
fromaddr='no-reply#' + app.config['MAIL_SERVER'],
toaddrs=app.config['ADMINS'], subject='werda Failure',
credentials=auth, secure=secure)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
#save errors to log file:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/werda.log', maxBytes=10240,
backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('werda startup')
return app, admin
from app import models

I got it!
I return'ed app and admin in create_app(), which caused the problem. And it seems that's also where the mysterious Tuple was situated.
If create_app() only return's app my app starts as it should. Now to work out how to run flask-admin correctly.
Corrected code for now:
init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_admin import Admin
from flask_bootstrap import Bootstrap
from flask_security import Security, SQLAlchemyUserDatastore
from flask_mail import Mail
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from config import Config
db = SQLAlchemy()
migrate = Migrate()
bootstrap = Bootstrap()
from app.models import User, Role
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security()
mail = Mail()
admin = Admin()
def create_app(config_class=Config):
app=Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
migrate.init_app(app, db)
from app.models import User, Role
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security.init_app(app, user_datastore)
bootstrap.init_app(app)
mail.init_app(app)
app.config['FLASK_ADMIN_SWATCH'] = 'cerulean'
from app.errors import bp as errors_bp
app.register_blueprint(errors_bp)
from app.main import bp as main_bp
app.register_blueprint(main_bp)
admin = Admin(app, name='werda', template_mode='bootstrap3')
#send errors via mail:
if not app.debug:
if app.config['MAIL_SERVER']:
auth = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
secure = None
if app.config['MAIL_USE_TLS']:
secure = ()
mail_handler = SMTPHandler(
mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
fromaddr='no-reply#' + app.config['MAIL_SERVER'],
toaddrs=app.config['ADMINS'], subject='werda Failure',
credentials=auth, secure=secure)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
#save errors to log file:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/werda.log', maxBytes=10240,
backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('werda startup')
return app #deleted admin here
from app import models

Related

azure function app python module import failure

I'm not able to execute my cloud function due to failures to import modules, module azure-identity for example, it's telling me module not found, I had my requirements.txt file:
msrestazure
azure-identity
azure.keyvault.secrets
azure-cli
and my code imports:
import logging
import json
import base64
import azure.functions as func
import requests
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.compute import ComputeManagementClient
import os
Result: Failure Exception: ModuleNotFoundError: No module named 'azure.identity'. Troubleshooting Guide: https://aka.ms/functions-modulenotfound Stack: File "/azure-functions-host/workers/python/3.6/LINUX/X64/azure_functions_worker/dispatcher.py", line 318, in _handle__function_load_request func_request.metadata.entry_point) File "/azure-functions-host/workers/python/3.6/LINUX/X64/azure_functions_worker/utils/wrappers.py", line 42, in call raise extend_exception_message(e, message) File "/azure-functions-host/workers/python/3.6/LINUX/X64/azure_functions_worker/utils/wrappers.py", line 40, in call return func( * args, ** kwargs) File "/azure-functions-host/workers/python/3.6/LINUX/X64/azure_functions_worker/loader.py", line 85, in load_function mod = importlib.import_module(fullmodname) File "/usr/local/lib/python3.6/importlib/init.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "/home/site/wwwroot/dworkerfn/init.py", line 6, in from azure.identity import AzureCliCredential**
My files hierarchy:
├── dworkerfn
│   ├── function.json
│   ├── __init__.py
│   ├── launch-worker.sh
│   └── sample.dat
├── host.json
└── requirements.txt
This issue is not related to the module itself, I tried with different modules, requests for example and always the same issue.

AWS SAM Nested Application in Python with Dynamorm

I am using AWS SAM to build a Serverless application. I followed the instruction to build a nested application.
My application structure is basically the following:
.
├── MAKEFILE
├── README.md
├── __init__.py
├── apps
│ ├── __init__.py
│ ├── account
│ │ ├── __init__.py
│ │ ├── endpoints.py
│ │ ├── models.py
│ │ ├── requirements.txt
│ │ └── template.yaml
├── samconfig.toml
└── template.yaml
The requirements.txt in the folder apps/account/ has the following python packages: boto3 marshmallow and dynamorm.
The sam build and sam deploy works fine and the lambda functions are deployed correctly. However, I receive an error when calling the lambda function. The logs show the following error Unable to import module 'endpoints': No module named 'dynamorm'.
Here are excerpts from my code:
endpoints.py
import json
import boto3
from models import Account
print('Loading function')
def account_info(event, context):
apiKey = event["requestContext"]["identity"]["apiKeyId"]
account_info = Account.get(id= apiKey)
return {
"statusCode": 200,
"body": json.dumps(account_info)
}
models.py
import datetime
from dynamorm import DynaModel, GlobalIndex, ProjectAll
from marshmallow import Schema, fields, validate, validates, ValidationError
class Account(DynaModel):
# Define our DynamoDB properties
class Table:
name = 'XXXXXXXXXX'
hash_key = 'id'
read = 10
write = 5
class Schema:
id = fields.String(required=True)
name = fields.String()
email = fields.String()
phonenumber = fields.String()
status = fields.String()
I am not sure what am I missing? Are there additional instructions to build a nested app in SAM?
Thank you so much for the help!
According to https://github.com/awslabs/aws-sam-cli/issues/1213, this feature is not supported yet.
In my case, I did 'sam build' on every nested stacks and fix parent yaml template as following (use template.yaml generated by sam build command), then works. But just workaround and not nice way.
XXX_APP:
Type: AWS::Serverless::Application
Properties:
Location: nest_application/.aws-sam/build/template.yaml

How to get data from BigQuery in React.js app?

What I want to do and the problem
I want to access a table in the BigQuery, but got error like
TypeError: fs.createReadStream is not a function
at GoogleAuth.getClient (googleauth.js:497)
at GoogleAuth.authorizeRequest (googleauth.js:530)
at BigQuery.makeAuthenticatedRequest (util.js:374)
at BigQuery.request_ (service.js:129)
at BigQuery.request (service.js:140)
at BigQuery.createJob (bigquery.js:942)
at BigQuery.wrapper (index.js:42)
at BigQuery.createQueryJob (bigquery.js:862)
at BigQuery.wrapper (index.js:42)
at BigQuery.query (bigquery.js:1264)
at index.js:69
at new Promise (<anonymous>)
at BigQuery.wrapper (index.js:54)
at Signup.handleClick (Signup.js:52)
at HTMLUnknownElement.callCallback (react-dom.development.js:336)
at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
at invokeGuardedCallback (react-dom.development.js:440)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:454)
at executeDispatch (react-dom.development.js:584)
at executeDispatchesInOrder (react-dom.development.js:609)
at executeDispatchesAndRelease (react-dom.development.js:713)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js:722)
at forEachAccumulated (react-dom.development.js:694)
at runEventsInBatch (react-dom.development.js:739)
at runExtractedPluginEventsInBatch (react-dom.development.js:880)
at handleTopLevel (react-dom.development.js:5803)
at batchedEventUpdates$1 (react-dom.development.js:24401)
at batchedEventUpdates (react-dom.development.js:1415)
at dispatchEventForPluginEventSystem (react-dom.development.js:5894)
at attemptToDispatchEvent (react-dom.development.js:6010)
at dispatchEvent (react-dom.development.js:5914)
at unstable_runWithPriority (scheduler.development.js:697)
at runWithPriority$2 (react-dom.development.js:12149)
at discreteUpdates$1 (react-dom.development.js:24417)
at discreteUpdates (react-dom.development.js:1438)
at dispatchDiscreteEvent (react-dom.development.js:5881)
My Codes
First, I want to check the code with simple code. There is a button and when clicked it, the handleClick function works. All element for access BigQuery are in this function for now.
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import PersonIcon from '#material-ui/icons/Person';
import Typography from '#material-ui/core/Typography';
import Container from '#material-ui/core/Container';
class Signup extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(event) {
const { BigQuery } = require('#google-cloud/bigquery');
const bigquery = new BigQuery({
projectId: '(PROJECT_ID)',
keyFilename: '../../credentials/(credential file name).json',
});
const query = `
SELECT *
FROM \`(PROJECT_ID).paper_list.user_auth_info\`;
`
bigquery.query(query)
.then(data => {
const rows = data[0];
rows.forEach(row => alert("Hello"));
})
.catch(err => console.log(err));
}
render() {
const { classes } = this.props;
return (
<Container
component="main"
maxWidth="xs"
className={classes.outer}
>
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<PersonIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign Up
</Typography>
<form className={classes.form} noValidate>
<Button
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={this.handleClick}
>
Sign Up
</Button>
</form>
</div>
</Container>
);
}
}
The directory structure is like following,
.
├── Dockerfile
├── README.md
├── app.yaml
├── credentials # <- credential file is in this directory
├── node_modules
├── package-lock.json
├── package.json
├── public
└── src
├── App.css
├── App.js
├── App.test.js
├── Main.js
├── components
│   ├── AddFile.js
│   ├── Footer.js
│   ├── Header.js
│   ├── Inner.js
│   ├── Login.js
│   ├── PaperFolder.js
│   ├── PaperInfo.js
│   ├── PaperLabels.js
│   ├── SearchResultTable.js
│   ├── SideBar.js
│   ├── Signup.js # <- the code above
│   ├── TopLinks.js
│   └── ToppageMain.js
├── images
│   └── maarten-van-den-heuvel-8EzNkvLQosk-unsplash.jpg
├── index.css
├── index.js
├── serviceWorker.js
How to fix this error?
Thanks to the comment by Blundering Philosopher, I could understand the problem.
The BigQuery should be accessed from server-side, but the React.js is front-end, this was the problem. I wrote the API server with Go, and resolved it.

Reference module from a module in separate Terraform projects

Is it possible with Terraform to have a directory structure like the following:
├── environments
│   └── production
│   ├── app1
│   ├── instances.tf
│   ├── app2
│   └── shared
│   ├── iam.tf
│   └── security_groups.tf
└── modules
└── iam
└── node
Where environments/production/{app1, app2, shared} all each have their own terraform state and each are independent of each other. However, from app1 and app2 I need to reference module output variables like security groups, IAM etc from shared.
So environments/production/shared/iam.tf looks like:
module "iam" {
source = "../../../modules/iam"
var1 = "foo"
var2 = "bar"
var3 = "car"
var4 = "nar"
}
How then, from app1, or app2 do I reference the instance of iam from shared?
environments/production/app1/instances.tf:
module "app1" {
source = "../../../modules/node"
iam_profile_id = { how do I reference the IAM module from shared here?
// shared.module.iam.profile_id?
}

Django: Download Excel after User Clicks a Button

In my Django project, I need to send an in-memory Excel file to the client side for download. The download should start after the user clicks a button.
Here is my project structure:
C:.
│ db.sqlite3
│ manage.py
│ Pipfile
│ Pipfile.lock
│ requirements.txt
│
├───app
│ │ admin.py
│ │ apps.py
│ │ forms.py
│ │ models.py
│ │ tests.py
│ │ urls.py
│ │ views.py
│ │ __init__.py
│ │
│ ├───migrations
│ │ __init__.py
│ │
│ └───templates
│ └───app
│ home.html
│
└───project
settings.py
urls.py
wsgi.py
__init__.py
My app/forms.py:
from django import forms
class HomeForm(forms.Form):
OPTIONS = (
('name', 'name'),
('city', 'city')
)
columns = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
choices=OPTIONS)
My app/views.py:
from django.views.generic import TemplateView
from django.shortcuts import render
from app.forms import HomeForm
class HomeView(TemplateView):
template = 'app/home.html'
def get(self, request):
form = HomeForm()
return render(request, self.template, {'form': form})
This is my app/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.HomeView.as_view(), name="home"),
]
My project/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('app.urls')),
path('admin/', admin.site.urls),
]
My app/home.html:
<!DOCTYPE html>
<html>
<head>
<title>Generate Data</title>
</head>
<body>
<form method="get">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Generate Excel">
</form>
</html>
</body>
The page with the checkboxes
I’m new to Django. How can I get the columns (name, city) as a list, create a dictionary {‘name’: [‘Bob’, ‘Tom’], ‘city’: [‘San Francisco’, ‘Atlanta’]}, and use the dictionary in the following function, which creates in-memory Excel data:
import pandas as pd
from io import BytesIO as IO
from django.http import HttpResponse
import xlsxwriter
def write_to_excel():
df_output = pd.DataFrame({'name': ['Bob', 'Tom'], 'city': ['San Francisco', 'Atlanta']})
# my "Excel" file, which is an in-memory output file (buffer)
# for the new workbook
excel_file = IO()
xlwriter = pd.ExcelWriter(excel_file, engine='xlsxwriter')
df_output.to_excel(xlwriter, 'sheetname')
xlwriter.save()
xlwriter.close()
# important step, rewind the buffer or when it is read() you'll get nothing
# but an error message when you try to open your zero length file in Excel
excel_file.seek(0)
# set the mime type so that the browser knows what to do with the file
response = HttpResponse(excel_file.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
# set the file name in the Content-Disposition header
response['Content-Disposition'] = 'attachment; filename=myfile.xlsx'
return response
When a user clicks the Generate Excel button, the Excel file with the data should be downloaded. I've given all of this code because I think it's necessary for someone to help me.

Resources