How to handle argument in view

Hi
In form I’m submitting 2 argument, which will be the 2 parameter of external python script.
What changes I need to do in view

Template
        <div id="dvPassport" style="display: none">
        <form action="/external/" method="post" name="Test_Script">
            {% csrf_token %}
            Password:
            <input type="text" name="param" required><br><br>
            {{data_external}}
            <input type="text" name="clusterid" value="{{forms.clusterid}}" readonly><br><br>
        </div><br><br>
        <button class="btn ripple btn-main-primary">Submit</button>
        </form>

Here 2 arg is coming, 1 is password & 2nd clusterid.
Now we need to handle in view, where I have defined to call another python script.

from subprocess import run,PIPE
import codecs
def external(request):
	inp= request.POST.get('param')
	out= run([sys.executable,'//path//test.py',inp],shell=False,stdout=PIPE)
	return render(request,'logs.html',{'data02' :codecs.decode(out.stdout)})

Here, external python script (test.py) need to pass 2 argv, how to handle it.

Pass the password and ‘forms’ to the dictionary in your render function call (at the end of your view)

return render(request,'logs.html',{'data02' :codecs.decode(out.stdout), 'data_external': the_password, 'forms': clusterid})

There is a caveat, however:

  1. The password will be hidden when rendered normally but visible to those that know where to look. Rendering passwords … not a good idea.
  2. Your template suggests that you were using an object called ‘forms’. So, I added that to the answer instead.

Still not working.
Let me clarify my question here:-

def external(request):
	inp= request.POST.get('param')
  	out= run([sys.executable,'//Path//test.py',inp],shell=False,stdout=PIPE)
	return render(request,'logs.html',{'data02' :codecs.decode(out.stdout)})

