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.
Related
I have a file that registers a blueprint and runs the app api/v1/app.py:
#!/usr/bin/python3
"""returns api status code"""
from api.v1.views import app_views
from flask import Flask
from models import storage
from os import getenv
app = Flask(__name__)
app.register_blueprint(app_views, url_prefix="/api/v1")
#app.teardown_appcontext
def close_session(session):
"""close a session"""
storage.close()
if __name__ == '__main__':
host = getenv('HBNB_API_HOST') if getenv('HBNB_API_HOST') else '0.0.0.0'
port = getenv('HBNB_API_PORT') if getenv('HBNB_API_PORT') else 5000
app.run(port=port, host=host, threaded=True)
a file that creates a blueprint api/v1/views/__init__.py:
#!/usr/bin/python3
"""create a blueprint"""
from flask import Blueprint
app_views = Blueprint("app_views", __name__)
and a file that creates a blueprint route api/v1/views/index.py:
#!/usr/bin/python3
"""returns api status code"""
from flask import jsonify
from api.v1.views import app_views
#app_views.route('/status')
def status():
"""return ok response"""
return jsonify({"status": "OK"})
i registered the blueprint with the url_prefix /api/v1, but when i try to access http://0.0.0.0:5000/api/v1/status, I get 404.
So what am I missing here ?
You defined the prefix correctly. The problem here is because the file api/v1/views/index.py was never interpreted. If you add import api/v1/views/index.py in the file api/v1/app.py it will probably work
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)
As I'm testing the URL endpoint for a resource, I'm getting a 404 Not Found error. I don't understand why it cannot be found as the resource is added to the api instance and the blueprint is added to the flask app.
tests.py
def test_todo_collection_resource(self):
with app.test_client() as client:
http_response = client.get("/todos/")
json_data = http_response.get_json()
self.assertEqual(http_response.status_code, 200) <<<---FAILS
self.assertTrue(http_response.is_json)
self.assertTrue(all(
(instance['name'] in self.todo_resources.values()
for instance in json_data)
))
todos.py
from flask import Blueprint, jsonify
from flask_restful import Api, Resource, fields, marshal
from models import Todo
todo_api = Blueprint("resources.todos", __name__)
api = Api(todo_api)
todos_fields = {
'name': fields.String
}
class TodoList(Resource):
pass
api.add_resource(
TodoList,
''
'todos'
)
app.py
from flask import Flask, g, jsonify, render_template
from config import HOST, PORT, DEBUG
from peewee import *
import models
from resources.todos import todo_api
app = Flask(__name__)
app.register_blueprint(todo_api, url_prefix="/todos/")
models.DATABASE.init('todo_api.db')
models.initialize(models.User, models.Todo)
#app.route('/')
def my_todos():
return render_template('index.html')
if __name__ == '__main__':
app.run(host=HOST, port=PORT, debug=DEBUG)
You have not defined any methods in your TodoList class that is why there is a 404 error as it can't find any HTTP methods defined on that endpoint. The Flask-RESTful documentation specifies defining HTTP methods in your Resource class e.g.
class TodoList(Resource):
def get(self):
return TODOS
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)
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')