Flask Pymongo Insert - python

I'm calling db dev to insert data into its collection. But it's creating a new collection and inserting data into admin db.
from app import app
from flask import Flask
from flask import jsonify
from flask import request
from flask_pymongo import PyMongo
#app.route('/')
#app.route('/index')
def index():
return "Hello, World!"
app.config['MONGO_DBNAME'] = 'dev'
app.config['MONGO_AUTH_SOURCE'] = 'admin'
app.config['MONGO_URI'] = 'mongodb://<user>:<password>#<url>:27017/admin'
mongo = PyMongo(app)
#app.route('/mongo', methods=['GET'])
def get_all_docs():
doc = mongo.db.abcd.insert({'abcd':'abcd'})
return "Inserted"
if __name__ == '__main__':
app.run(debug=True)
Am I missing something here?
PS: I tried replacing admin with dev. It gave pymongo.errors.OperationFailure: Authentication failed. I guess thats because the authentication data is in admin db.
app.config['MONGO_URI'] = 'mongodb://<user>:<password>#<url>:27017'
This, also, didn't work.

Replacing admin with dev in MONGO_URI causes Authentication Error.
Adding authSource will authenticate with admin db.
To do this, replace admin with dev?authSource=admin
from app import app
from flask import Flask
from flask import jsonify
from flask import request
from flask_pymongo import PyMongo
#app.route('/')
#app.route('/index')
def index():
return "Hello, World!"
app.config['MONGO_URI'] = 'mongodb://<user>:<password>#<url>:27017/dev?authSource=admin'
mongo = PyMongo(app)
#app.route('/mongo', methods=['GET'])
def get_all_docs():
doc = mongo.db.abcd.insert({'abcd':'abcd'})
return "Inserted"
if __name__ == '__main__':
app.run(debug=True)

Related

How to access Flask Request header outside route method

I want to access headers for a certain API calls outside of its api route. I tried using the app_context and test_request_context but it doesn't seem to work.
from flask import Flask, request
app = Flask("app")
def access_header_for_something():
with app.test_request_context():
with app.app_context():
print(request.headers.get("Authorization"), request.host, request.path)
#app.route('/')
def index():
access_header_for_something()
return 'hello'
if __name__=="__main__":
app.run(debug=True)
Any suggestions would be really helpful
The above code snippet work with slight tweak:
from flask import Flask, request
app = Flask("app")
def access_header_for_something():
with app.app_context():
print(request.headers.get("Authorization"), request.host, request.path)
#app.route('/')
def index():
access_header_for_something()
return 'hello'
if __name__=="__main__":
app.run(debug=True)

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table even after using db.create_all()

