How to use <input> in Flask

Viewed 83

I want to use input from html to be a function in my Flask:

from flask import Flask, url_for, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

app = Flask(__name__)   
    
@app.route("/")
def homepage() :
    return render_template("index.html", make_cards = make_cards(user_deck), make_cards_u = user_cards(), result = find_winner(user_deck, computer_deck))
    
class user_cards (FlaskForm):
    SUITS = StringField('suits', validators=[DataRequired()])
   
    SEQUENCE = StringField('stringfield', validators=[DataRequired()])
    
    submit = SubmitField('Check!')

    
if __name__ == '__main__':
    # print(poker_hand_ranking(["10H", "JH", "QH", "AH", "KH"]))
    user_deck = user_cards()
    computer_deck = make_cards(user_deck)
    find_winner(user_deck, computer_deck)
    app.run(debug=True)
  

I want this program to interact with the user, so I did not define make_cards_u, and want an user input for the cards. So my HTML is as follows:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF=8">
        <title> Poker Game </title>
        <link rel="stylesheet" href ="{{url_for('static', filename='css/style.css')}}">
    </head>
    
    <body>
        <h1> Welcome to Gaming Poker</h1>
        <h3>Computer cards: {{make_cards}} <br>
        Your cards: <input> {{make_cards_u}} </input> </h3>
        <h2>Results: {{result}}</h2>
    </body>
</html>

However, I am getting an error

RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that
needed to interface with the current application object in some way.
To solve this, set up an application context with app.app_context(). 
See the documentation for more information.

My other python codes are as follow:

SEQUENCE = ['2', '3', '4', '5', '6', '7', '8', '9', '10',
            'J', 'Q', 'K', 'A']
VALUES = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
          '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
SUITS = ['S', 'H', 'C', 'D']

# The computer gets 5 cards
def make_cards(deck = None): 
    result_deck = set()
    while (len(result_deck) < 5):
        card = random.choice(SEQUENCE) + random.choice(SUITS)
        if (deck != None):
            if (card not in deck): 
                result_deck.add(card)
        else:
            result_deck.add(card)
    return list(result_deck)

def find_winner(user_deck, computer_deck):
    user_rank = poker_hand_ranking(user_deck)
    computer_rank = poker_hand_ranking(computer_deck)
    if (user_rank[0] < computer_rank[0]):
        print('Winner is user')
    elif (user_rank[0] > computer_rank[0]):
        print('Winner is computer')
    else:
        print('Draw!')
    print('User:', user_deck, user_rank[1])
    print('Computer:', computer_deck, computer_rank[1])

Also, I have codes that defines variables inside the if elif statements, which was too long to put in this question. The poker_hand_ranking was defined as below:

def poker_hand_ranking(deck):
    hand = deck
    suits = sorted([card[-1] for card in hand])
    faces = sorted([card[:-1] for card in hand])
    if is_royal_flush(hand, suits, faces):
        return 1, "You have a Royal Flush"
    elif is_straight_flush(hand, suits, faces):
        return 2, "You have a Straight Flush"
    elif is_four_of_a_kind(hand, suits, faces):
        return 3, "You have four of a Kind"
    elif is_full_house(hand, suits, faces):
        return 4, "You have a full House"
    elif is_flush(hand, suits, faces):
        return 5, "You have a flush"
    elif is_straight(hand, suits, faces):
        return 6, "You have a straight"
    elif is_three_of_a_kind(hand, suits, faces):
        return 7, "You have a three of a Kind"
    elif is_two_pairs(hand, suits, faces):
        return 8, "You have a two Pair"
    elif is_one_pair(hand, suits, faces):
        return 9, "You have a pair"
    else:
        #if none of these counts:
        return 10, "High Card"

How do I make the user input interact in Flask?

1 Answers

You could use the form user_cards in the template to create a HTML form and then handle the submitted value in the flask code.

You can check the user submitted values with your generated card decks and then decide who wins the game.

Here is my approach. As I do not have all the logic of poker game, I have randomly returned the poker hand ranking. You can replace it with original method.

Directory structure:

.
├── requirements.txt
├── sample_form.py
└── templates
    └── index.html

requirements.txt:

click==7.1.2
Flask==1.1.2
Flask-WTF==0.14.3
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
Werkzeug==1.0.1
WTForms==2.3.1

sample_form.py:

import random
from flask import Flask, url_for, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

app = Flask(__name__)   
# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

SEQUENCE = ['2', '3', '4', '5', '6', '7', '8', '9', '10',
            'J', 'Q', 'K', 'A']
VALUES = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
          '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
SUITS = ['S', 'H', 'C', 'D']

# The computer gets 5 cards
def make_cards(deck = None): 
    result_deck = set()
    while len(result_deck) < 5:
        card = random.choice(SEQUENCE) + random.choice(SUITS)
        if deck != None:
            if card not in deck: 
                result_deck.add(card)
        else:
            result_deck.add(card)
    return list(result_deck)

def find_winner(user_deck, computer_deck):
    user_rank = poker_hand_ranking(user_deck)
    computer_rank = poker_hand_ranking(computer_deck)
    if user_rank[0] < computer_rank[0]:
        return 'Winner is user'
    elif user_rank[0] > computer_rank[0]:
        return 'Winner is computer'
    else:
        return 'Draw!'

def poker_hand_ranking(deck):
    return random.choice(["some", "many"])

class user_cards(FlaskForm):
    suits = StringField('suits', validators=[DataRequired()])   
    sequence = StringField('sequence', validators=[DataRequired()])    
    submit = SubmitField('Check!')
    
@app.route("/", methods=['GET', 'POST'])
def homepage():
    card_form = user_cards()
    if card_form.validate_on_submit():
        user_deck = ["{}{}".format(card_form.suits.data,
                                   card_form.sequence.data)]
        computer_deck = make_cards()
        result = find_winner(user_cards, computer_deck)
        return render_template('index.html', form=card_form,
                               user_deck=user_deck,
                               computer_deck=computer_deck,
                               result=result)
    return render_template('index.html', form=card_form)

templates/index.html:

<html>
<head>
    <title>
        Card Form
    </title>
</head>
<body>
    <h1> Welcome to Gaming Poker</h1>
    <h2>Input Cards</h2>
    <form method="POST" action="/">
        {{ form.csrf_token }}
        {{ form.suits.label }} {{ form.suits(size=20) }}
        {{ form.sequence.label }} {{ form.sequence(size=20) }}
        {{ form.submit }}
    </form>    

    {% if computer_deck %}
    <h3>Computer cards: {{computer_deck}} </h3>
    {% endif %}

    {% if user_deck %}
    <h3>Your cards: {{user_deck}}</h3>
    {% endif %}

    {% if result %}
    <h2>Results: {{result}}</h2>
    {% endif %}
        
</body>
</html>

Output:

Before form submission:

before form submission

After form submission:

after submission

Disclaimer:

I have not actually selected the correct winner. Please include your logic. Hopefully my snippets will help you to understand how to work with form in Flask using Flask-wtf package.

Reference:

Related