0

Update: Does anyone know hot to get the folder's absolute path? It isn't ~/workspace/fp/documentos/ or any of it's variations, such as /workspace/fp/documentos/ or workspace/fp/documentos/. It seems that if I get the file path correctly, the issue will be solved.

Amateur coder & enthusiast here, first time asking... I'm working on the final project of the CS50 course. I'm building a website where you can register and upload certain documents. Everything seems to be running fine, but the moment I try to upload the documents, I get an Internal Server Error with the following message:

The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

What is going on? Is there a restriction for uploading documents into a folder in the CS50 IDE? I can't seem to find the solution to this problem. Documents are required to be in PDF format and I've tried either ~/workspace/fp/documentos/ & just /fp/documentos as file paths. Here is the code:

import os

from cs50 import SQL
from flask import Flask, flash, redirect, render_template, request, session, 
url_for
from flask_session import Session
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions
from werkzeug.security import check_password_hash, generate_password_hash
from werkzeug.utils import secure_filename

from helpersp import apology, login_required

# Define uploaded documents destination and allowed extensions

UPLOAD_FOLDER = '/fp/documentos/' 
ALLOWED_EXTENSIONS = set(['pdf'])

# Check if extension is allowed.

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route("/primer", methods=["GET", "POST"])
@login_required
def primer():
"""Prompts user to upload pre contractual documents"""
 if request.method == "GET":
     return render_template("primer.html")

 else:
     # check if the post request has the file part
     if "file" not in request.files:
         return render_template("sindocumentos.html")
     file = request.files["file"]
     #  if user does not select file, browser also
     # submit an empty part without filename
     if file.filename == "":
         return render_template("sindocumentos.html")
     if file and allowed_file(file.filename):
         filename = secure_filename(file.filename)
         file.save(os.path.join(app.config['/fp/documentos/'], filename))

     return render_template("successp.html")

Here is the HTML part:

{% extends "layoutp.html" %}

{% block title %}
    Subir carpeta
{% endblock %}

{% block main %}
    <form action="/primer" method="post" enctype=multipart/form-data>
        <div>
            Sube tu carpeta de documentos en un solo archivo PDF.
        </div>
        <div>
            El nombre del archivo debe tener el siguiente formato: 
           carpeta_nombre_apellido_año.pdf.
        </div>
        <div class="form-group">
           <input type="file" name="file">
        </div>
        <button class="btn btn-primary" type="submit">Subir</button>
    </form>
{% endblock %}

Any help is very much appreciated!

Edit: The flask trace goes as follows:

ERROR:flask.app:Exception on /primer [POST]
Traceback (most recent call last):
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ubuntu/workspace/fp/helpersp.py", line 34, in decorated_function
    return f(*args, **kwargs)
  File "/home/ubuntu/workspace/fp/profesores.py", line 133, in primer
    file.save(os.path.join(app.config[UPLOAD_FOLDER], filename))
KeyError: '/documentos'

UPDATE: Now, I have tried different file paths including absolute paths. I have also used UPLOAD_FOLDER=os.mkdir('documentos2') in order to create the folder and use it in the program itself. It stil won't work but now I get KeyError:None:

  File "/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ubuntu/workspace/fp/helpersp.py", line 34, in decorated_function
    return f(*args, **kwargs)
  File "/home/ubuntu/workspace/fp/profesores.py", line 124, in primer
    file.save(os.path.join(app.config[UPLOAD_FOLDER], filename))
KeyError: None

Any help is very much appreciated!

2
  • Does the stack trace in the flask terminal give more information? Are you running flask in ~/workspace/fp? Maybe the UPLOAD_FOLDER needs to be just /documentos, ie relative to the document_root. Dec 6, 2018 at 4:41
  • Thanks for your input! I have included the flask error trace in the initial post. I have changed the file path but stil won't work. Dec 8, 2018 at 23:37

1 Answer 1

0

The error message file.save(os.path.join(app.config[UPLOAD_FOLDER], filename)) KeyError: '/documentos' is telling you there is no key /documentos in the array app.config.

From example in flask doc:

import os
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename

UPLOAD_FOLDER = '/path/to/the/uploads'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

Notice how app.config['UPLOAD_FOLDER'] is declared, and used later (in the same doc) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)).

I suspect UPLOAD_FOLDER should be an absolute path, based on the example in the doc and the answer in this post. I have not tested, I leave that to you. Remember the flask trace is your friend.

To get the full path you might try:

UPLOAD_FILE=os.getcwd()+'/documentos'

getcwd from the python os library will return current working directory (ie the directory where flask is running), which should be ~/workspace/fp, then append the name of the subdirectory.

6
  • Thanks for your answer! Do you know how to get the absolute path? Cheers. Dec 10, 2018 at 3:02
  • I have added info to the answer. Give it a try. Dec 10, 2018 at 13:23
  • It still won't work :( Dec 11, 2018 at 17:49
  • Now's when the real work of programming/development begins: troubleshooting. You're gonna try stuff, read the stack trace if it doesn't work, research any error(s) it gives, in the doc, browser search, look at stack. Then do it again. Until finally you get a Woo-Hoo! Dec 12, 2018 at 3:47
  • It sometimes feels like a dead end, but I'm gonna keep trying! Do you think the issue might not be the file path but somewhere else? Dec 13, 2018 at 3:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .