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!

  • 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. – DinoCoderSaurus Dec 6 '18 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. – Oscar Medina Dec 8 '18 at 23:37
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.

| improve this answer | |
  • Thanks for your answer! Do you know how to get the absolute path? Cheers. – Oscar Medina Dec 10 '18 at 3:02
  • I have added info to the answer. Give it a try. – DinoCoderSaurus Dec 10 '18 at 13:23
  • It still won't work :( – Oscar Medina Dec 11 '18 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! – DinoCoderSaurus Dec 12 '18 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? – Oscar Medina Dec 13 '18 at 3:04

You must log in to answer this question.

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