Here, [sys.executable,‘//Path//test.py’,inp] … I’m giving one input to the script and that input, we are getting by request.POST.get(‘param’) … as name=param is defined in form.
Now, in form, I have defined 2nd input, which I’m taking from mysql DB and given the name=clusterid and I need to pass this to be 2nd input to the test.py script. This 2nd input from the form should be defined in Views…and I think, I should be using something like

	inp= request.POST.get('param')
        inp2= request.POST.get('clusterid')
  	out= run([sys.executable,'//Path//test.py',inp,inp2],shell=False,stdout=PIPE)

Please check above (in bold)…can be used somehow by little modification…as…it is not working in current format.
inp2= request.POST.get(‘clusterid’)
out= run([sys.executable,‘//Path//test.py’,inp,inp2],shell=False,stdout=PIPE)

So please provide more detail here. How is it not working? (What is it doing that you’re not expecting it to do, or what is it not doing that you’re expecting to see?)

What have you looked at to determine a cause for this issue?

  • Have you looked at what’s being passed to test.py?
  • Have you looked at what you’re getting as inp2 from the POST data?
  • Have you looked at the original html to verify that what’s being rendered is correct?

Thanks for replying.

Template
        <div id="dvPassport" style="display: none">
        <form action="/external/" method="post" name="Test_Script">
            {% csrf_token %}
            Password:
            <input type="text" name="param" required><br><br>
            {{data_external}}
            <input type="text" name="clusterid" value="{{forms.clusterid}}" readonly><br><br>
        </div><br><br>
        <button class="btn ripple btn-main-primary">Submit</button>
        </form>

As you see in form, as secondary input, I’m getting 2nd input…name=clusterid. 1st input…name=param. One difference between these 2 input is, 1st input, I’m taking from input typed by the user in form but the 2nd input, I’m getting from DB.
So, in View, I want to pass these 2 input as a argument…so that these 2 input being used in test.py.

views
-------
inp= request.POST.get('param')
inp2= request.POST.get('clusterid')
out= run([sys.executable,'//Path//test.py',inp,inp2],shell=False,stdout=PIPE)
return render(request,'logs.html',{'data02' :codecs.decode(out.stdout)})

Error message

  File "/Path/urls.py", line 20, in <module>
    from my_app import views
  File "/Path/my_app/views.py", line 34
    inp2= request.POST.get('clusterid')
                                      ^
IndentationError: unindent does not match any outer indentation level

I tried removing lines…spaces…tab±…etc but still getting same error.

Note:-
I need help here

  1. not sure why getting indentation error.
  2. The logic I’m using to pass 2 input to my external Python is correct or not
  3. In return render(…), Do I need to make any changes?

None of the other issues matter until you fix the indentation issue.

You’re only posting snippets, so without seeing an exact copy/paste of the complete view into your post (always surrounded by the three backticks), it’s going to be impossible for us to diagnose it.

But yes, I think you’re on the right track in that you’ve probably got a mix of tab characters with your spaces somewhere in your code.

This is my complete view

from django.shortcuts import render
from my_app.models import Customer
import requests
import sys
from subprocess import run,PIPE
import codecs




# Create your views here.
def all_events(request):
    form = Customer.objects.all().order_by('customer_name')
    return render(request, 'patch_management_homepage.html',{'form':form})

def all_events(request):
    form = Customer.objects.all().order_by('customer_name')
    return render(request, 'test_form.html',{'form':form})

def cluster_patch(request,clusterid):
    form = Customer.objects.all().filter(clusterid=clusterid)
    return render(request, 'cluster_patching_page.html',{'form':form})

def host_details(request,clusterid):
    form = Customer.objects.all().filter(clusterid=clusterid)
    return render(request, 'host_details.html',{'form':form})

def all_reports(request):
    return render(request, 'reports.html')


def external(request):
	inp= request.POST.get('param')
    sinp= request.POST.get('clsterid')
    out= run([sys.executable,'//Path//test.py',inp,sinp],shell=False,stdout=PIPE)
	return render(request,'logs.html',{'data02' :codecs.decode(out.stdout)})

I’m getting error in last block…def external(request)
1 difference you will find here from previous code…2nd input I’m using here name is ‘clsterid’

You have a mix of spaces and tabs here. You have tab characters at the beginning of the inp=... and return ... lines, and spaces at the beginning of the other two lines in that block.

Thanks. Now, indentation error fixed. But still, I’m not getting 2nd input in the script.
That means I need to make some changes in return…value ?
Or I’m not getting 2nd input from the form …

From one of my earlier responses:

What have you looked at to determine a cause for this issue?

  • Have you looked at what’s being passed to test.py?
  • Have you looked at what you’re getting as inp2 from the POST data?
  • Have you looked at the original html to verify that what’s being rendered is correct?

In form, test1 is getting from DB. This test1 should be passed to the python script test.py
Screenshot from 2022-12-03 09-07-47

how can I verify " * Have you looked at what you’re getting as inp2 from the POST data?"

I’m talking about the html itself that is rendered from the originating view and being sent to the browser.

You’ll want to use your browser’s developer tools to verify that the html you’re receiving is what you’re expecting to see.

You can then use the network tab to see the data that gets submitted. You can also add print statements within the view to show what values you have at different locations in the code.

Thanks, it worked, I just print the 2nd input in view. Not sure, how come it started working after printing the input.

Anyway, now I’m facing new issue.
This test.py…which is used in views…actually a python script where I’m using paramiko to connect to the remote jumpbox, and there I’m calling ansible-playbook. This is working perfectly fine and I’m also getting log on html page as well as in server once this script completes.

It is happening like this because ansible-playbook is running on remote jumpbox server and log is generating over there and once the scripts complete running over there, then it copy the log to myserver.

I have 2 question

  1. Is there anyway I can get live logfile…which I need to display on html page.
    (I’m thinking…I think, it can be achieved 2 ways…

       i)ansible-playbook should run in myserver but I'm not able to do this because I will not get approval to open a tunnel from my server to all datacenter...which is currently present in existing jumpbox.
    
       ii) If I can create a 2nd session to the jumbox and use tail -f logfile....I'm not sure...how it is feasible because my current script test.py is busy with calling ansible-playbook...so, until it completes it will not allow me to do anything else. )
    
  2. Now, I’m getting log displaying on html page but logoutput is not in proper format…I mean, one line completes there second line of log starts…so, it is not clear to understand. So, is there anyway I can format this.