Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 302需要登录的问题_Python_Heroku_Flask_Sqlalchemy - Fatal编程技术网

Python 302需要登录的问题

Python 302需要登录的问题,python,heroku,flask,sqlalchemy,Python,Heroku,Flask,Sqlalchemy,我在Heroku上运行烧瓶应用程序时遇到问题。在本地运行时,该应用程序允许我登录并浏览导航栏选项。当我通过Heroku在线运行它时,最终会出现302代码,它会将我踢出登录屏幕,然后再次单击“登录”,它会将我带回主页(/index) 我已经设置了密钥,但我不确定还能做什么。请在此处查看应用程序() 有关Helper.py,请参见此处 import os import requests import urllib.parse from flask import redirect, render_t

我在Heroku上运行烧瓶应用程序时遇到问题。在本地运行时,该应用程序允许我登录并浏览导航栏选项。当我通过Heroku在线运行它时,最终会出现302代码,它会将我踢出登录屏幕,然后再次单击“登录”,它会将我带回主页(/index)

我已经设置了密钥,但我不确定还能做什么。请在此处查看应用程序()

有关Helper.py,请参见此处

import os
import requests
import urllib.parse

from flask import redirect, render_template, request, session
from functools import wraps


def login_required(f):
    """
    Decorate routes to require login.

    http://flask.pocoo.org/docs/1.0/patterns/viewdecorators/
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if session.get("user_id") is None:
            return redirect("/")
        return f(*args, **kwargs)
    return decorated_function


# allows user to call stocks based on symbol
def lookup(symbol):
    """Look up quote for symbol."""
    os.system("export API_KEY="+"pk_0d1467f2aeb748d0b81f445f22bd6665")

    # Contact API
    try:
        api_key = os.environ.get("API_KEY")
        response = requests.get(f"https://cloud-sse.iexapis.com/stable/stock/{urllib.parse.quote_plus(symbol)}/quote?token={api_key}")
        response.raise_for_status()
    except requests.RequestException:
        return None

    # Parse response
    try:
        quote = response.json()
        return {
            "name": quote["companyName"],
            "price": float(quote["latestPrice"]),
            "symbol": quote["symbol"]
        }
    except (KeyError, TypeError, ValueError):
        return None


def usd(value):
    """Format value as USD."""
    return f"${value:,.2f}"
主应用程序.py

import os

from flask import Flask, flash, jsonify, redirect, render_template, request, session
from flask_session import Session
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import func
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
from werkzeug.security import check_password_hash, generate_password_hash
from datetime import datetime

from helpers import login_required, lookup, usd

# Configure application
app = Flask(__name__)

app.config['SECRET_KEY'] = 'f3cfe9ed8fae309f02079dbf'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']

# calls SQLAlchemy database
db = SQLAlchemy(app)

# defines table values
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), unique=True, nullable=False)
    cash = db.Column(db.Float(7), nullable=False)
    remainder = db.Column(db.Float(7), nullable=False)

class Transactions(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    stockname = db.Column(db.String(80), unique=True, nullable=False)
    stocksymbol = db.Column(db.String(80), unique=True, nullable=False)
    stockprice = db.Column(db.Float(7), nullable=False)
    stockshares = db.Column(db.Integer, nullable=False)
    stocktotal = db.Column(db.Float(7), nullable=False)

class History(db.Model):
    datetime = db.Column(db.DateTime(), primary_key=True)
    username = db.Column(db.String(80), nullable=False)
    buysell = db.Column(db.String(4), nullable=False)
    stockname = db.Column(db.String(80), nullable=False)
    stocksymbol = db.Column(db.String(80), nullable=False)
    stockprice = db.Column(db.Float(7), nullable=False)
    stockshares = db.Column(db.Float(7), nullable=False)

# Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True

# Ensure responses aren't cached
@app.after_request
def after_request(response):
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Expires"] = 0
    response.headers["Pragma"] = "no-cache"
    return response

# Custom filter
app.jinja_env.filters["usd"] = usd

# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

# Make sure API key is set
if not os.environ.get("API_KEY"):
    #set up api key for the stock quote engine
    try:
        os.environ["API_KEY"] = "pk_0d1467f2aeb748d0b81f445f22bd6665"
    except:
        raise RuntimeError("API_KEY not set")


@app.route("/register", methods=["GET", "POST"])
def register():
    """Register user"""

    # User reached route via GET (as by clicking a link or via redirect)
    if request.method == "GET":
        return render_template("register.html")

    # User reached route via POST (as by submitting a form via POST)
    elif request.method == "POST":

        # retrieve user entered information
        username = request.form.get("username")
        password = request.form.get("password")
        confirmation = request.form.get("confirmation")

        # Query database for username
        user = User.query.filter_by(username=username).first()

        # Enter valid username
        if not username:
            flash("Please enter a username")
            return redirect("/register")

        # Enter valid password
        elif not password:
            flash("Please enter a password")
            return redirect("/register")

        # Password was not confirmed
        elif not confirmation:
            flash("Please confirm password")
            return redirect("/register")

        # Ensure passwords match
        elif password != confirmation:
            flash("Passwords do not match")
            return redirect("/register")

        # if username is taken
        elif user:
            flash("Username is already taken")
            return redirect("/register")

        # saves password to hash
        password = generate_password_hash(password)

        # adds username, password, cash available and remainder to table
        db.session.add(User(username=username,password=password,cash=10000,remainder=10000))
        db.session.commit()

        # Save user id into session
        # Do not change to session["user_id"] = user; for some reason website does not run properly 
        session["user_id"] = User.query.filter_by(username=username).first()

        # Redirect user to home page
        return redirect("/index")


@app.route("/", methods=["GET", "POST"])
def login():
    """Log user in"""

    # User reached route via GET (as by clicking a link or via redirect)
    if request.method == "GET":
        return render_template("login.html")

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # calls entered username and password
        username = request.form.get("username")
        password = request.form.get("password")

        # finds entered username in database
        user = User.query.filter_by(username=username).first()

        # Ensure username was submitted
        if not username:
            flash("Please provide username")
            return redirect("/")

        # Ensure password was submitted
        elif not password:
            flash("Please provide password")
            return redirect("/")

        # Ensure username exists and password is correct
        elif not user:
            flash("Invalid username")
            return redirect("/")

        elif not check_password_hash(user.password, password):
            flash("Invalid password")
            return redirect("/")

        # Remember which user has logged in
        # Do not change to session["user_id"] = user; for some reason website does not run properly 
        session["user_id"] = user

        # Redirect user to home page
        return redirect("/index")


@app.route("/logout")
def logout():
    """Log user out"""

    # Forget any user_id
    session.clear()

    # Redirect user to login form
    return redirect("/")

@app.route("/index")
@login_required
def index():

    """Show portfolio of stocks"""

    """
    worked
    session["user_id"]

    #calls current user
    username = session["user_id"]
    """

    #calls current user
    username = session["user_id"]

    # calls total investments for current user
    total = username.cash

    # calls remaining cash for current user
    remainder = username.remainder

    # tries calling transactions for current user
    try:

        # initializes transactions table for current user
        transactions = Transactions.query.filter_by(username=username.username)

        # totals all stock investments for current user
        stocktotal = transactions.with_entities(func.sum(Transactions.stocktotal).label("total")).first().total

        # calculates remainder amount of cash
        remainder = total - stocktotal

        # updates remainder
        username.remainder = remainder
        db.session.commit()

    # if new user then defaults to this
    except:

        # calculates total stocks invested based on cash total and remainder; for a new user it will always be 0
        stocktotal = total - remainder

    # returns html template
    return render_template("index.html", total=total, remainder=remainder, transactions=transactions, stocktotal=stocktotal)