0

I am developing a website in Python Flask. What I have to do is to get uploaded file in one of the forms and attach it to mail. I tried solution given in similar question but it gives following error:

AttributeError: 'str' object has no attribute 'filename'

What am I doing wrong? I am beginner in python and flask. Here's my code:

class UploadForm(Form):
    branch = StringField('branch', validators = [DataRequired()])
    year = StringField('year', validators = [DataRequired()])
    sub = StringField('sub', validators = [DataRequired()])
    paper = FileField('Logo', validators = [Required()])

def uploadPaper(form):
    msg = Message('New upload request', sender = ADMINS[0], recipients = ADMINS)
    msg.body = 'text body'
    msg.html = 'Branch: ' + form.branch.data + '<br />' + 'Year: ' + form.year.data + '<br />' + 'Subject: ' + form.sub.data
    msg.attach(form.paper.data.filename, 'application/octect-stream', form.paper.data.read())
    with app.app_context():
        mail.send(msg)
    return "success"

I am calling uploadPaper() function on validating the form.

Franco Roura
  • 807
  • 8
  • 26

1 Answers1

0

Well, the error you've got means you're trying to read a file from a string.

AttributeError: 'str' object has no attribute 'filename'

This happens because your uploadPaper() function is returning a string (Or 'str') instead of a 'file' object. Since Python is object-oriented, your script is probably trying to read the "filename" attribute from the file object.

I can also see in your function that there is an object with the attribute you're trying to use, here at

msg.attach(form.paper.data.filename, 'application/octect-stream', form.paper.data.read())

It looks like the form.paper.data object has the property "filename" you're trying to user later on.

Why don't you try return form.paper.data instead of return "success"?

Franco Roura
  • 807
  • 8
  • 26
  • Actually, I tried printing type of form.paper.data and it shows 'str' which is name of the file I am uploading. I don't know how to use form.paper.data to attach my file to an email. – Abhishek Kuvalekar Feb 21 '18 at 05:07
  • That is exactly what I'm trying to say. `form.paper.data` should not be a string, it's supposed to be an object. You're trying to do `msg.attach(object.filename, 'application/octet-stream', object.read())` when your object is just a string. Strings (or 'str') don't have attributes. Please show your imported modules at the top of the code so that I can see what you're using. – Franco Roura Feb 23 '18 at 19:56
  • here are my imports: `from flask import render_template, flash, redirect, request` `from app import app, mail` `from .forms import SearchForm, RequestForm, UploadForm` `from app import searchBar` `import os, os.path, time, subprocess, datetime` `from flask_mail import Message` `from config import ADMINS` `from werkzeug.utils import secure_filename ` – Abhishek Kuvalekar Feb 26 '18 at 04:26
  • I made it word using `request`. But I want to know why my previous approach wasn't working. – Abhishek Kuvalekar Feb 26 '18 at 04:30