I am trying to get an image from a website and I don't know what i am doing wrong.
Here is my code:
import httplib2
h = httplib2.Http('.cache')
response, content = h.request('http://1.bp.blogspot.com/-KSBzFF0bIyU/TtFyj-KgC0I/AAAAAAAABEo/o43IoY_9Bec/s1600/praia-de-ponta-verde-maceio.jpg')
print(response.status)
with open('maceio.jpg', 'wb') as f:
print(content, file = f)
--------------------------------------------------------------------------------
200
Traceback (most recent call last):
File "/home/matheus/workspace/Get Link/new_method_v2.py", line 12, in <module>
print(content, file = f)
TypeError: 'str' does not support the buffer interface
The error is caused by the following line:
print(content, file = f)
print implicitely converts the bytes object named content to a string (str object), which cannot be written to a file in binary mode, since Python does not know which character encoding to use.
Why are you taking the print detour at all? Just write the contents to the file using the file.write() method:
with open('maceio.jpg', 'wb') as f:
f.write(content)
Related
I followed Kodi simple video plugin tutorial which works as expected with JSON string embedded into main.py file.
The tutorial refers that JSON string can be obtained by other means from other media (file, internet).
My attempt to read utf-8 JSON file into the string was unsuccessful so far.
Initially I tried the following approach
import json
import codecs
fname = 'c:/temp/iptv/video_data.json'
with open(fname, encoding='utf-8') as f:
data = f.read()
VIDEO = json.loads(data)
What produced the following error in log file
2020-05-09 11:11:29.327 T:19428 ERROR: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
- NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
Error Type: <type 'exceptions.TypeError'>
Error Contents: 'encoding' is an invalid keyword argument for this function
Traceback (most recent call last):
File "C:\Users\Alex Fox\AppData\Roaming\Kodi\addons\plugin.video.example\main.py", line 27, in <module>
with open(fname, encoding='utf-8') as f:
TypeError: 'encoding' is an invalid keyword argument for this function
-->End of Python script error report<--
I investigated the problem and found that Kodi 18.4 uses python27.dll and I assume that this library is somehow accessed from Kodi.
I substituted the code above with following code snippet into main.py file
import json
import codecs
fname = 'c:/temp/iptv/video_data.json'
with open(fname, 'rb') as f:
bytes = f.read()
data = bytes.decode('utf-8')
VIDEOS = json.loads(data)
On plugin's run it produces following error record in log file
2020-05-09 16:54:17.024 T:5700 ERROR: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
- NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
Error Type: <type 'exceptions.UnicodeEncodeError'>
Error Contents: 'ascii' codec can't encode characters in position 1-4: ordinal not in range(128)
Traceback (most recent call last):
File "C:\Users\Alex Fox\AppData\Roaming\Kodi\addons\plugin.video.example\main.py", line 239, in <module>
router(sys.argv[2][1:])
File "C:\Users\Alex Fox\AppData\Roaming\Kodi\addons\plugin.video.example\main.py", line 233, in router
list_categories()
File "C:\Users\Alex Fox\AppData\Roaming\Kodi\addons\plugin.video.animatron\main.py", line 137, in list_categories
url = get_url(action='listing', category=category)
File "C:\Users\Alex Fox\AppData\Roaming\Kodi\addons\plugin.video.animatron\main.py", line 66, in get_url
return '{0}?{1}'.format(_url, urlencode(kwargs))
File "C:\bin\Portable\Kodi\system\python\Lib\urllib.py", line 1343, in urlencode
v = quote_plus(str(v))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-4: ordinal not in range(128)
-->End of Python script error report<--
While at the same time following code outside KODI (tested with Python 3.8.2)
import json
import codecs
fname = 'c:/temp/iptv/animation.json'
with open(fname, 'rb') as f:
bytes = f.read()
str = bytes.decode('utf-8')
VIDEOS = json.loads(str)
print(json.dumps(VIDEOS, indent=4))
for key in VIDEOS.keys():
print(key)
outputs JSON dump and VIDEO dictionary keys properly.
What is a proper way to read utf-8 encoded JSON file/internet into a string in Kodi?
Solution for obtaining data from web server:
Download and install from zip file script.modules.requtests-2.22.0.zip in Kodi.
Then add into addon.xml file <import addon="script.module.requests" version="2.22.0"/>
<requires>
<import addon="xbmc.python" version="2.25.0"/>
<import addon="script.module.requests" version="2.22.0"/>
</requires>
Now in plugin's main.py file insert following code snippet
import json
import requests
url = 'http://iptv.server.com/series.json'
VIDEOS = {}
html = requests.get(url)
DATA = json.loads(html.content)
for title in DATA.keys():
title_utf8 = title.encode('utf-8')
VIDEOS[title_utf8] = []
for episode in DATA[title]:
episode['name'] = episode['name'].encode('utf-8')
episode['genre'] = episode['genre'].encode('utf-8')
VIDEOS[title_utf8].append(episode)
Launch Kodi and test the plugin.
Next code snippet is for reading file from local storage
import json
fname = 'c:/temp/iptv/animation.json';
VIDEOS = {}
with open(fname,'r') as f:
str = f.read()
DATA = json.loads(str)
for title in DATA.keys():
title_utf8 = title.encode('utf-8')
VIDEOS[title_utf8] = []
for episode in DATA[title]:
episode['name'] = episode['name'].encode('utf-8')
episode['genre'] = episode['genre'].encode('utf-8')
VIDEOS[title_utf8].append(episode)
I've just rebuilt my Raspberry Pi and hence installed the latest version of the Dropbox API and now my program doesn't work. I think this is due to point 1 in these breaking changes: https://github.com/dropbox/dropbox-sdk-python/releases/tag/v7.1.0. I'm sure this question from SO (Dropbox API v2 - trying to upload file with files_upload() - throws TypeError) solves my problem... but as a newbie, I can't figure out how to actually implement it - and anyway, I'm already using f.read()... can anyone help?
This is my code:
def DropboxUpload(file):
sourcefile = "/home/pi/Documents/iot_pm2/dropbox_transfer/" + filename
targetfile = "/" + filename
dbx = dropbox.Dropbox(cfg.dropboxtoken)
f = open(sourcefile, "r")
filecontents = f.read()
try:
dbx.files_upload(filecontents, targetfile, mode=dropbox.files.WriteMode.overwrite)
except dropbox.exceptions.ApiError as err:
print(err)
f.close()
And this is the error:
Traceback (most recent call last):
File "/home/pi/Documents/iot_pm2/dropbox_uploader.py", line 20, in <module>
DropboxUpload(filename)
File "/home/pi/Documents/iot_pm2/dropbox_uploader.py", line 12, in DropboxUpload
dbx.files_upload(filecontents, targetfile, mode=dropbox.files.WriteMode.overwrite)
File "/usr/local/lib/python3.5/dist-packages/dropbox/base.py", line 2125, in files_upload
f,
File "/usr/local/lib/python3.5/dist-packages/dropbox/dropbox.py", line 272, in request
timeout=timeout)
File "/usr/local/lib/python3.5/dist-packages/dropbox/dropbox.py", line 363, in request_json_string_with_retry
timeout=timeout)
File "/usr/local/lib/python3.5/dist-packages/dropbox/dropbox.py", line 407, in request_json_string
type(request_binary))
TypeError: expected request_binary as binary type, got <class 'str'>
Thanks in advance.
You need to supply bytes, but you're supplying str.
You can get bytes by changing the file mode to binary. I.e., instead of:
f = open(sourcefile, "r")
do:
f = open(sourcefile, "rb")
I'm pulling in a file from FTP that I want to put in a Pandas dataframe eventually. I am stuck up on decoding the output into a string that can be read by pd.read_csv.
def fetch_data():
ftp = FTP('hostname')
ftp.login('username','password')
files = ftp.nlst()
output = []
for file in files:
filedata = open("C:/Users/USER/" + file, 'w+b')
ftp.retrbinary("RETR " + file, filedata.write)
ftp.quit()
decoded_data = bytes.decode(filedata)
output_frame = pd.read_csv(decoded_data)
output.append(output_frame)
Here's the traceback:
Traceback (most recent call last):
File "dataframe.py", line 70, in <module> fetch_data()
File "dataframe.py", line 32, in fetch_data
decoded_data = bytes.decode(filedata)
TypeError: descriptor 'decode' requires a 'bytes' object but received a'_io.BufferedRandom'
I think I am misunderstanding the binary information coming from ftp.retrbinary.
What's the best way to decode this information so that it can be read by pd.read_csv?
It looks like for what you want you could simply use pd.read_csv by passing it the path to your downloaded file instead:
output_frame = pd.read_csv("C:/Users/USER/" + file)
I am trying to use the API from https://neweden-dev.com/ZKillboard_API in python.
My code works up to this point:
import xml.etree.ElementTree as ET
import urllib2
import gzip
import zlib
url = 'https://zkillboard.com/api/kills/characterID/95089021/xml/'
request = urllib2.Request(url)
request.add_header('Accept-encoding', 'gzip,deflate')
data = urllib2.urlopen(request)
After this point, I get very confused.
contents = data.read()
f = open("export.xml","w")
f.write(contents)
f.close()
Above was my first step. Opening the file made me realize that it was compressed (duh).
So from this point I tried two things:
f = open("test.xml.gz", "w")
f.write(data.read())
f.close()
g = gzip.open("test.xml.gz", "rb")
file_content = g.read()
g.close()
which gives me the error:
Traceback (most recent call last):
File "C:\Users\[filepath]", line 19, in <module>
file_content = g.read()
File "C:\Python27\lib\gzip.py", line 254, in read
self._read(readsize)
File "C:\Python27\lib\gzip.py", line 312, in _read
uncompress = self.decompress.decompress(buf)
error: Error -3 while decompressing: invalid distance too far back
My next step was to use zlib:
x = zlib.decompress(data.read())
which gives me the error of:
Traceback (most recent call last):
File "C:\Users\[filepath]", line 15, in <module>
x = zlib.decompress(data.read())
error: Error -3 while decompressing data: incorrect header check
I know I am missing something super simple here, any thoughts? Thanks.
I need to read from a file, linewise. Also also need to make sure the encoding is correctly handled.
I wrote the following code:
#!/bin/bash
import codecs
filename = "something.x10"
f = open(filename, 'r')
fEncoded = codecs.getreader("ISO-8859-15")(f)
totalLength = 0
for line in fEncoded:
totalLength+=len(line)
print("Total Length is "+totalLength)
This code does not work on all files, on some files I get a
Traceback (most recent call last):
File "test.py", line 11, in <module>
for line in fEncoded:
File "/usr/lib/python3.2/codecs.py", line 623, in __next__
line = self.readline()
File "/usr/lib/python3.2/codecs.py", line 536, in readline
data = self.read(readsize, firstline=True)
File "/usr/lib/python3.2/codecs.py", line 480, in read
data = self.bytebuffer + newdata
TypeError: can't concat bytes to str
Im using python 3.3 and the script must work with this python version.
What am I doing wrong, I was not able to find out which files work and which not, even some plain ASCII files fail.
You are opening the file in non-binary mode. If you read from it, you get a string decoded according to your default encoding (http://docs.python.org/3/library/functions.html?highlight=open%20builtin#open).
codec's StreamReader needs a bytestream (http://docs.python.org/3/library/codecs#codecs.StreamReader)
So this should work:
import codecs
filename = "something.x10"
f = open(filename, 'rb')
f_decoded = codecs.getreader("ISO-8859-15")(f)
totalLength = 0
for line in f_decoded:
total_length += len(line)
print("Total Length is "+total_length)
or you can use the encoding parameter on open:
f_decoded = open(filename, mode='r', encoding='ISO-8859-15')
The reader returns decoded data, so I fixed your variable name. Also, consider pep8 as a guide for formatting and coding style.