How do I fix an IndentationError - python

I started learning flask a few days ago from the e-book flask framework cookbook.
I am confused about the following error.
File "run.py", line 1, in <module>
from my_app import app
File "/home/kenosis/flask_app/my_app/__init__.py", line 2, in <module>
from my_app.product.views import product_blueprint
File "/home/kenosis/flask_app/my_app/product/views.py", line 10
def home():
^
IndentationError: unexpected indent
This is my views.py
from werkzeug import abort
from flask import render_template
from flask import Blueprint
from my_app.product.models import PRODUCTS
product_blueprint = Blueprint('product', __name__)
#product_blueprint.route('/')
#product_blueprint.route('/home')
def home():
return render_template('home.html', products=PRODUCTS)
#product_blueprint.route('/product/<key>')
def product(key):
product = PRODUCTS.get(key)
if not product:
abort(404)
return render_template('product.html', product=PRODUCTS)
and then this is my init
from flask import Flask
from my_app.product.views import product_blueprint
app = Flask(__name__)
app.register_blueprint(product_blueprint)
product_blueprint = Blueprint('main', __name__, template_folder='templates')
What am I doing wrong?

Indentation is very important in Python. Do not indent after the decorator
from flask import render_template, abort
from flask import Blueprint
from my_app.product.models import PRODUCTS
product_blueprint = Blueprint('product', __name__)
#product_blueprint.route('/')
#product_blueprint.route('/home')
def home():
return render_template('home.html', products=PRODUCTS)
#product_blueprint.route('/product/<key>')
def product(key):
product = PRODUCTS.get(key)
if not product:
abort(404)
return render_template('product.html', product=PRODUCTS)

Related

Mocker.patch a function when unit testing a Flask blueprint

I've got a blueprint file /views/index.py:
from flask import Blueprint, render_template
index = Blueprint('index', __name__)
def auth():
return "dog"
#index.route('/')
def index_view():
return render_template(
'index.html', user=auth())
This is initialized fine from /main.py:
from flask import Flask
from views.index import index
from views.login import login
app = Flask(__name__)
app.register_blueprint(index)
How can I mock the auth() function in my blueprint to return an override like "cat"?
Use the following /tests/test_root.py:
import sys
from pathlib import Path
sys.path.append(str(Path('.').absolute().parent))
from main import app
def test_index_route(mocker):
mocker.patch("views.index.auth", return_value="cat")
response = app.test_client().get('/')
assert response.status_code == 200
assert b"cat" in response.data
assert not b"dog" in response.data
Navigate into the /tests/ dir, run pytest and this test will pass.

how to enter url having two forward slashes in it

I am entering an url to process a file and return me an api with an output example: 12.334.198.190:5000/home/files/xyx.pdf and in my linux vm the address of the file is /home/files/xyz.pdf so the error is 'No such file or directory: home/files/xyz.pdf'. I think the '/' before home is not being picked up and thus the error. Any idea how to fix this?
Adding code for reference:
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
#categorie
#app.route('/', defaults={'path': ''})
#app.route('/<path:path>')
def get_dir(path):
categories = convert(path)
return categories
##app.route('/get_dir/<path>')
#def get_dir(path):
# return path
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)

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

Python:ValueError: Attempted relative import in non-package

I have the following package structure
This is my code in home.py
import os
from flask import Blueprint, render_template, request, flash, url_for
from .. import db
from ..models.home import Summary
from ..forms.home import SummarizerForm
from ..processing.summarizer import Summarizer
from ..helpers import flash_errors
from ..processing.newsbot import NewsBot
home = Blueprint('home', __name__)
#home.route('/', methods=['GET', 'POST'])
def index():
summary = None
url = ''
form = SummarizerForm(request.form)
if request.method == "POST" and form.validate():
summary = Summarizer(form.text.data, form.algorithm.data, form.length.data)
if summary.error:
flash(summary.error)
else:
source_url = form.text.data if form.text.data.startswith(('http://', 'https://')) else ''
summary_db_entry = Summary(
summary.bullets,
summary.highlighted_text,
source_url=source_url)
db.session.add(summary_db_entry)
db.session.commit()
url_hash = summary_db_entry.url
url = os.path.join(request.url, url_for('home.summary_entry', url_hash=url_hash)[1:])
flash_errors(form)
return render_template(
'home/index.html',
form=form,
summary=summary,
url=url
)
#home.route('/s/<url_hash>')
def summary_entry(url_hash):
summary = Summary.query.filter_by(url=url_hash).first_or_404()
source_url = summary.source_url
return render_template(
'home/summary.html',
summary=summary,
source_url=source_url
)
#home.route('/about')
#home.route('/about/')
def about():
return render_template('home/about.html')
And the init.py out of the package
from .views.home import home
I get the following error on init.py which is out of the package.
Traceback (most recent call last):
File "/Users/johnsriskandarajah/Documents/summarizer-flask-app-master/tldrapp/__init__.py", line 35, in <module>
from .views.home import home
ValueError: Attempted relative import in non-package
How can this error be fixed? I tried out most of the solutions online but couldn't find any luck.
Full project structure

flask and flask_login - avoid importing flask_login from main code

I am currently coding up a simple web application using flask and flask_login. This is main.py:
import flask
import flask_login
app = flask.Flask(__name__)
login_manager = flask_login.LoginManager()
login_manager.init_app(app)
#app.route('/')
#flask_login.login_required
def index():
return "Hello World!"
The above code works. The problem arises because I want to separate authentication related code from the main flask application code. In other words, I want my_auth.py that imports flask_login, and I want main.py to import my_auth, and NOT have to import flask_login.
The problem is with the #flask_login.login_required decorator. If I do not import flask_login from main.py, is it still possible to somehow "wrap" the main index() function with login_required?
(I've actually asked a wrong question before, which may still be relevant: flask and flask_login - organizing code)
create a file my_auth.py
# my_auth.py
import flask_login
login_manager = flask_login.LoginManager()
# create an alias of login_required decorator
login_required = flask_login.login_required
and in file main.py
# main.py
import flask
from my_auth import (
login_manager,
login_required
)
app = flask.Flask(__name__)
login_manager.init_app(app)
#app.route('/')
#login_required
def index():
return "Hello World!"
Maybe this is what you want to achieve.
I can confirm that Akshay's answer works.
While waiting for an answer, however, I've also found a workaround(?) that does not rely on using the decorator:
In main.py:
#SVS.route("/")
def index():
if not my_auth.is_authenticated():
return flask.redirect(flask.url_for('login'))
return "Hello World!"
In my_auth.py:
def is_authenticated():
return flask_login.current_user.is_authenticated

Categories