I have made a loop of image urls through python and now I want to display all the images on html page using all the image urls,i am using jinja for loop.
what am I doing wrong here , need some help
import boto3
session = boto3.Session(
aws_access_key_id='my_key',
aws_secret_access_key='My_key')
s3 = session.client('s3')
objects = s3.list_objects_v2(Bucket='My_bucket')
for obj in objects['Contents']:
print("\n")
print(obj['Key'])
print("\n")
url = s3.generate_presigned_url(ClientMethod='get_object',Params={'Bucket': "My_bucket", 'Key': obj['Key'], },ExpiresIn=36000,)
print(url)
f = open('index.html','w')
message = """<!DOCTYPE html>
<html>
<head>
<title>sahil</title>
</head>
<body>
<table>
<tr>
<td>
<ul>
{% for urls in url %}
<li>{{ <img src="urls"> }}</li>
{% endfor %}
</ul>
</td>
</tr>
</table>
</body>
</html>"""
f.write(message)
f.close()
CodePudding user response:
I don't code with Python yet it seems like you continuously overwrite url
value to new string instead of creating an array to loop on and then later you try to loop over single last url string. Debug url value before using it in template to actually see what you are looping on
CodePudding user response:
There are two main issues with your code:
At no point are you rendering the Jinja template. This means that the message
variable is being written to the file as is, Jinja instructions and all. On top of that, since you're not actually saving each URL you generate in the Python loop, if you did render this template, it would operate on each character of the final URL you generate, which is less than useful. Well, that is if you fixed the bug in the template, since it was attempting to execute some HTML.
There are comments in this example on other minor issues. That said, the inclusion of AWS secrets in code is not a minor issue. Do not do that. It is a surprisingly common reason AWS secrets leak into the wild. You really should get out of that habit now, before it causes you problems.
import boto3
# Bring in the Template enging from Jinja
from jinja2 import Template
# NEVER store AWS secrets in code. Use one of the options available at
# https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html
session = boto3.Session()
s3 = session.client('s3')
# Create a pagination helper to get all objects if there are more than 1000
paginator = s3.get_paginator('list_objects')
# Store the generated URLs in an array
urls = []
for objects in paginator.paginate(Bucket='My_bucket'):
# Pull out the Contents for this page, it may not be present, so default to
# an empty list if this page has no items
for obj in objects.get('Contents', []):
# Note: Prevent problems by using the bucket name from the list_objects request
url = s3.generate_presigned_url(ClientMethod='get_object',Params={'Bucket': objects['Name'], 'Key': obj['Key'], },ExpiresIn=36000,)
# Add the new URL to the list of URLs
urls.append(url)
# Use with block to let Python manage the lifespan of the file object
with open('index.html','w') as f:
# Note: Compacting the HTML here just to make the example smaller
message = """<!DOCTYPE html>
<html><head><title>sahil</title></head>
<body><table><tr><td><ul>
{% for url in urls %}
<!-- The jinja portion here is just the "url" variable, the rest is raw HTML -->
<li> <img src="{{url}}"> </li>
{% endfor %}
</ul></td></tr></table></body></html>"""
# Need to actually call jinja to render the HTML
t = Template(message)
# Pass in the urls list to the render engine
f.write(t.render(urls=urls))