Testing blobstore image post - python-2.7

I'm testing a post request which contains an image, after the post request if succesfull i receive a url like
http://testbed.example.com/_ah/upload/agx0ZXN0YmVkLXRlc3RyGwsSFV9fQmxvYlVwbG9hZFNlc3Npb25fXxgDDA
as i already tried and checked in stackoverflow, this wont work to try to upload the image
i have a handler in a route like "/upload/image"
and the code looks like:
class UploadScreenshot(webapp2.RequestHandler, blobstore_handlers.BlobstoreUploadHandler):
def post(self):
try:
upload_screenshot = self.get_uploads('file')
upload_url = self.request.get('upload_url')
fbkey = self.request.get('fbkey')
screenshotKey = upload_screenshot[0].key()
feedback = N.FeedbackModel.query(N.FeedbackModel.fbkey == fbkey)
feedback.screenshotBlobID = screenshotKey
feedback.put()
except:
self.error(400)
what could i do to upload to the Blobstore, i have my app in appspot also but i wanna test this before deploying
thanks

Sounds like you got things a bit backwards. By the time your UploadScreenshot handler is called the blob should be already uploaded and your handler can access it using the blob key (which you have in screenshotKey). You can't (re)use the upload url at this point (it should have been already used when the user submited the upload form).
You may want to revisit the blob upload procedure/example.
BTW, this can be fully tested on the development server, the upload URL you get will be a localhost one and the blob is stored on localhost as well.

Related

I don't want users to access a django url path but I still want my home page to use the path

To be more precise I have the following
path('',views.home,name='home'),
path('json', json, name="json"),
my home page calls the json file to plot a chart, however if user types in the url '.../json' they can access the json data file. I want users to not have access to the path /json but I still want my home page to access this json path.
Thanks
This is not quite possible because when your homepage is loaded by a user, the page tells them to request the json data from your server. The browser sees will make a request for the data, and there is almost no difference between the user going to http://yoursite.com and the browser making a call to http://yoursite.com/json.
One way you could try if the data is only loaded once is to append a single-use token to homepage (which is different for every request) and allow the browser to use this to allow the request.
def home(request):
# do everything
context['token'] = generate_token()
session['json_token'] = context['token']
return render()
def json(request):
if request.GET.get('token', '') == session['json_token']:
del session['json_token']
# generate_data
return data
return HttpResponse(status_code=405)

uploaded image from next.js to django to store in aws s3 is blank

