Forums

Persistent 500 Permission Error

Below is the flask_app.py code that I am trying to use to upload csv files to pythonanywhere. Despite many hours of troubleshooting I am unable to find a solution -

from flask import Flask, request
import os
import logging

app = Flask(__name__)

# Define the upload folder path correctly
UPLOAD_FOLDER = '/home/my_username/mysite/uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

# Configure logging
logging.basicConfig(filename='/home/my_username/mysite/upload_errors.log', level=logging.DEBUG)

@app.route('/upload', methods=['POST'])
def upload_file():
    app.logger.debug('Received request for file upload.')

    if 'file' not in request.files:
        app.logger.error('No file part in the request.')
        return 'No file part', 400

    file = request.files['file']
    if file.filename == '':
        app.logger.error('No file selected for uploading.')
        return 'No selected file', 400

    try:
        # Correctly build the file path
        file_path = os.path.join(UPLOAD_FOLDER, file.filename)
        app.logger.info(f'Attempting to save file to {file_path}')

        # Log absolute path of UPLOAD_FOLDER
        app.logger.info(f'UPLOAD_FOLDER absolute path: {os.path.abspath(UPLOAD_FOLDER)}')

        # Log actual full path for saving the file
        app.logger.info(f'Full file path: {os.path.abspath(file_path)}')

        # Save the file
        file.save(file_path)
        app.logger.info('File successfully saved.')
        return 'File successfully uploaded', 200

    except Exception as e:
        app.logger.error(f'Error saving file: {e}', exc_info=True)
        return 'Failed to upload file', 500

# Comment out app.run() for production use on PythonAnywhere
# if __name__ == '__main__':
#     app.run(debug=True)

When I run my Arduino code I consitently get this error:

10:07:42.552 -> Modem Info: Manufacturer: SIMCOM INCORPORATED Model: SIMCOM_SIM7600G-H Revision: SIM7600G_V2.0.2 IMEI: 862636053708325 +GCAP: +CGSM
10:07:42.552 -> Connecting to network...
10:07:42.706 -> Connected to GPRS
10:07:42.706 -> Processing file: System Volume Information
10:07:42.706 -> Processing file: data0.csv
10:07:42.706 -> Found CSV file: data0.csv
10:07:42.706 -> Uploading file: /data0.csv
10:07:42.706 -> Attempting to open file: /data0.csv
10:07:42.706 -> Uploading file: /data0.csv
10:07:42.953 -> Successfully connected to server
10:07:53.770 -> File upload complete
10:07:55.124 -> Server response:
10:07:55.124 -> HTTP/1.1 500 INTERNAL SERVER ERROR
10:07:55.124 -> Date: Sun, 25 Aug 2024 09:08:01 GMT
10:07:55.124 -> Content-Type: text/html; charset=utf-8
10:07:55.124 -> Content-Length: 21
10:07:55.124 -> Connection: keep-alive
10:07:55.124 -> Server: PythonAnywhere
10:07:55.124 -> 
10:07:55.124 -> Failed to upload file
10:07:55.124 -> Disconnected from server

Grateful for any magic solution - what am I doing wrong?

[formatted by admin]

What is your client code?

Here is the necessary client code - at this stage I am trying to upload a single file "data0.csv" which is less than 100kb. Ultimatley I want to be able to upload multiple similar data files that could be say 1-5Mb in size.

// Example Arduino Client Code for PythonAnywhere Support
const char server[] = "my_username.pythonanywhere.com";  // Server URL
const int port = 80;  // HTTP port
const char serverPath[] = "/upload"; // Upload endpoint

void uploadData0File() {
  const char* fileName = "data0.csv";
  File file = SD.open(fileName);
  if (!file) {
    Serial.println("Failed to open file for reading: " + String(fileName));
    return;
  }

  Serial.println("Uploading file: " + String(fileName));

  // Prepare HTTP POST request
  String boundary = "----ESP8266BOUNDARY";
  String header1 = "--" + boundary + "\r\n" +
                   "Content-Disposition: form-data; name=\"file\"; filename=\"" + String(fileName) + "\"\r\n" +
                   "Content-Type: text/csv\r\n\r\n";
  String footer = "\r\n--" + boundary + "--\r\n";

  int fileSize = file.size();
  int contentLength = header1.length() + fileSize + footer.length();

  if (!client.connect(server, port)) {
    Serial.println("Connection to server failed");
    file.close();
    return;
  }

  Serial.println("Successfully connected to server");

  client.print("POST ");
  client.print(serverPath);  // Upload path
  client.println(" HTTP/1.1");
  client.println("Host: my_username.pythonanywhere.com");
  client.println("Content-Type: multipart/form-data; boundary=" + boundary);
  client.print("Content-Length: ");
  client.println(contentLength);
  client.println();

  // Send headers and file data
  client.print(header1);
  uint8_t buffer[512];
  int bytesRead;
  while ((bytesRead = file.read(buffer, sizeof(buffer))) > 0) {
    client.write(buffer, bytesRead);
  }
  client.print(footer);
  file.close();

  Serial.println("File upload complete");
  // Handle server response
}

[formatted by admin]

Do you see any errors in the backend log? Could you make sure that your code is trying to save the file in the location you have permissions for?