In this episode, we’ll explore how to enhance media management in your FastHTML app using advanced features of Cloudinary. You’ll learn how to apply image transformations, support video uploads, and implement tagging and search functionalities to manage your media effectively.

Part 1: Advanced Image Transformations with Cloudinary

Overview of Image Transformations:

Cloudinary provides powerful tools for transforming images directly via URL parameters. These transformations can optimize images for different devices, apply filters, resize, crop, and more, all dynamically without needing to store multiple versions of an image.

Step 1: Understanding Transformation URLs

Transformations in Cloudinary are applied by adding specific parameters to the URL of the image. For example, adding w_300,h_300,c_fill will resize an image to 300×300 pixels and crop it to fill the dimensions.

Step 2: Applying Transformations in FastHTML

To use these transformations in your FastHTML app, modify your image gallery to include transformation parameters:

# main.py
from fasthtml.common import *
import config  # Import Cloudinary configuration and functions

app, rt = fast_app()

@rt('/')
def get():
    images = config.list_images()
    image_elements = [
        Img(
            src=f"https://res.cloudinary.com/{config.cloudinary.config().cloud_name}/image/upload/w_300,h_300,c_fill/{img['public_id']}.jpg",
            alt=img['public_id'],
            cls='gallery-image',
            onclick=f"openLightbox('https://res.cloudinary.com/{config.cloudinary.config().cloud_name}/image/upload/{img['public_id']}.jpg')"
        ) for img in images
    ]

    return Div(
        H1('Enhanced Image Gallery'),
        Div(*image_elements, cls='gallery'),
        Style('''
            /* Add styles here */
        '''),
        Script('''
            /* Add script here */
        ''')
    )

serve()

Explanation of Code:

  • f"https://res.cloudinary.com/{config.cloudinary.config().cloud_name}/image/upload/w_300,h_300,c_fill/{img['public_id']}.jpg": Constructs the URL with transformation parameters to resize and crop images dynamically.
  • onclick attribute: Still uses the original image for the lightbox, which displays a larger version without transformation.

Step 3: Experiment with Different Transformations

Try different transformations like adding filters (e.g., e_sepia for a sepia effect) or changing the image quality (q_auto for automatic quality adjustment). Update your main.py to see these changes.

Part 2: Adding Video Support to Your FastHTML App

Overview of Video Management in Cloudinary:

Cloudinary supports video uploads and transformations similar to images. You can upload videos, apply transformations, and deliver them efficiently.

Step 1: Update Upload Function for Video Support

Modify your upload function in main.py to handle video uploads:

@rt('/upload', methods=['POST'])
def upload(request):
    try:
        file = request.files['file']
        if not file:
            return Div(P('No file selected! Please choose a file to upload.'))

        # Check file type for image or video
        if file.content_type not in ['image/jpeg', 'image/png', 'image/gif', 'video/mp4', 'video/avi']:
            return Div(P('Invalid file type! Please upload an image or video (JPEG, PNG, GIF, MP4, AVI).'))

        # Upload file to Cloudinary
        response = cloudinary.uploader.upload(file.file, resource_type="auto")
        file_url = response['secure_url']
        return Div(
            P('File uploaded successfully!'),
            A(file_url, 'View your file here', href=file_url, target='_blank')
        )
    except Exception as e:
        return Div(P('An error occurred during upload: ' + str(e)))

Explanation of Code:

  • resource_type="auto": Automatically detects and handles the file type (image or video).
  • Support for Video File Types: Checks for both image and video file types to ensure only supported formats are uploaded.

Step 2: Display Videos in Your Gallery

Update your gallery to display videos alongside images:

@rt('/')
def get():
    resources = config.list_images()  # Use list_images or a modified function to list both images and videos
    elements = []
    for res in resources:
        if res['resource_type'] == 'image':
            elements.append(
                Img(
                    src=f"https://res.cloudinary.com/{config.cloudinary.config().cloud_name}/image/upload/w_300,h_300,c_fill/{res['public_id']}.jpg",
                    alt=res['public_id'],
                    cls='gallery-image'
                )
            )
        elif res['resource_type'] == 'video':
            elements.append(
                Video(
                    Src=f"https://res.cloudinary.com/{config.cloudinary.config().cloud_name}/video/upload/w_300,h_300,c_fill/{res['public_id']}.mp4",
                    controls=True,
                    cls='gallery-video'
                )
            )

    return Div(
        H1('Enhanced Media Gallery'),
        Div(*elements, cls='gallery'),
        Style('''
            /* Add styles here */
        ''')
    )

Explanation of Code:

  • Video(...): Adds video elements to the gallery with appropriate transformation URLs.
  • Conditional Logic: Checks if the resource type is an image or video to display accordingly.

Part 3: Implementing Tagging and Search Functionality

Overview of Tagging and Search:

Tagging allows you to categorize your media, making it easier to manage and retrieve specific files. Cloudinary supports tagging and searching media based on these tags.

Step 1: Tagging Images and Videos on Upload

Modify the upload function to add tags:

@rt('/upload', methods=['POST'])
def upload(request):
    try:
        file = request.files['file']
        tags = request.form.get('tags', '')

        response = cloudinary.uploader.upload(file.file, resource_type="auto", tags=tags.split(','))
        file_url = response['secure_url']
        return Div(
            P('File uploaded successfully!'),
            A(file_url, 'View your file here', href=file_url, target='_blank')
        )
    except Exception as e:
        return Div(P('An error occurred during upload: ' + str(e)))

Explanation of Code:

  • tags=tags.split(','): Takes tags from the form and splits them into a list for Cloudinary.

Step 2: Implement Search by Tag Functionality

Create a new route in main.py to search images by tags:

@rt('/search', methods=['GET'])
def search(request):
    tag = request.query.get('tag', '')
    if not tag:
        return Div(P('Please enter a tag to search.'))

    resources = cloudinary.api.resources_by_tag(tag)
    elements = [Img(src=res['secure_url'], alt=res['public_id'], cls='gallery-image') for res in resources.get('resources', [])]

    return Div(
        H1(f'Results for tag: {tag}'),
        Div(*elements, cls='gallery'),
        A('Back to gallery', href='/')
    )

Explanation of Code:

  • request.query.get('tag', ''): Retrieves the tag from the query parameters.
  • cloudinary.api.resources_by_tag(tag): Fetches all media tagged with the specified tag.
  • Search Form: You can add a search form to the homepage to allow users to search by tag.

Conclusion

In this episode, you learned how to enhance your FastHTML app with advanced Cloudinary features like image transformations, video support, and tagging and search functionalities. These tools allow you to create a more dynamic and user-friendly media management system.

Homework/Assignment:

  • Try adding more transformations, like rotation or adding watermarks to images.
  • Enhance the search functionality to filter by multiple tags.

In the final episode, we will discuss how to deploy your FastHTML and Cloudinary-integrated application to a production environment!

แชร์ให้เพื่อน:

Surapong Kanoktipsatharporn on Linkedin
Surapong Kanoktipsatharporn
CTO at Bua Labs
The ultimate test of your knowledge is your capacity to convey it to another.

Published by Surapong Kanoktipsatharporn

The ultimate test of your knowledge is your capacity to convey it to another.