I set up functionality for s3, I can easily upload images from Django admin interface. I have "createProduct" page and I want to create a product by sending form data from next.js. Django stores the URL s3 bucket in DB and retrieves the image from s3 when needed.
I set view image and cropping it functionality and it works as well. For this I have a separate component:
<div className="form-group">
<label htmlFor="image">Image</label>
<FileLoader
onFileUpload={image => setValue('image', image._id)}
/>
</div>
I need to create an endpoint. Admin, first uploads the image, image gets saved to s3, then admin gets the url of the image, and passes it to the form data, so form data will be sent to the createProduct endpoint.
#api_view(['POST'])
#permission_classes([IsAdminUser])
def createProduct(request):
user=request.user
print("user in post",user)
print("request.data",request.data)
name=request.data['name']
price=request.data['price']
brand=request.data['brand']
countInStock=request.data['countInStock']
category=request.data['category']
description=request.data['description']
// Here i need to send the imag url I guess
image=request.FILES.get('image')
print("image",image)
product=Product.objects.create(user=user, name=name,
price=price,brand=brand,
countInStock=countInStock,category=category,description=description, image=image)
product.save()
serializer=ProductSerializer(product, many=False)
return Response(serializer.data)
this is the endpoint for s3 upload:
#api_view(['POST'])
def upload(request):
data=request.data
print("image data sent",data)
client=boto3.client("s3",
aws_access_key_id=os.environ.get('AWS_ACCESS_KEY_ID'),
aws_secret_access_key=os.environ.get('AWS_SECRET_ACCESS_KEY'),
# s3 does not need region
# region_name=os.environ.get(AWS_REGION_NAME),
)
response = client.upload_fileobj(data,"bingology-bucket","testing",{'ContentType': "image/jpeg"}
I get successfully uploaded message, image is in the bucket but it does show only black background and "type" is "-".
I also tried to get presigned-url, i got the url but it did not save anyting so s3. and I could not view the url when I visit due to permission issue even thought bucket is public
I think we need another endpoint, with the logic to handle the upload using this architecture:
uploadImage (name for this another endpoint) receive image metadata from the next js.
uploadImage generates a pre-signed Url (since you are using S3), return this URL to nextjs and nextjs perform a upload using this presigned url and invoke the createProduct endpoint passing the URL (uploadImage can filter to return the exact URL of object) and all the product data to store in DB.
This approach can be better using a SAGA pattern to orchestrate things, because since you need to handle with 2 differently process (s3 upload and db transaction), you can orchastrate this things, or use transactions in a monolitic architeture (all business logic in one deployment).
Few tips:
Using SAGA pattern in this case, you just need to instrument a job to delete the image if has an error in createProduct. You can implement this by using a logic in the front end to put a message on an SNS with an lambda expression to read from this and delete the image in S3, since the product are not saved correctly.
Documentation:
https://microservices.io/patterns/data/saga.html
https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html

a web server developed by python, how to transfer a image file, and can show in a web browser?

I want to develop a simple web server using python to handle some simple http request. I have learn how to response the request, such as transferring html pages or transferring some other file. When I transfer a image file, a client use a browser to get the file, the url is like below:
http://114.212.82.104:8080/1.png
I set 'Content-Type = application/x-png'. But the browser directly download the file, and can not display in the browser. Not like the image below
https://www.baidu.com/img/bd_logo1.png
it can display in the browser. How to display the image in the browser?
Can someone help me?
and i know i can encode the image file into html page to fix it. code like below:
class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
path = os.getcwd()+ self.path
if os.path.isfile(path):
with open(path,'rb') as fileTrans:
content = fileTrans.read().encode('base64').replace('\n','')
#self.sendContent(200, content)
self.send_response(200)
page = "<p>\"fef\"</p><img src=\"data:image/jpg;base64,{0}\"/>"
contentPage = page.format(content)
self.send_header('Content-Type', 'text/html')
self.send_header("Content-Length", str(len(contentPage)))
self.end_headers()
self.wfile.write(contentPage)
else:
self.sendContent(404,"file do not exists")
But I know there must be another way, i see the source code of URL(https://www.baidu.com/)
it just use
<img hidefocus="true" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129"></div><a href="/" id="result_logo" onmousedown="return c({'fm':'tab','tab':'logo'})">
different from my page:
<p>"fef"</p><img src="data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAcIAAAJYCAIAAAB+b3GqAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAvppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODg3NkM1Njg1MzVFMTFFNkE0NkJFNTEzMUFCNzc4RTMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODg3NkM1Njc1MzVFMTFFNkE0NkJFNTEzMUFCNzc4RTMiIHhtcDpDcmVhdG9yVG9vbD0iOC4xLjMiPiA8eG1wTU06RG......
OK,I think I have solved this problem.
Just set the attribute - 'Content-Type' of header as 'image/png' instead of 'application/x-png'.

Django Rest Framework Not Returning Full JSON

I am having trouble retrieving the full JSON Response when executing a GET request on an API I am building with DRF. If I include pagination and retrieve, say, 100 results then I receive the full JSON Response. If I do not use pagination, and would like to retrieve a few thousand results, then the server simply cuts off at a seemingly random spot and does not return full JSON. For instance, it may return {"hi": "hel instead of returning {"hi":"hello"}. DRF reports this as a 200 response code, so it seems as though it executes properly.
The code for my view looks like:
class RepresentativeListView(generics.ListAPIView):
queryset = models.Representative.objects.all()
serializer_class = serializers.RepresentativeSerializer
The code for my serializer looks like:
class RepresentativeSerializer(serializers.ModelSerializer):
class Meta:
model = models.Representative
fields = (
'bioguide_id',
'stats',
'leadership_score',
'ideology_score',
)
Could anyone understand why a full JSON response would not be coming through?
This might be an issue with your Apache / Nginx / whatever you use web server.
It may close the connection if the application didn't respond on time.
Check your web server logs and the time it takes for the application to render the response vs the server timeout.

How can I send a request to a view from an admin command without hard coding the url

I am trying to create an admin command that will simulate some api calls associated with a view but I don't want to hard code the url, for example like that url='http://127.0.0.1:8000/api/viewname', in order to send the request.
If I use the reverse option I can obtain half the url /api/viewname.
If I try to post the request that way
url = reverse('name-of-view')
requests.post(url, data=some_data)
I get
requests.exceptions.MissingSchema: Invalid URL '/api/viewname/': No schema supplied. Perhaps you meant http:///api/viewname/?
Do I have to look whether the server is running on the localhost or is there a more generic way?
requests module needs the absolute url to post to. you need
url = 'http://%s%s' % (request.META['HTTP_HOST'], reverse('name-of-view'))
requests.post(url, data=some_data)