In this episode, we’ll learn how to dynamically retrieve and display images from Cloudinary in a FastHTML app. By the end of this tutorial, you’ll be able to create a simple image gallery that fetches images from your Cloudinary account and displays them on your webpage.
Part 1: Understanding Cloudinary Image Retrieval
Overview of Cloudinary’s Media Management
Cloudinary allows you to store and manage images and other media files. To display these images in your FastHTML app, you need to retrieve them using Cloudinary’s API.
Key Concepts for Image Retrieval:
- Public IDs: Unique identifiers for each image in your Cloudinary account. Used to fetch and manipulate images.
- Transformation URLs: Cloudinary URLs that include transformation parameters to dynamically adjust image properties like size, format, and effects.
Part 2: Setting Up Cloudinary for Image Retrieval
Step 1: List Your Cloudinary Images
To list all images in your Cloudinary account, you need to use the Cloudinary Admin API. Update your config.py
file to include the following function:
# config.py
import cloudinary
import cloudinary.uploader
import cloudinary.api
cloudinary.config(
cloud_name='your_cloud_name',
api_key='your_api_key',
api_secret='your_api_secret'
)
def list_images():
response = cloudinary.api.resources(type='upload', max_results=10)
return response.get('resources', [])
Explanation of Code:
- cloudinary.api.resources: Calls the Cloudinary API to list uploaded images.
- type=’upload’: Specifies that we are listing uploaded resources.
- max_results=10: Limits the number of images returned (you can adjust this number).
Step 2: Create a Route to Display Images in FastHTML
Update your main.py
file to create a route for displaying images:
# main.py
from fasthtml.common import *
import config # Import Cloudinary configuration and functions
app, rt = fast_app()
@rt('/')
def get():
# Retrieve images from Cloudinary
images = config.list_images()
image_elements = [Img(src=img['secure_url'], alt=img['public_id'], cls='gallery-image') for img in images]
return Div(
H1('Image Gallery'),
Div(*image_elements, cls='gallery'),
Style('''
.gallery { display: flex; flex-wrap: wrap; }
.gallery-image { margin: 10px; width: 200px; height: auto; }
''')
)
serve()
Explanation of Code:
- config.list_images(): Calls the function to retrieve a list of images from Cloudinary.
- image_elements: Uses a list comprehension to create
<img>
elements for each image returned by Cloudinary. - Div(*image_elements, cls=’gallery’): Wraps all image elements in a parent
<div>
with a CSS class for styling. - Style(…): Adds some basic CSS to style the gallery.
Part 3: Styling and Enhancing the Gallery
Step 1: Adding CSS for Better Styling
You can enhance the visual appearance of your image gallery by adding more CSS styles. Update the Style
block in main.py
:
Style('''
.gallery {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
padding: 10px;
}
.gallery-image {
margin: 10px;
width: 200px;
height: auto;
border: 2px solid #ccc;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.2s ease;
}
.gallery-image:hover {
transform: scale(1.05);
border-color: #444;
}
''')
Explanation of CSS:
.gallery
: Sets up a flex container to arrange images in a responsive layout..gallery-image
: Styles each image with margins, a border, rounded corners, and a subtle shadow..gallery-image:hover
: Adds a hover effect to slightly enlarge and change the border color of the image.
Step 2: Adding a Lightbox Feature (Optional Advanced Enhancement)
A lightbox allows users to click on an image and view it in a larger, overlay view. For simplicity, we’ll use a basic HTML/CSS/JavaScript approach.
Update the HTML and JavaScript in main.py
:
@rt('/')
def get():
images = config.list_images()
image_elements = [Img(src=img['secure_url'], alt=img['public_id'], cls='gallery-image', onclick=f"openLightbox('{img['secure_url']}')") for img in images]
return Div(
H1('Image Gallery'),
Div(*image_elements, cls='gallery'),
Div(
Div(Img(id='lightbox-img', cls='lightbox-image')),
Div('×', cls='lightbox-close', onclick="closeLightbox()"),
cls='lightbox', id='lightbox'
),
Style('''
/* (existing styles) */
.lightbox {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
justify-content: center;
align-items: center;
z-index: 1000;
}
.lightbox-image {
max-width: 90%;
max-height: 80%;
}
.lightbox-close {
position: absolute;
top: 20px;
right: 20px;
font-size: 2rem;
color: #fff;
cursor: pointer;
}
'''),
Script('''
function openLightbox(imageUrl) {
document.getElementById('lightbox-img').src = imageUrl;
document.getElementById('lightbox').style.display = 'flex';
}
function closeLightbox() {
document.getElementById('lightbox').style.display = 'none';
}
''')
)
Explanation of Code:
- onclick attribute: Adds a JavaScript function call to each image to open the lightbox when clicked.
openLightbox
function: Sets the image source for the lightbox and displays the lightbox overlay.closeLightbox
function: Hides the lightbox overlay.
Part 4: Running and Testing Your Gallery
- Run Your Application:
Start your FastHTML application again:
python main.py
- Test the Gallery:
Visithttp://localhost:5001
to see your image gallery. Click on images to test the lightbox feature.
Conclusion
In this episode, you learned how to retrieve images from Cloudinary and display them dynamically in your FastHTML app. You also enhanced the gallery with CSS for better styling and added a lightbox feature for an improved user experience.
Homework/Assignment:
- Experiment with different image transformations using Cloudinary’s URL-based transformations.
- Add a filter or search functionality to display images based on tags or categories.
In the next episode, we’ll explore how to enhance media management with advanced Cloudinary features like image transformations, video support, and more!