I am setting up a python script to upload files to an Azure FileShare. I am following this official tutorial for SDK v2.
Now, the tutorial uses this argument: content_settings=ContentSettings(content_type='image/png'). My point is that the class ContentSettings is not very well documented and I have no idea what values of content_type are valid. This is the official documentation I could find. Does anyone know where I can find a list of valid content types for this argument? Does anyone know what happens if this argument is mispecified?
Does anyone know what happens if this argument is mispecified?
Adding to what #GauravMantri have mentioned, when you are trying to set the content type of the file other than the actual content type, the file will be no longer be in a valid format except for few of the content types and cannot be read.
For demonstration purposes, I have used the same sample as mentioned in the Official Documentation. Below is the code I'm using.
azure.storage.file import FileService
file_service = FileService(account_name='<ACCOUNT_NAME>',
account_key='<ACCOUNT_KEY>')
file_service.create_file_from_path(
'<FILESHARE_NAME>',
None,
'sunset.png',
'sunset.png',
content_settings=ContentSettings(content_type='video/x-msvideo')) ```
RESULTS:
Below are the results that I got when I'm trying to download a image/png file as video/x-msvideo content type.
Related
I've been using python-libtorrent to check what pieces belong to a file in a torrent containing multiple files.
I'm using the below code to iterate over the torrent file
info = libtorrent.torrent_info('~/.torrent')
for f in info.files():
print f
But this returns <libtorrent.file_entry object at 0x7f0eda4fdcf0> and I don't know how to extract information from this.
I'm unaware of the torrent_info property which would return piece value information of various files. Some help is appreciated.
the API is documented here and here. Obviously the python API can't always be exactly as the C++ one. But generally the interface takes a file index and returns some property of that file.
I'm trying to deliver videos, through Slack API using Python's library slackclient.
I often use slack.api_call('chat.postMessage'...) and I am familiar with 'files.upload' but when I execute
slack = SlackClient(TOKEN)
slack.api_call('files.upload', file=open('video.mp4', 'rb')...)
the file is uploaded to the given channel, but is not posted as a message.
What I am trying to achieve is to create a message which I can send as a private message or to a channel that would look something like this
and maybe add some text above it if possible.
I've explored the Attachment section in the docs, but couldn't find anything related to files.
If there is a way to not supply the file in binary format, but as a link that would also be ok (as long as it is displayed in an embedded fashion).
How about this sample script? It uses io.BytesIO(f.read()) for the file. In order to use this, files:write:user has to be included in the scopes. About the text, you can import it using initial_comment. In my environment, attachments could not be used for files.upload. The API document is https://api.slack.com/methods/files.upload.
Script :
with open('./sample.mp4', 'rb') as f:
slack.api_call(
"files.upload",
channels='#sample',
filename='sample.mp4',
title='sampletitle',
initial_comment='sampletext',
file=io.BytesIO(f.read())
)
Result :
If I misunderstand your question, I'm sorry.
I came across this question because I had the same issue - my file would upload and I would get a response, but the file would not be posted to the channel I had sent. It turned out to be a poor job by me of reading the Slack API documentation. I had used chat.postMessage many times and included a single 'channel' argument. Here is that API: https://api.slack.com/methods/chat.postMessage
The files.upload method it wants a comma separated list of channels in a 'channels' argument. See https://api.slack.com/methods/files.upload Once I changed from 'channel' to 'channels' and made sure to pass it as a list, I was successfully posting the image to the channel I wanted.
To the original question then, in your link to the code you used (https://ibb.co/hwH5hF) try changing channel='bla'to channels=['bla']
This works for me:
import slack
client = slack.WebClient(token='xoxb-XXX')
with open('/path/to/attachment.jpeg', 'rb') as att:
r = client.api_call("files.upload", files={
'file': att,
}, data={
'channels': '#my_channel',
'filename': 'downloaded_filename.jpeg',
'title': 'Attachment\'s title',
'initial_comment': 'Attachment\'s description',
})
assert r.status_code == 200
I am confronted to the loss of alpha channel when I try to send image to clipboard, none of the solutions described here worked with the software I am working with but when I copy paste png files into this software, the alpha channel seems to be preserved.
Under this consideration, I want to simulate the Ctrl+C on files allowed by Windows Explorer. Using Clipview I found that the field 15 : CF_HDROP is relevant to my goal. tried to set this field using win32clipboard
import win32clipboard
win32clipboard.OpenClipboard(0)
file1="C:\\Users\\User\\Desktop\\test.png"
win32clipboard.SetClipboardData(15, file1)
win32clipboard.CloseClipboard()
I don't get any error doing this, but it does not work when I try to use this new clipboard content, because as described there tuple of unicode filenames must be stored in the CF_HDROP field.
I have no clue how to proceed. I also tried with
file1= (unicode('C:\\Users\\User\\Desktop\\CANEVAS\\test.png'),)
but I got this error:
TypeError: expected a readable buffer object.
The documentation for CF_HDROP says
The data consists of an STGMEDIUM structure that contains a global memory object. The structure's hGlobal member points to a DROPFILES structure as its hGlobal member.
win32clipboard.GetClipboardData has built-in support for CF_HDROP. It decodes the STGMEDIUM and DROPFILES structures to produce a tuple of file names.
The documentation does not state that SetClipboardData has the corresponding code to construct the STGMEDIUM and DROPFILES structures from a tuple of file names.
I don't know enough about Python or its FFI to know how straightforward it is to construct the structures and pass them to the SetClipboardData function. Or if there is an existing library that will do this for you.
Why isn't the code below working? The email is received, and the file comes through with the correct filename (it's a .png file). But when I try to open the file, it doesn't open correctly (Windows Gallery reports that it can't open this photo or video and that the file may be unsupported, damaged or corrupted).
When I download the file using a subclass of blobstore_handlers.BlobstoreDownloadHandler (basically the exact handler from the GAE docs), and the same blob key, everything works fine and Windows reads the image.
One more bit of info - the binary files from the download and the email appear very similar, but have a slightly different length.
Anyone got any ideas on how I can get email attachments sending from GAE blobstore? There are similar questions on S/O, suggesting other people have had this issue, but there don't appear to be any conclusions.
from google.appengine.api import mail
from google.appengine.ext import blobstore
def send_forum_post_notification():
blob_reader = blobstore.BlobReader('my_blobstore_key')
blob_info = blobstore.BlobInfo.get('my_blobstore_key')
value = blob_reader.read()
mail.send_mail(
sender='my.email#address.com',
to='my.email#address.com',
subject='this is the subject',
body='hi',
reply_to='my.email#address.com',
attachments=[(blob_info.filename, value)]
)
send_forum_post_notification()
I do not understand why you use a tuple for the attachment. I use :
message = mail.EmailMessage(sender = ......
message.attachments = [blob_info.filename,blob_reader.read()]
I found that this code doesn't work on dev_appserver but does work when pushed to production.
I ran into a similar problem using the blobstore on a Python Google App Engine application. My application handles PDF files instead of images, but I was also seeing a "the file may be unsupported, damaged or corrupted" error using code similar to your code shown above.
Try approaching the problem this way: Call open() on the BlobInfo object before reading the binary stream. Replace this line:
value = blob_reader.read()
... with these two lines:
bstream = blob_info.open()
value = bstream.read()
Then you can remove this line, too:
blob_reader = blobstore.BlobReader('my_blobstore_key')
... since bstream above will be of type BlobReader.
Relevant documentation from Google is located here:
https://cloud.google.com/appengine/docs/python/blobstore/blobinfoclass#BlobInfo_filename
I'm using the Google App Engine Blobstore to store a range of file types (PDF, XLS, etc) and am trying to find a mechanism by which the original filename of the uploaded file - as stored in blob_info - can be used to name the downloaded file i.e. so that the user sees 'some_file.pdf' in the save dialogue rather than 'very_long_db_key.pdf'.
I can't see anything in the docs that would allow this:
http://code.google.com/appengine/docs/python/blobstore/overview.html
I've seen hints in other posts that you could use the information in blob_info to set the content-disposition header. Is this the best approach to achieving the desired end?
There is an optional 'save_as' parameter in the send_blob function. By default this is set to False. Setting it to True will cause the file to be treated as an attachment (ie it will trigger a 'Save/Open' download dialog) and the user will see the proper filename.
Example:
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, resource):
resource = str(urllib.unquote(resource))
blob_info = blobstore.BlobInfo.get(resource)
self.send_blob(blob_info,save_as=True)
It is also possible to overwrite the filename by passing in a string:
self.send_blob(blob_info,save_as='my_file.txt')
If you want some content (such as pdfs) to open rather than save you could use the content_type to determine the behavior:
blob_info = blobstore.BlobInfo.get(resource)
type = blob_info.content_type
if type == 'application/pdf':
self.response.headers['Content-Type'] = type
self.send_blob(blob_info,save_as=False)
else:
self.send_blob(blob_info,save_as=True)
For future reference, save_as and the BlobstoreDownloadHandler is documented here:
http://code.google.com/appengine/docs/python/tools/webapp/blobstorehandlers.html
It does seem like it should be a bit easier to find. Let's see if it can be improved.
Another option is to append the file name to the end of the download URL. For example:
/files/AMIfv95HJJY3F75v3lz2EeyvWIvGKxEcDagKtyDSgQSPWiMnE0C2iYTUxLZlFHs2XxnV_j1jdWmmKbSVwBj6lYT0-G_w5wENIdPKDULHqa8Q3E_uyeY1gFu02Iiw9xm523Rxk3LJnqHf9n8209t4sPEHhwVOKdDF2A/prezents-list.doc
If you use Jinja2 for templating, you can construct such an URL like this:
{{file.filename}}
then you should adapt your URL mapping accordingly to something like this:
('/files/([^/]+)/?.*', DownloadHandler)
If you have the blob key in the URL, you can ignore the file name in your server-side code.
The benefit of this approach is that content types like images or PDF open directly in the browser, which is convenient for quick viewing. Other content types will just be saved to disk.
Yes it is the best approach; just query the BlobInfo object using the given Blobstore key and use its content-type property.