upload image using image Path in flask - python

I want to upload an image file to imgur using the python-Flask. So for this I am submitting an image file from the form and want to upload this file to imgur.
But the point is the example snippets given in the imgur api want the path name of the file that was uploaded. So far I was trying to upload but I am stuck!!
This is my main.py file
if request.method == "POST":
image = request.files.get('myfile') #myfile is name of input tag
config ={
'album':album,
'name':'Catastrophe!',
'title':'Catastrophe!'
}
print os.path.realpath(image.filename) # this line gives me wrong path of file.
print "uploading image..."
#image = client.upload_from_path(filepath,config=config,anon=False)
The commented print statement gives me path like this
/home/suraj/Desktop/FlaskTrials/wallpaper.jpg
But the thing is the correct file path could be anything the user wants to choose image from
How do I get this path. Am I doing the right thing to upload the image to imgur api ?
I would be able to do by making an dir in root folder and adding image to it and then get the filename of that and upload to imgur.
But I was wandering is it possible without saving and image file.
Thanks in advance

It looks to me like you forgot to save the file on the server. Here is a modified version of your code based on http://flask.pocoo.org/docs/0.10/patterns/fileuploads/.
if request.method == "POST":
image = request.files['myfile'] #myfile is name of input tag
config ={
'album':album,
'name':'Catastrophe!',
'title':'Catastrophe!'
}
print "uploading image..."
filename = secure_filename(image.filename)
file.save(os.path.join('/home/suraj/Pictures', filename))
print os.path.realpath(image.filename)
I recommend considering restricting the file names to certain extensions, as suggested by the Flask doc.

Related

How to Publish Docx file with images to WordPress site?

So I am able to post Docx files to WordPress using WP REST-API using mammoth docx package in Python
I am able to upload an image to WordPress.
But when there are images in the docx file they are not uploading on the WordPress media section.
Any input on this?
I am using python for this.
Here is the code for Docx to HTML conversion
with open(file_path, "rb") as docx_file:
# html = mammoth.extract_raw_text(docx_file)
result = mammoth.convert_to_html(docx_file, convert_image=mammoth.images.img_element(convert_image))
html = result.value # The generated HTML
kindly do note that I am able to see images in the actual published post but they have a weird source image URL & are not appearing in the WordPress media section.
Weird image source URL like
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQECAgMCAgICAgQDAwIDBQQFBQUEBAQFBgcGBQUHBgQEBgkGBwgICAgIBQYJCgkICgcICAj/2wBDAQEBAQICAgQCAgQIBQQFCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAj/wAARCAUABQADASIAAhEBAxEB/8QAHwAAAQMFAQEBAAAAAAAAAAAAAAUGBwMECAkKAgsB/8QAhxAAAQIEBAMEBQYHCAUOFggXAQIDAAQFEQYHEiETMUEIIlFhCRQ & so on
Also Huge thanks to Contributors for the Python to WordPress repo
The mammoth cli has a function that extracts images, saves them to a directory and inserts the file names in the img tags in the html code. If you don't want to use mammoth in command line you could use this code:
import os
from mammoth.cli import ImageWriter, _write_output
output_dir = './output'
filename = 'filename.docx'
with open(filename, "rb") as docx_fileobj:
convert_image = mammoth.images.img_element(ImageWriter(output_dir))
output_filename = "{0}.html".format(os.path.basename(filename).rpartition(".")[0])
output_path = os.path.join(output_dir, output_filename)
result = mammoth.convert(
docx_fileobj,
convert_image=convert_image,
output_format='html',
)
_write_output(output_path, result.value)
Note that you would still need to change the img links as you'll be uploading the images to Wordpress, but this solves your mapping issue. You might also want to change the ImageWriter class to save the images to something else than tiff.

step to save image file to server using django api

I am new in python and django, right now I would like to upload an image from postman (content type: form-data) and then save it in server. So far I have doing this
#csrf_exempt
def detector(request):
data = {"success": False}
if request.method == "POST":
print("oke0")
# check to see if an image was uploaded
if request.FILES.get("image", None) is not None:
...# here I would like to save the image
else:
return JsonResponse(data)
return JsonResponse(data)
so the flow is: upload image from postman and then directory 'media' will be created and the image will be stored there
so far I have been following this https://www.geeksforgeeks.org/python-uploading-images-in-django/ but I don't know how to try it in postman, anyone knows step by step to save image file to server in django?
Here is the code, but keep in mind that I didn't test it, since I wrote it on the fly.
I also assume you use Python3.2+, since you won't be able to use os.makedirs with exist_ok flag.
If you're using Python3.5+, you can also replace that code with something like Pathlib which can create folder, but won't raise an exception like so:
import pathlib
pathlib.Path('save_path').mkdir(parents=True, exist_ok=True)
and you can replace the os.makedirs in the code bellow with this call in that case.
import os
import uuid
#csrf_exempt
def detector(request):
data = {"success": False}
if request.method == "POST":
print("oke0")
if request.FILES.get("image", None) is not None:
#So this would be the logic
img = request.FILES["image"]
img_extension = os.path.splitext(img.name)[1]
# This will generate random folder for saving your image using UUID
save_path = "static/" + str(uuid.uuid4())
if not os.path.exists(save_path):
# This will ensure that the path is created properly and will raise exception if the directory already exists
os.makedirs(os.path.dirname(save_path), exist_ok=True)
# Create image save path with title
img_save_path = "%s/%s%s" % (save_path, "image", img_extension)
with open(img_save_path, "wb+") as f:
for chunk in img.chunks():
f.write(chunk)
data = {"success": True}
else:
return JsonResponse(data)
return JsonResponse(data)
Now, that's an easy part.
For Postman, simply follow this answer -> https://stackoverflow.com/a/49210637/1737811
Hope this answers your question.