I am getting operational error no such table when I am entering data to my database. I have tried using db.create_all(), but it is not working. This is the image of the error.
I have tried db.create_all() in app and also using terminal but it is not working.
The database is created but table is not created in it.
models.py
from flask import app
from flask_sqlalchemy import SQLAlchemy
from application import app
from application import db
class Employee(db.Model):
id = db.Column(db.Integer(),primary_key=True)
username = db.Column(db.String(length=100),nullable=False)
email_address = db.Column(db.String(length=50),nullable=False)
password_hash = db.Column(db.String(length=60),nullable=False
init.py
from os import name
from flask import Flask, current_app, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
with app.app_context():
print(current_app.name)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'this is secret key'
db = SQLAlchemy(app)
routes.py
from application import routes
import re
from flask.helpers import url_for
from wtforms.form import Form
from application import app
from flask import Flask, render_template,redirect,url_for,flash,request
from application.forms import EmployeeRegistration, LoginForm
from application.models import Employee
from application import db
from werkzeug.security import generate_password_hash,check_password_hash
#app.route('/')
def index():
return render_template('index.html')
#app.route('/home')
def home():
return render_template('home.html')
#app.route('/register',methods=['GET','POST'])
def register():
form = EmployeeRegistration()
if form.validate_on_submit():
employee_to_create = Employee(
username=form.username.data,
email_address = form.email_address.data,
password_hash= generate_password_hash(form.password1.data)
)
db.session.add(employee_to_create)
db.session.commit()
return redirect(url_for('home'))
if form.errors != {}:# if there are not errors from the validations
for err_msg in form.errors.values():
flash(f"There was an error : {err_msg}",category='danger')
return render_template('register.html',form=form)
#app.route('/login',methods=['GET','POST'])
def login():
form = LoginForm()
return render_template('login.html',form=form)

Flask throws error in run_wsgi_app function

I am setting up my first Flask application and i have followed the documenation from http://flask.pocoo.org/docs/1.0/patterns/sqlite3/.
My app.py code is as follows:
from flask import Flask, g, render_template, request, jsonify
import sqlite3
app = Flask(__name__)
DATABASE = 'sql_db.db'
#app.route("/")
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(DATABASE)
db.row_factory = sqlite3.Row
return db
#app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
def index():
return 'It works!'
if __name__ == "__main__":
app.run(debug=True)
In the index function, I will do some queries and render a template but I can't get this basic code to work. I get the following error:
File ".../venv/lib/python2.7/site-packages/werkzeug/test.py", line 923, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: function takes exactly 1 argument (2 given)
The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a Connection.
Any ideas?
You have #app.route("/") in wrong place. It has to be before def index().
#app.route("/")
def index():
return 'It works!'
You can even see it in doc in your link: http://flask.pocoo.org/docs/1.0/patterns/sqlite3/
this here works for me, let me know if it works.
Code:
from random import randint
from time import strftime
from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField
from sklearn import tree
import mysql.connector
import pymysql
DEBUG = True
app = Flask(__name__, static_url_path='', static_folder='', template_folder='templates')
app.config.from_object(__name__)
app.instance_path, '/', ''
# app.config['SECRET_KEY'] = 'SjdnUends821Jsdlkvxh391ksdODnejdDw'
app.config['SECRET_KEY'] = 'owieihfwuefgw98rgw8o73rg7wgfwfgw87'
#app.route("/", methods=['GET', 'POST'])
def index():
return render_template('index.html', name = "nothing")
if __name__ == "__main__":
app.run(host='127.0.0.1', port=8080)
I think you need (app.run(host='127.0.0.1', port=8080)) but i'm not
sure
Happy codeing

All Flask Endpoints return 404 (Not Found)

I have an API with 12 endpoints which was working fine, then the endpoints started failing and now all return 404 status code. Here are some of my files
My run.py
import os
from app import create_app
config = os.getenv('APP_SETTINGS')
app = create_app(config)
if __name__ == "__main__":
app.run(debug=True)
I register my endpoints in app.py like so
from flask import Flask
from .api.v2.views.userview import auth
def create_app(config):
'''Creates all Flask configurations and returns app.
Expects config name'''
app = Flask(__name__, instance_relative_config=True)
app.config['JSON_SORT_KEYS'] = False
app.config.from_object(app_config[config])
app.config.from_pyfile('config.py', silent=True)
app.url_map.strict_slashes = False
app.register_blueprint(auth)
return app
And finally my endpoint user.py
from flask import request, jsonify
from flask import Blueprint
from ..models.usermodel import UserModel
usr_obj = UserModel()
auth = Blueprint('auth', __name__, '/api/v2')
#auth.route('/auth/signup', methods=['POST'])
def user_signup():
fullname = request.json['fullname']
username = request.json['username']
email = request.json['email']
password = request.json['password']
data = usr_obj.inituser(fullname, username, email, password)
return jsonify(data), 201
When I try to run this endpoint or any other in Version 1 (/api/v1) I get a Not Found error. I have also tried THIS SOLUTION with no success.
I made a silly mistake the Blueprint declaration ought to be
auth = Blueprint('auth', __name__, url_prefix='/api/v2')

Correct way to get a mongo instance in blueprints Flask

I have 3 blueprints in a flask app and the dir structure is like:
main/
__init__.py
books/
users/
authors/
apps/
Every package inisde main is a blueprint.
In my main/__init__.py i have
from flask import Flask
from flask_pymongo import PyMongo
app = Flask(__name__)
from main.users.views import users
from main.admin.views import admin
app.register_blueprint(users, url_prefix='/api/users')
MONGO_HOST = os.environ['MONGO_HOST']
MONGO_PORT = os.environ['MONGO_PORT']
app.config["MONGO_URI"] = "mongodb://{}:{}/".format(MONGO_HOST, MONGO_PORT)
mongo = PyMongo(app)
How do I access mongo inside each blueprint ? Is this even correct way of using mongo here.
in official documentation it says not to use something like db=Pymongo(app)
I guess the answer comes too late for you, but eventually it will help anyways.
I usually exclude the database-lines in an external file, e.g. database.py.
and then import the mongo instance in my app and in the blueprints, respectively. Please consider the example below. For the sake of completion and comprehension I also added other elements that make sense for the functions.
database.py
from flask_pymongo import PyMongo
mongo = PyMongo()
forms.py
from wtforms import Form
from wtforms.fields import BooleanField, PasswordField, StringField
from wtforms.validators import Email, Required
class LoginForm(Form):
email = StringField('Email', validators=[Required(), Email('Not a valid email address')])
password = PasswordField('Password',validators=[Required()])
remember = BooleanField('Remember')
authentication.py
from flask import Blueprint, redirect, render_template, request
from flask_login import LoginManager, UserMixin, current_user, login_user
from werkzeug.security import check_password_hash
from database import mongo
from forms import LoginForm
authentication = Blueprint('authentication', __name__, template_folder='templates')
login_manager = LoginManager()
login_manager.login_view = 'authentication.log_in'
#authentication.route('/login', methods=['GET', 'POST'])
def log_in():
if (current_user.is_authenticated):
return redirect(url_for('get_index'))
login_form = LoginForm(request.form)
if (request.method == 'POST'):
if (login_form.validate()):
user_collection = mongo.db.user
user = user_collection.find_one({'email':login_form.email.data})
if (user) and (check_password_hash(user['password'],
login_form.password.data)):
login_user(User(user), login_form.remember)
return redirect(url_for('get_index'))
else:
return render_template('login.html', form=login_form)
elif (request.method == 'GET'):
return render_template('login.html', form=login_form)
class User(UserMixin):
def __init__(self, user):
super()
self.id = user['_id']
self.email = user['email']
def get(user_id, mongo):
user_collection = mongo.db.user
user = user_collection.find_one({'_id':ObjectId(user_id)})
return User(user)
#login_manager.user_loader
def load_user(user_id):
return User.get(user_id, mongo)
app.py
from flask import Flask, render_template, request
from flask_login import login_required
from authentication import authentication, login_manager
from database import mongo
from forms import LoginForm
app = Flask(__name__)
app.secret_key = os.urandom(24)
app.config['MONGO_URI'] = 'mongodb:27017/app'
mongo.init_app(app)
app.register_blueprint(authentication)
login_manager.init_app(app)
#app.route('/', methods=['GET'])
#login_required
def get_index():
if (request.method == 'GET'):
render_template('index.html')
if __name__ == '__main__':
app.run(host="0.0.0.0")

Categories