pythondjangoncbiete3

expected str, bytes or os.PathLike object, not InMemoryUploadedFile


I have a method to read a Newick file and return a String in Django framework which is the following:

def handle_uploaded_file(f):
    output = " "
    for chunk in f.chunks():
        output += chunk.decode('ascii')
    return output.replace("\n", "").replace("\r", "")


def post(self, request):
    form = HomeForm(request.POST, request.FILES)
    if form.is_valid():
        input = handle_uploaded_file(request.FILES['file'])
        treeGelezen = Tree(input, format=1)
        script, div = mainmain(treeGelezen)
        form = HomeForm()
    args = {'form': form, 'script': script, 'div': div}
    return render(request, self.template_name, args)

Which works fine for normal Newick files but i also have some files which have a string at the beginning of the file. I'm trying to make another method which checks if the file has the following String before it (which is the case in some files): "newick;" and removes the string if found. It works locally but i can't seem to merge them. This is how it locally looks like:

def removeNewick(tree_with_newick):
    for x in tree_with_newick:
        if x.startswith('newick;'):
            print('')
    return x


filepath = "C:\\Users\\msi00\\Desktop\\ncbi-taxanomy.tre"
tree_with_newick = open(filepath)
tree = Tree(newick=removeNewick(tree_with_newick), format=1)

which works perfectly when i specify the path just in python so i tried combining them in Django like this:

def handle_uploaded_file(f):
    tree_with_newick = open(f)
    for x in tree_with_newick:
        if x.startswith('newick;'):
            print('')
    return cutFile(x)


def cutFile(f):
    output = " "
    for chunk in f.chunks():
        output += chunk.decode('ascii')
    return output.replace("\n", "").replace("\r", "")


def post(self, request):
    form = HomeForm(request.POST, request.FILES)
    if form.is_valid():
        input = handle_uploaded_file(request.FILES['file'])
        treeGelezen = Tree(input, format=1)
        script, div = mainmain(treeGelezen)
        form = HomeForm()
    args = {'form': form, 'script': script, 'div': div}
    return render(request, self.template_name, args)

Which doesn't work and it gives the following error:

expected str, bytes or os.PathLike object, not InMemoryUploadedFile

I've been working on it for two days already and couldn't figure out why the error is popping up.


Solution

  • The error is happening because the function handle_uploaded_file(f) is trying to open an already opened file.

    The value of request.FILES['file'] is a InMemoryUploadedFile and can be used like a normal file. You don't need to open it again.

    To fix, just remove the line that tries to open the file:

    def handle_uploaded_file(f):
        for x in f:
            if x.startswith('newick;'):
                print('')
        return cutFile(x)