CGI with Python - python

I'm beginning to use CGI with Python.
After running the following piece of code:
#!c:\python34\python.exe
import cgi
print("Content-type: text/html\n\n") #important
def getData():
formData = cgi.FieldStorage()
InputUN = formData.getvalue('username')
InputPC = formData.getvalue('passcode')
TF = open("TempFile.txt", "w")
TF.write(InputUN)
TF.write(InputPC)
TF.close()
if __name__ =="__main__":
LoginInput = getData()
print("cgi worked")
The following error occurs:
Traceback (most recent call last):
File "C:\xampp\htdocs\actual\loginvalues.cgi", line 21, in <module>
LoginInput = getData()
File "C:\xampp\htdocs\actual\loginvalues.cgi", line 16, in getData
TF.write(InputUN)
TypeError: must be str, not None
>>>
I'm trying to write the values, inputted in html, to a text file.
Any help would be appreciated :)

Your calls to getValue() are returning None, meaning the form either didn't contain them, had them set to an empty string, or had them set by name only. Python's CGI module ignores inputs that aren't set to a non-null string.
Works for Python CGI:
mysite.com/loginvalues.cgi?username=myname&pass=mypass
Doesn't work for Python CGI:
mysite.com/loginvalues.cgi?username=&pass= (null value(s))
mysite.com/loginvalues.cgi?username&pass (Python requires the = part.)
To account for this, introduce a default value for when a form element is missing, or handle the None case manually:
TF.write('anonymous' if InputUN is None else InputUN)
TF.write('password' if InputPC is None else InputUN)
As a note, passwords and other private login credentials should never be used in a URL. URLs are not encrypted. Even in HTTPS, the URL is sent in plain text that anyone on the network(s) between you and your users can read.
The only time a URL is ever encrypted is over a tunneled SSH port or an encrypted VPN, but you can't control that, so never bank on it.

Related

How to retrieve the last 5 characters from dictionary value after converting to string

I'm writing a Python script that logs into a server and pulls router data through an api. The pulled data is then used to create a dictionary with router names as the key and a telnet url as the key. Here is an example of the url that's collected.
telnet://192.168.1.113:32769
The telnet port is the last 5 characters of the url and I'm trying to pull that information only. I know with a string I can use (-5) but I'm getting the following error.
Traceback (most recent call last):
File "C:\Users\b\Documents\Atom Test1 Project\test_wip.py", line 41, in <module>
test_value2=test_value.split(-5)
TypeError: must be str or None, not int
[Finished in 1.812s]
I think this means I need to convert it tonto a string. I tried converting and then retrieving the last 5 charcters but it's not working. Here is my code.
from __future__ import unicode_literals, print_function
import eve
import json
import time
from netmiko import ConnectHandler, redispatch
#from resteve import eve
import json
address = '192.168.1.113'
instance = m11.Server(address)
instance.login('admin', 'password', '0')
users = instance.get_all_nodes()
payload = json.loads(users.content)
data = payload['data']
users = instance.get_all_nodes()
payload = json.loads(users.content)
data = payload['data']
for item in payload["data"].values():
result[item["name"]] = item["url"]
test_value=item['url']
print(test_value)
test_value.format(str)
test_value2=test_value.split(-5)
print(test_value2)
I'm new at this and still putting it all together so any help is greatly appreciated. Thanks.
To get last 5 chars use indexing test_value[-5:], because .split() expects a string and here it will try to split on the first argument

Executing arbitrary Python code (user submitted) inside an Azure Function

I'm trying to run a sample function that allows a user to execute arbitrary code
Note: I"m assuming this is ok because Azure Functions will by default provide a sandbox. (And the end user will need to write code with dataframes, objects etc. I've looked into pypy.org but don't think I need it as I am not worried about attacks that use it as a spambot or something):
import os
import json
import ast
print('==============in python function========================')
postreqdata = json.loads(open(os.environ['req']).read())
response = open(os.environ['res'], 'w')
response.write("hello world from "+postreqdata['name'])
response.close()
logic = (postreqdata['logic'])
eval(logic)
but I keep getting the following output/error:
2018-01-17T09:09:08.949 ==============in python function========================
2018-01-17T09:09:09.207 Exception while executing function: Functions.ccfinopsRunModel. Microsoft.Azure.WebJobs.Script: Traceback (most recent call last):
File "D:\home\site\wwwroot\ccfinopsRunModel\run.py", line 12, in <module>
eval(logic)
File "<string>", line 1
print('code sent from client')
^
SyntaxError: invalid syntax
.
My POST request body contains the following:
{
"name": "Python Function App",
"logic": "print('code sent from client')"
}
So the "logic" variable is being read in, and eval() is trying to interpret the string as python code, but it is causing a Syntax Error where there appears to be none.
What am I doing wrong? If there was a restriction on 'eval' I'm assuming it would say that instead of "Syntax Error"
Thanks for any help you can provide!
Use exec to run your code. eval is used evaluating expressions.
logic = (postreqdata['logic'])
exec(logic)
Also can try sending your code as multi-line string as below,
>>> s = '''
for i in range(3):
print("i")
'''
>>> exec(s)
0
1
2

Read-attribute-missing error while uploading file in Python

