# Run external python script with input file as argument

**URL:** <https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794>\
**Category:** Using Django\
**Created:** [December 3, 2021, 10:21am UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794 "2021-12-03T10:21:22Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ptrs32](https://avatars.discourse-cdn.com/v4/letter/p/47e85d/32.png) [@ptrs32](https://forum.djangoproject.com/u/ptrs32)\
**Post date:** [December 3, 2021, 10:21am UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794/1 "2021-12-03T10:21:22Z")

</div>

Hello, i’m trying to developp my first Django project and i’m actually stuck with an error.

So i have on my HTML template a button to load a xls file, and a submitting button that i want it to start an external python script using this file.

Here is my project:

home.html

```auto
<h1>Home</h1>
<form action="/external/" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    Input xls file :<br><br>
    <input type="file" name="InputFile" accept=".xls" required><br>
    <input type="submit" value="execute python script"><br>
</form>

```

views.py

```auto
from subprocess import run, PIPE
import sys

def home(request):
    return render(request, 'home.html')

def external(request):
    inp=request.FILES.get('InputFile')
    run([sys.executable,r'pathToMyDjangoProject\script.py', inp], shell=False,stdout=PIPE)
    return render(request,'home.html')

```

urls.py

```auto
urlpatterns = [
    path(r'', views.home),
    path('external/', views.external),
]

```

script.py

```auto
def process(excelFile):
    rdr = pd.read_excel(excelFile, header=None).values.tolist()
    
    for row in rdr:
    ...

```

Finally the html page seems to work, le type of **inp** is a _django InMemoryUploadedFile_ so i guess it’s correctly loaded but the error i have is :

> **TypeError at /external/**  
> expected str, bytes or os.PathLike object, not InMemoryUploadedFile  
> .  
> |Request Method:|POST|  
> |Request URL:|[http://127.0.0.1:8000/external/|](http://127.0.0.1:8000/external/%7C)  
> |Django Version:|3.2.7|  
> |Exception Type:|TypeError|  
> |Exception Value:|expected str, bytes or os.PathLike object, not InMemoryUploadedFile|

I think to understand there is a problem with variable’s type in the run() function but do you have an idea to correct it ?

Thank you by advance,

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [December 3, 2021, 1:34pm UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794/2 "2021-12-03T13:34:35Z")

</div>

The way you have this constructed, you’re going to need to save the file to disk somewhere, and then pass the fully-qualified file name as the parameter.

---

<div class="post-metadata">

**Author:** ![ptrs32](https://avatars.discourse-cdn.com/v4/letter/p/47e85d/32.png) [@ptrs32](https://forum.djangoproject.com/u/ptrs32)\
**Post date:** [December 3, 2021, 1:46pm UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794/3 "2021-12-03T13:46:22Z")

</div>

Ok thank you, that is also what i thought.

And otherwise, do you have any idea on how to do it without the need to save the file ? Not the full script but maybe some terms or links to help me search in the right way ?

---

<div class="post-metadata">

**Author:** ![nemecek\_f](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/nemecek_f/32/668_2.png) [@nemecek\_f](https://forum.djangoproject.com/u/nemecek_f)\
**Post date:** [December 3, 2021, 4:57pm UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794/4 "2021-12-03T16:57:35Z")

</div>

What about some model? Like `FileToProcess`?

You can then create `manage.py` command that has access to Django ORM, you can query the “to be processed” files and do what you need to do.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [December 3, 2021, 9:13pm UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794/5 "2021-12-03T21:13:33Z")

</div>

Unless there’s more to this than what you’ve posted, I don’t see the benefit of running this as an external process.

Instead of:

> [@ptrs32](#):
>
> ```auto
> def external(request):
> inp=request.FILES.get('InputFile')
> run([sys.executable,r'pathToMyDjangoProject\script.py', inp], shell=False,stdout=PIPE)
> return render(request,'home.html')
> 
> ```
> 
> def process(excelFile):  
> rdr = pd.read\_excel(excelFile, header=None).values.tolist()
> 
> ```
> for row in rdr:
> ...
> 
> ```

You could try:

```auto
def external(request):
    inp=request.FILES.get('InputFile')
    process(inp)
    return render(request,'home.html')

def process(excelFile):
    rdr = pd.read_excel(excelFile, header=None).values.tolist()
    
    for row in rdr:
    ...

```

You may also need to open and read the file to get the data from the file field - see [Managing files | Django documentation | Django](https://docs.djangoproject.com/en/3.2/topics/files/#using-files-in-models).

---

<div class="post-metadata">

**Author:** ![ptrs32](https://avatars.discourse-cdn.com/v4/letter/p/47e85d/32.png) [@ptrs32](https://forum.djangoproject.com/u/ptrs32)\
**Post date:** [December 6, 2021, 10:11am UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794/6 "2021-12-06T10:11:41Z")

</div>

Well, my _script.py_ is about 600 lines long. I did not imagine myself integrating it fully into the _external_ function of _views.py_. Even if in practice it would work.

And what if i turn it into a python function and i just import it to views.py ? any contraindications?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [December 6, 2021, 1:26pm UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794/7 "2021-12-06T13:26:30Z")

</div>

> [@ptrs32](#):
>
> Well, my _script.py_ is about 600 lines long. I did not imagine myself integrating it fully into the _external_ function of _views.py_ .

Notice that I didn’t suggest that. I show `external` as calling a function named `process`.

> [@ptrs32](#):
>
> And what if i turn it into a python function and i just import it to views.py ?

A function is a function. There is no semantic difference whether a function resides in the same file or is in a different file and imported.

> [@ptrs32](#):
>
> any contraindications?

None at all.

The key here is that there’s no need to start another instance of Python to run your function. (Ok, so there _are_ a couple of real edge cases that may make it desirable to do so, I just have no reason to believe that this would be one of them.)  
By running your function within the same process, you can pass the data directly - it does not need to be passed via some external mechanism like a file or pipe.

---

<div class="post-metadata">

**Author:** ![ptrs32](https://avatars.discourse-cdn.com/v4/letter/p/47e85d/32.png) [@ptrs32](https://forum.djangoproject.com/u/ptrs32)\
**Post date:** [December 6, 2021, 1:31pm UTC](https://forum.djangoproject.com/t/run-external-python-script-with-input-file-as-argument/10794/8 "2021-12-06T13:31:50Z")

</div>

I understand, yes sorry I did not really understand your first answer but it is ultimately the simplest to put in place.  
Thanks for your help