Static files are still being served from file system instead of AWS-S3 in Flask

I have a script that generates an image.
That image is saved in a directory inside my OS static folder. image.png is saved in:
-static
-images
-monkeys
- image.png
The server endpoint function should upload the image into my S3-bucket and return that static file from my bucket, not from my OS file system.
This does not work for some reason.
The image uploading works fine, I can see the image in the bucket, I'm just not able to serve the static image, I get an error:
"The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.". Basically it cannot find the image.
I am using flask-S3 in the following way:
app = Flask(__name__)
app.config['FLASKS3_BUCKET_NAME'] = os.environ.get('S3_BUCKET_NAMEING')
app.config['USE_S3_DEBUG'] = True
s3 = FlaskS3(app)
My endpoint for serving the static image:
#app.route('/image/monkey/<address>', methods = ['GET'])
def monkey_image(address):
# There is some code here that generates that image and places it
# inside the monkeys folder. I did not include it because
# it is not relevant to the question
image = open(image_path, 'rb')
S3_path = 'images/monkeysS3/' + monkey_image_name
upload_image_to_s3_bucket(image,'static/' + S3_path)
return redirect(flask_url_for('static', filename=S3_path))
So the last 2 lines matters.
upload_image_to_s3 works. The issue comes from
return redirect(flask_url_for('static', filename=path)).
It just can't find the image inside my S3 bucket.
This goes for development and production as well.
Thanks

In Django, how do I get a file path for an uploaded file when uploading?

I am trying to add some validation for user uploaded files. This requires running through a custom script I made called "sumpin", which only takes a filepath as a variable and sends back JSON data that will verify. Everything inside my script is working independently, putting it together where the error occurs.
Since this is file validation, I decided to expand my file_extension validator that was already working.
models.py
from allauthdemo.fileuploadapp.slic3rcheck import sumpin
def user_directory_path_files(instance, filename):
return os.path.join('uploads', str(instance.objectid), filename)
def validate_file_extension(value):
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.stl','.STL']
if not ext in valid_extensions:
raise ValidationError(u'Please upload a .stl file type only')
data = sumpin(value.path)
print (data)
class subfiles(models.Model):
STL = models.FileField(_('STL Upload'),
upload_to=user_directory_path_files, validators=[validate_file_extension])
The error that I get is that the path (value.path) is not valid.
This is the incorrect path because the upload_to tag must change this at a later point. This may be obvious, but I also need to have the file at the filepath location when my script is called. So essentially my questions are...
How can pass the "upload_to" path into my validator to run through my custom script?
Is there a better method to deal with uploaded files, like in the main class with a "save" or "clean" function?
I've found my own answer, but I'll post it here in case someone runs across this issue in the future.
I was incorrect, a validator wouldn't actually download the file. I need to use a file upload handler, which is shown below.
import os
from django.core.files.storage import default_storage
from allauthdemo.fileuploadapp.slic3rcheck import sumpin
def handle_uploaded_file(f):
with open(default_storage.path('tmp/'+f.name), 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
data = sumpin(default_storage.path('tmp/'+f.name))
os.remove(default_storage.path('tmp/'+f.name))
return data
then I call this inside my views.py.
from allauthdemo.fileuploadapp.uploadhandler import handle_uploaded_file
#login_required
def STLupload(request):
# Handle file upload
if request.method == 'POST':
formA = ObjectUp(request.POST, request.FILES)
if formA is_valid():
data = handle_uploaded_file(request.FILES['STL'])
This will return whatever I called to return within handle_upload_file, which worked perfect for my issues. Hopefully someone will find this useful the future.

Flask-strange routing issue

So I am trying to test out serving some user uploaded files in Flask. For images I am simply renaming them with a shortened UUID and putting them in a folder, but for other file types I would like to retain the original filename, so I devised the convoluted method of saving each file in a subfolder named with a UUID. Everything works fine, both the images and files upload and are in the directories they should be in. Just to test I made a template for a download page to just display the filename(planned to implement a download button later). However, when I plug the generated URL in for an uploaded file, I get a 404, and the function that url is supposed to be bound to doesn't even appear to execute(I had it print the filename in console and it doesnt even print), and in console the url is displayed: "GET /xVgePgj2Y HTTP/1.1" 404 -
My code for uploading the files and making the URL:
else:
new_folder_name = shortuuid.uuid()[:9]
os.mkdir(os.path.join(app.config['FILE_FOLDER'], new_folder_name))
file.save(os.path.join(os.path.join(app.config['FILE_FOLDER'], new_folder_name), filename))
new_folder_path = os.path.join(app.config['FILE_FOLDER'], new_folder_name)
return url_for('uploaded_file', new_folder_name=new_folder_name)
My code for serving the files:
#app.route('/<new_folder_name>', methods=['GET'])
def uploaded_file(new_folder_name):
filename = subfolder_fetch(new_folder_name)
return render_template("download.html", filename=filename)
and finally my code for fetching the filename from the subdirectory (called in the serving function - didn't pass the filename to the url_for function because that would make it ugly and complicated):
def subfolder_fetch(new_folder_name):
stuff = os.listdir(os.path.join(app.config['FILE_FOLDER'], new_folder_name))
for name in folder:
print (name)
return name
I'm puzzled as to what is even going on and why my uploaded_file function isn't even being called.
Thanks in advance.

Categories