Read-attribute-missing error while uploading file in Python - 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

Related

TypeError: '_Folders' object is not callable

I'm using win32.client and trying to manipulate email body text.
This was working today but I think when testing I might have broken Outlook! When I try to call an index of a _Folders object, I get a type error that it is uncallable.
I use indexes to get into my nested folders. This was working until tonight and I haven't changed any of the code.
import win32com.client
import urllib.parse
import webbrowser
from pyshorteners import Shortener
application = win32com.client.Dispatch('Outlook.Application')
namespace = application.GetNamespace('MAPI')
# 6 is the number for the main inbox
inbox_folder = namespace.GetDefaultFolder(6)
# had to create multiple objects of subfolders to get to specific directory
inbox = inbox_folder.Folders
mobile_folder = inbox(3)
mobile_folder_directory = mobile_folder.Folders
mobile_script_folder = mobile_folder_directory(2)
# using Items method to parse specific email files within the folder
messages = inbox_folder.Items
I get this error:
File "mail1.py", line 10, in mobile_folder = inbox_folders(3) TypeError: '_Folders' object is not callable
I was messing around with other code trying to monitor my inbox for new mail.
I ran some of this code in another file with some modifications to match my inboxes
import ctypes # for the VM_QUIT to stop PumpMessage()
import pythoncom
import win32com.client
import sys
# outlook config
SHARED_MAILBOX = "Your Mailbox Name"
# get the outlook instance and inbox folder
session = win32com.client.Dispatch("Outlook.Application").Session
user = session.CreateRecipient(SHARED_MAILBOX)
shared_inbox = session.GetSharedDefaultFolder(user, 6).Items # 6 is Inbox
class HandlerClass(object):
def OnItemAdd(self, item):
print("New item added in shared mailbox")
if item.Class == 43:
print("The item is an email!")
outlook = win32com.client.DispatchWithEvents(shared_inbox, HandlerClass)
def main():
print("Starting up Outlook watcher")
pythoncom.PumpMessages()
if __name__ == "__main__":
try:
status = main()
sys.exit(status)
except KeyboardInterrupt:
print("Terminating program..")
ctypes.windll.user32.PostQuitMessage(0)
sys.exit()
My suspicion is that it changed something with Outlook versions.
I also got something saying that a MAPIFolder object isn't callable. My research was showing this is an old, unsupported Outlook protocol.
Here's more data when I try to index my folders:
>>> inbox_folder
<win32com.gen_py.Microsoft Outlook 16.0 Object Library.MAPIFolder instance at 0x12191504>
>>> inbox = inbox_folder.Folders
>>> inbox
<win32com.gen_py.Microsoft Outlook 16.0 Object Library._Folders instance at 0x46668848>
>>> inbox(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '_Folders' object is not callable
I still don't know what broke it, but it turns out that searching folders by index wasn't working anymore.
The solution was now searching by folder name:
inbox_folder = namespace.GetDefaultFolder(6)
# had to create multiple objects of subfolders to get to specific directory
inbox = inbox_folder.Folders
mobile_folder = inbox["Mobile"]
mobile_script_folder = mobile_folder.Folders["Mobile_4_4_Alpha"]
not sure why it fixed it but it did. yay!
don't know why but delete this file work in my case.
C:\Users\[user name]\AppData\Local\Temp\gen_py\[python version]\00062FFF-0000-0000-C000-000000000046x0x9x6.py
credit: https://blog.csdn.net/ericatardicaca/article/details/90721909

How to download photos from Flickr by Flickr API in Python 3

noob question series...
I am a new learner of python, recently want to create a small python application that can collect photos from flickr based on different search input. (eg: if i input "dog", it will download all dog images from flickr)
I did some research online and notice that flickr API might be the best way and the method flickr.photos.getSizes should be the one I need to use.
However, I have few stupid questions when coding:
I have applied my key and secret for flickr API, I just don't know what to do next with flickr.photos.getSizes in python to download photos. Like, how to call this method in python? (and I noticed required arguments for this method are keys and photo_id, how to get photo_ids based on search input "dog")
Then I followed a tutorial from https://github.com/alexis-mignon/python-flickr-api/wiki/Tutorial but when I imported flickr_api I got error message:
Could not load all modules
<class 'ImportError'> No module named 'objects'
Traceback (most recent call last):
File "D:/Agfa/Projects/Image/flickr.py", line 2, in <module>
import flickr_api
File "D:\Application\Anaconda3\lib\site-packages\flickr_api\__init__.py", line 32, in <module>
from auth import set_auth_handler
ImportError: cannot import name 'set_auth_handler'
Then I took a look at the _ init _.py:
try:
from objects import *
import objects
import upload as Upload
from upload import upload, replace
except Exception as e:
print "Could not load all modules"
print type(e), e
from auth import set_auth_handler
from method_call import enable_cache, disable_cache
from keys import set_keys
from _version import __version__
Seems like this library does not support python 3 but I don't know what to do. (I cannot install methond_call, keys, _version on my python 3) guess I will use flickrapi
Thank you so much for your time and again thanks in advance.
I think I finally got the proper way to use FlickrAPI:
there are many ways but I figured out 2:
def flickr_walk(keyward):
count = 0
photos = flickr.walk(text=keyward,
tag_mode='all',
tags=keyward,
extras='url_c',
per_page=100)
for photo in photos:
try:
url=photo.get('url_c')
urllib.request.urlretrieve(url, path+'\\' + str(count) +".jpg")
except Exception as e:
print('failed to download image')
flickr.walk uses Photos.search API, I can use the API directly as well:
def flickr_search(keyward):
obj = flickr.photos.search(text=keyward,
tags=keyward,
extras='url_c',
per_page=5)
for photo in obj:
url=photo.get('url_c')
photos = ET.dump(obj)
print (photos)
Remember to get the key and secret first:
api_key = 'xxxxxxxxxxxxxxxx'
api_secret = 'xxxxxxxxxxxxx'
flickr=flickrapi.FlickrAPI(api_key,api_secret,cache=True)
I dont have any clue on the why/how. If you want to use the flickr_api module with python3.5+, you need to fix the Imports, like I did below:
try:
from objects import *
import objects
import upload as Upload
from upload import upload, replace
except Exception as e:
#print "Could not load all modules"
print( type(e), e)
from .auth import set_auth_handler
from .method_call import enable_cache, disable_cache
from .keys import set_keys
from ._version import __version__
After this edit, it fails with another Import Error on:
>>> import flickr_api
<class 'SyntaxError'> invalid syntax (method_call.py, line 50)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/krysopath/.local/lib/python3.5/site-packages/flickr_api/__init__.py", line 32, in <module>
from .auth import set_auth_handler
File "/home/krysopath/.local/lib/python3.5/site-packages/flickr_api/auth.py", line 43, in <module>
import urlparse
ImportError: No module named 'urlparse'
So you can fix this by yourself, if you want to, by just walking along the Import Errors and adding a dot to convert them into absolute Imports, that dont fail.
I guess, if you want to use this modul you have to fix it first... and have an unknown return. So if you didnt already invested heavily, it might be more effective to use that other module.

CGI with 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.

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.

lxml.etree.iterparse closes input file handler?

filterous is using iterparse to parse a simple XML StringIO object in a unit test. However, when trying to access the StringIO object afterwards, Python exits with a "ValueError: I/O operation on closed file" message. According to the iterparse documentation, "Starting with lxml 2.3, the .close() method will also be called in the error case," but I get no error message or Exception from iterparse. My IO-foo is obviously not up to speed, so does anyone have suggestions?
The command and (hopefully) relevant code:
$ python2.6 setup.py test
setup.py:
from setuptools import setup
from filterous import filterous as package
setup(
...
test_suite = 'tests.tests',
tests/tests.py:
from cStringIO import StringIO
import unittest
from filterous import filterous
XML = '''<posts tag="" total="3" ...'''
class TestSearch(unittest.TestCase):
def setUp(self):
self.xml = StringIO(XML)
self.result = StringIO()
...
def test_empty_tag_not(self):
"""Empty tag; should get N results."""
filterous.search(
self.xml,
self.result,
{'ntag': [u'']},
['href'],
False)
self.assertEqual(
len(self.result.getvalue().splitlines()),
self.xml.getvalue().count('<post '))
filterous/filterous.py:
from lxml import etree
...
def search(file_pointer, out, terms, includes, human_readable = True):
...
context = etree.iterparse(file_pointer, tag='posts')
Traceback:
ERROR: Empty tag; should get N results.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/victor/dev/filterous/tests/tests.py", line 149, in test_empty_tag_not
self.xml.getvalue().count('<post '))
ValueError: I/O operation on closed file
PS: The tests all ran fine on 2010-07-27.
Seems to work fine with StringIO, try using that instead of cStringIO. No idea why it's getting closed.
Docs-fu is the problem. What you quoted "Starting with lxml 2.3, the .close() method will also be called in the error case," is nothing to do with iterparse. It appears on your linked page before the section on iterparse. It is part of the docs for the target parser interface. It is referring to the close() method of the target (output!) object, nothing to do with your StringIO. In any case, you also seem to have ignored that little word also. Before 2.3, lxml closed the target object only if the parse was successful. Now it also closes it upon error.
Why do you want to "access" the StringIO object after parsing has finished?
Update By trying to access the database afterwards, do you mean all those self.xml.getvalue() calls in your tests? [Show the ferschlugginer traceback in your question so we don't need to guess!] If that's causing the problem (it does count as an IO operation), forget getvalue() ... if it were to work, wouldn't it return the (unconventionally named) (invariant) XML?

Categories