I am trying to allow a user to upload files to a server from a form, and then display images from my website. The script is Python, which also interfaces to MySQL via cursor.execute commands. I can upload text form fields, but not the file contents, similar to the problem reported at:
uploading html files and using python
I can upload the selected file name, but not read it; I get a read error.
My code is:
#!/home2/snowbear/python/Python-2.7.2/python
import cgi
# Import smtplib for the actual sending function.
import smtplib
import shutil
import datetime
import os
import sys, traceback, re
# Helps troubleshoot python script.
import cgitb; cgitb.enable()
# Import mysql database program.
import mysql.connector
# Windows needs stdio set for binary mode.
try:
import msvcrt
msvcrt.setmode (0, os.O_BINARY) # stdin = 0
msvcrt.setmode (1, os.O_BINARY) # stdout = 1
except ImportError:
message = "No Windows msvcrt to import"
pass
print '<form name="PB_Form" action="PB_resubmit.py" method="post" enctype="multipart/form-data">'
...
# Get form values.
...
if form.has_key("filePix1") and form["filePix1"].value != "":
txtImage1 = form['filePix1'].value
fileItem1 = form['filePix1']
if not fileItem1.file:
print "<br><center>No fileItem1: %s</center>" % fileItem1
else:
data = fileItem1.file.read()
objFile = open(txtImage1, "w+")
objFile.write(data)
objFile.close()
else:
newImage1 = False
...
I get an error for the line:
data = fileItem1.file.read()
The error is:
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'read'
args = ("'NoneType' object has no attribute 'read'",)
message = "'NoneType' object has no attribute 'read'"
Although "fileitem1" is a proper handle to the file entered into the form, since I can get the file name, it however, does not have a "read attribute," as specified in the error message.
I'm using Bluehost for my server. Could the file-read attribute be turned off by the server, or am I missing something, such as another special import for handling files?
Thanks for any suggestions, Walter
&&&&&&&&&&&&&&&&
New note:
The problem was that form['filePix1'] "file" and "filename" attributes were missing; only the "value" attribute existed, and this would only produce the file name, not the file contents.
With much experimenting, I discovered that the browser, Sea Monkey, is causing the problem of missing attributes. When I used Firefox, the "file," "filename," and "value" attributes were normal. I have no idea why Sea Monkey doesn't support file loading attributes.
Walter

Type error writing to file in Python

I am writing a Python script to notify me when changes are made to a webpage and store the current state of the page to a file in order to resume seamlessly after rebooting.
The code is as follows:
import urllib
url="http://example.com"
filepath="/path/to/file.txt"
try:
html=open(filepath,"r").read() # Restores imported code from previous session
except:
html="" # Blanks variable on first run of the script
while True:
imported=urllib.urlopen(url)
if imported!=html:
# Alert me
html=imported
open(filepath,"w").write(html)
# Time delay before next iteration
Running the script returns:
Traceback (most recent call last):
File "April_Fools.py", line 20, in <module>
open(filepath,"w").write(html)
TypeError: expected a character buffer object
------------------
(program exited with code: 1)
Press return to continue
I've no idea what this means. I'm relatively new to Python. Any help would be much appreciated.
urllib.urlopen does not return a string, it returns a response as a file-like object. You need to read that response:
html = imported.read()
Only then is html a string you can write to a file.
As an aside, using open(filename).read() is not considered good style, because you never close the file. The same goes for writing. Try using a context manager instead:
try:
with open(filepath,"r") as htmlfile:
html = htmlfile.read()
except:
html=""
The with block will automatically close the file when you leave the block.

How do I search for text in a page using regular expressions in Python?

I'm trying to create a simple module for phenny, a simple IRC bot framework in Python. The module is supposed to go to http://www.isup.me/websitetheuserrequested to check is a website was up or down. I assumed I could use regex for the module seeing as other built-in modules use it too, so I tried creating this simple script although I don't think I did it right.
import re, urllib
import web
isupuri = 'http://www.isup.me/%s'
check = re.compile(r'(?ims)<span class="body">.*?</span>')
def isup(phenny, input):
global isupuri
global cleanup
bytes = web.get(isupuri)
quote = check.findall(bytes)
result = re.sub(r'<[^>]*?>', '', str(quote[0]))
phenny.say(result)
isup.commands = ['isup']
isup.priority = 'low'
isup.example = '.isup google.com'
It imports the required web packages (I think), and defines the string and the text to look for within the page. I really don't know what I did in those four lines, I kinda just ripped the code off another phenny module.
Here is an example of a quotes module that grabs a random quote from some webpage, I kinda tried to use that as a base: http://pastebin.com/vs5ypHZy
Does anyone know what I am doing wrong? If something needs clarified I can tell you, I don't think I explained this enough.
Here is the error I get:
Traceback (most recent call last):
File "C:\phenny\bot.py", line 189, in call
try: func(phenny, input)
File "C:\phenny\modules\isup.py", line 18, in isup
result = re.sub(r'<[^>]*?>', '', str(quote[0]))
IndexError: list index out of range
try this (from http://docs.python.org/release/2.6.7/library/httplib.html#examples):
import httplib
conn = httplib.HTTPConnection("www.python.org")
conn.request("HEAD","/index.html")
res = conn.getresponse()
if res.status >= 200 and res.status < 300:
print "up"
else:
print "down"
You will also need to add code to follow redirects before checking the response status.
edit
Alternative that does not need to handle redirects but uses exceptions for logic:
import urllib2
request = urllib2.Request('http://google.com')
request.get_method = lambda : 'HEAD'
try:
response = urllib2.urlopen(request)
print "up"
print response.code
except urllib2.URLError, e:
# failure
print "down"
print e
You should do your own tests and choose the best one.
The error means your regexp wasn't found anywhere on the page (the list quote has no element 0).

Categories