Desiigner
Desiigner

Reputation: 2316

Failed to run python flask app (404, 405 response code)

Doing 2nd CS50 project and the first thing I have to do is to create an index.html page where I have to type in a username and it'll displayed. I have to do it using SocketIO to make other users be able to see it too.

When I run my Flask app and go the page I'm getting the following text in my console:

flask run
 * Serving Flask-SocketIO app "main.py"
 * Forcing debug mode on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 399-480-796
127.0.0.1 - - [2018-08-12 05:17:54] "GET / HTTP/1.1" 200 1123 0.008075
127.0.0.1 - - [2018-08-12 05:17:55] "GET /index.js HTTP/1.1" 404 342 0.000796
127.0.0.1 - - [2018-08-12 05:17:55] "GET /static/index.js HTTP/1.1" 404 342 0.000821
127.0.0.1 - - [2018-08-12 05:17:55] "GET /static/index.js HTTP/1.1" 404 342 0.003149

But when I press my "Enter" button it fails with 'Method Not Allowed' and what I see in my console is:

127.0.0.1 - - [2018-08-12 05:18:01] "POST / HTTP/1.1" 405 323 0.003737

project_folder/main.py:

from flask import Flask, jsonify, render_template, request
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config["SECRET_KEY"] = 'dev'
socketio = SocketIO(app)

@app.route("/")
def index():
    return render_template("index.html")

@socketio.on("new user")
def new(data):
    username = data["username"]
    emit('plus user', {'username': username}, broadcast=True)

project_folder/templates/layout.html:

<html>
  <head>
    <title>{% block title %}{% endblock %}</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous">
    <script type='text/javascript' src='index.js'></script>
    <script src='{{ url_for('static', filename='index.js') }}'></script>
  </head>
  <body>
    <div class="container">
      {% block body %}
      {% endblock %}
    </div>
  </body>
</html>

project_folder/templates/index.html:

{% extends "layout.html" %}

{% block title %}
  Sign In
{% endblock %}

{% block body %}

  <form action="{{ url_for('index') }}" method='post'>

    <h1>Hi! In this chat room you can be whoever you want.</h1>
    <h2>The only thing I ask you is to tell me the name I'll be calling you.</h2>
    <h3>You don't have to tell me your real name.</h3>
    <h4>Enjoy.</h4>
    <br>

    <div class="form-group">
      <input class="form-control" name='username' autofocus placeholder="Username">
    </div>

    <div class="formgroup">
      <button id='newuser' class='btn btn-primary' data-new='username'>Enter</button>
    </div>

    <ul id="users"></ul>
  </form>

{% endblock %}

project_folder/templates/index.js:

document.addEventListener('DOMContentLoaded', () => {

  // connect to websocket
  var socket = io.connect(location.protocol + '//' + document.domain + ":" + location.port);

  // when connected, configure buttons
  socket.on('connect', () => {

    document.querySelector('#newuser').onclick = () => {
      const username = newuser.dataset.new;
      socket.emit('new user', {'username': username})
    };
  });

});

// When a new user has registered , add to the ul
socket.on('plus user', data => {
  const li = document.createElement('li');
  li.innerHTML = data.username;
  document.querySelector('#users').append(li);
});

It's almost the same task and I took like 90% of the code from the lecture video but it doesn't wrong. What am I doing wrong?

Upvotes: 1

Views: 1693

Answers (2)

Gaurav
Gaurav

Reputation: 543

In Layout.html

You are Routing Index.Js to wrong Folder, either replace static with template as done below

<script src='{{ url_for('templates', filename='index.js') }}'></script>

Or create a new folder static in the root directory,i.e. project_folder if you want to use:

<script src='{{ url_for('static', filename='index.js') }}'></script>

Generally the second way is preferred.

Upvotes: 1

Thirsty_Crow
Thirsty_Crow

Reputation: 133

Looks like your routing is at fault here. Your form is submitting to URL pattern of 'index' but your routing only handles the '/' route.

Change

@app.route("/")

to following in main.py:

@app.route("/index")

Upvotes: 0

Related Questions