Flaskで
・フラッシュメッセージを出す
・フォームに入力された値をデータベースに格納してWebページに表示

それぞれは動作するのですが、組み合わせるとエラーが起きます。

エラー文
secret keyに関してのエラー文のようですが、検索しても修正方法がわからず困っています。

Flaskの公式ドキュメント・Message Flashingにシークレットキーに関する記述がありましたが、この例ではログイン実装などをしているため、今回のような例でもなぜ必要なのかわかりません。

・ターミナル
フォームの記入/未記入にかかわらず、エラー文は同じです。

(<class 'RuntimeError'>, RuntimeError('The session is unavailable because no secret key was set.  
Set the secret_key on the application to something unique and secret.',), <traceback object at 0x10d2cf3c8>)

・ブラウザでの動作
フォームへの記入/無記入関係なく、Createボタンを押すと

Bad Request
The browser (or proxy) sent a request that this server could not understand.

となります。

  if error:
    abort (400)

フォームが未記入の場合、上記の部分でflash("テキストを入力してください", "failed")とした方がいいのかと考えましたが、フォームの記入/未記入にかかわらず、エラー文が同じなため、解決方法がわからない状態です。

実行プログラム
app.py

from flask import Flask, flash, render_template, request, redirect, url_for, abort, jsonify
from flask_sqlalchemy import SQLAlchemy
import sys

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://username@localhost:5432/todoappbegin'
db = SQLAlchemy(app)

class Todo(db.Model):
    __tablename__ = 'todos'
    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.String(), nullable=False)

    def __repr__(self):
        return f'<Todo {self.id}{self.description}>'

db.create_all()

#テキストが入力されていたら、データベースに格納し、HTMLページに表示
@app.route('/todos/create', methods=['POST'])
def create_todo():
  error = False
  body = {}
  try:
    description = request.form['description']
    todo = Todo(description=description)
    #テキストが入力されていたら
    if description:
      db.session.add(todo)
      db.session.commit()
      body['description'] = todo.description
      flash("投稿に成功しました", "success")

    elif texts == "":
      flash("テキストを入力してください", "failed")
      db.session.rollback()

  except:
    error = True
    db.session.rollback()
    print(sys.exc_info())
  finally:
    db.session.close()
  if error:
    abort (400)
  else:
    return jsonify(body)

@app.route('/')
def index():
    return render_template('index.html', data=Todo.query.all())

Index.html

<html>
  <head>
    <title>Todo App</title>
    <style>
      #error {
        display: none;
      }
    </style>
  </head>
  <body>
    <div id="error" class="hidden">Something went wrong!</div>
    <form id="form" method="post" action="/texts/create">
      <input type="text" id="username" name="username">
      <input type="text" id="texts" name="texts" />
      <input type="submit" value="Create" />
    </form>
    <ul id="username">
      {% for d in data %}
      <li>{{d.username}}</li>
      {% endfor %}
    </ul>
    <ul id="texts">
      {% for d in data %}
      <li>{{ d.texts }}</li>
      {% endfor %}
    </ul>
    <script>
      const nmInput = document.getElementById('username')
      const descInput = document.getElementById('texts');
      document.getElementById('form').onsubmit = function(e) {
        e.preventDefault();
        const nm = nameInput.value;
        const desc = descInput.value;
        descInput.value = '';
        fetch('/texts/create', {
          method: 'POST',
          body: JSON.stringify({
            'username':nm,
            'texts': desc,
          }),
          headers: {
            'Content-Type': 'application/json',
          }
        })
        .then(response => response.json())
        .then(jsonResponse => {
          console.log('response', jsonResponse);
          li = document.createElement('li');
          li.innerText = nm;
          li.innerText = desc;
          document.getElementById('usernames').appendChild(li);
          document.getElementById('texts').appendChild(li);
          document.getElementById('error').className = 'hidden';
        })
        .catch(function() {
          document.getElementById('error').className = '';
        })
      }
    </script>
  </body>
</html>

組み合わせたそれぞれのプログラム
フラッシュメッセージの表示は
Flaskでフラッシュメッセージを表示する方法
というQuiitaの記事のプログラムの動作を確認しました。

また入力したデータをデータベースに格納・Webページに表示するプログラムは以下です。
HTMLファイルは現在実行しているものと同じです。

from flask import Flask, render_template, request, redirect, url_for, abort, jsonify
from flask_sqlalchemy import SQLAlchemy
import sys

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://username@localhost:5432/todoappbegin'
db = SQLAlchemy(app)

class Todo(db.Model):
    __tablename__ = 'todos'
    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.String(), nullable=False)

    def __repr__(self):
        return f'<Todo {self.id}{self.description}>'

db.create_all()

@app.route('/todos/create', methods=['POST'])
def create_todo():
  error = False
  body = {}
  try:
    description = request.form['description']
    todo = Todo(description=description)
    db.session.add(todo)
    db.session.commit()
    body['description'] = todo.description
  except:
    error = True
    db.session.rollback()
    print(sys.exc_info())
  finally:
    db.session.close()
  if error:
    abort (400)
  else:
    return jsonify(body)

@app.route('/')
def index():
    return render_template('index.html', data=Todo.query.all())

実行環境
Python 3.6.0
Flask 1.1.1
Sqlalchemy 1.3.10
psql (PostgreSQL) 11.5
ブラウザ Google Chrome