Programmable Media

Python sample projects

Last updated: Feb-17-2025

We've created some sample projects to get you started with integrating Cloudinary into your Python applications, featuring both Django and Flask frameworks.

Tip
Check out our collection of Python code explorers too!

Django photo album

The Django photo album app showcases various functionalities such as uploading, saving delivery URLs to the database, transforming, and delivering images. In particular, explore how to upload images through your server or via signed and unsigned uploads directly from the browser. Additionally, learn how to apply smart-cropping to uploaded images to fit them in a square and save their delivery URLs to your database. Finally, view all uploaded images displayed in a photo album and seamlessly apply transformations on-the-fly.

This is the Django photo album app in action:

Video Player is loading.
Current Time 0:00
Duration -:-
Loaded: 0%
Stream Type LIVE
Remaining Time 0:00
 
1x
  • descriptions off, selected
  • captions off, selected

    Here's an excerpt from the code featuring a CloudinaryField within the Photo table of the models.py file, intended for storing Cloudinary URLs in the database. Additionally, the CloudinaryJsFileField is utilized in the forms.py file to capture and transform images uploaded to Cloudinary via a form.

    models.py
    Python
    from django.core.files.uploadedfile import UploadedFile
    from django.db import models
    from cloudinary.models import CloudinaryField
    from django.core.exceptions import ValidationError
    
    # For testing model validation
    FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 10  # 10mb
    
    
    def file_validation(file):
        if not file:
            raise ValidationError("No file selected.")
    
        # For regular upload, we get UploadedFile instance, so we can validate it.
        # When using direct upload from the browser, here we get an instance of the CloudinaryResource
        # and file is already uploaded to Cloudinary.
        # Still can perform all kinds on validations and maybe delete file, approve moderation, perform analysis, etc.
        if isinstance(file, UploadedFile):
            if file.size > FILE_UPLOAD_MAX_MEMORY_SIZE:
                raise ValidationError("File shouldn't be larger than 10MB.")
    
    
    class Photo(models.Model):
        """
        This is the main model in the project. It holds a reference to cloudinary-stored
        image and contains some metadata about the image.
        """
    
        # Misc Django Fields
        create_time = models.DateTimeField(auto_now_add=True)
        title = models.CharField("Title (optional)", max_length=200, blank=True)
    
        # Points to a Cloudinary image
        image = CloudinaryField('image', validators=[file_validation])
    
        """ Informative name for model """
    
        def __unicode__(self):
            try:
                public_id = self.image.public_id
            except AttributeError:
                public_id = ''
            return "Photo <%s:%s>" % (self.title, public_id)

    forms.py
    Python
    from django.forms import ModelForm
    
    import cloudinary
    import hashlib
    # Next two lines are only used for generating the upload preset sample name
    from cloudinary.compat import to_bytes
    from cloudinary.forms import CloudinaryJsFileField, CloudinaryUnsignedJsFileField
    from .models import Photo
    
    
    class PhotoForm(ModelForm):
        class Meta:
            model = Photo
            fields = '__all__'
    
    
    class PhotoDirectForm(PhotoForm):
        image = CloudinaryJsFileField(
            attrs={'style': "margin-top: 30px"},
            options={
                'tags': "directly_uploaded",
                'crop': 'limit', 'width': 1000, 'height': 1000,
                'eager': [{'crop': 'fill', 'width': 150, 'height': 100}]
            })
    
    
    class PhotoUnsignedDirectForm(PhotoForm):
        upload_preset_name = "sample_" + hashlib.sha1(
            to_bytes(cloudinary.config().api_key + cloudinary.config().api_secret)).hexdigest()[0:10]
        image = CloudinaryUnsignedJsFileField(upload_preset_name)


    Django form and model helpers

    The django_cloudinary_app folder in the my-django-app repository demonstrates seamlessly integrating Cloudinary features while preserving your standard workflow of saving delivery URLs directly into your database during uploads. Learn how to upload images to Cloudinary, apply transformations, and store their Cloudinary delivery URLs in your database using Cloudinary's form and model helper classes.

    Furthermore, within the my-django-app repository, you'll find a django_app folder containing the same application without Cloudinary integration. This application serves as a reference point for comparison. You can review the code that requires modification to integrate Cloudinary. Notice the enhancements Cloudinary brings, including optimized image sizes and improved resize and cropping functionality.

    This is the Django form and model helpers app in action:

    Video Player is loading.
    Current Time 0:00
    Duration -:-
    Loaded: 0%
    Stream Type LIVE
    Remaining Time 0:00
     
    1x
    • descriptions off, selected
    • captions off, selected

      Here's an excerpt from the code for configuring a form and table to enable users to select images for uploading to Cloudinary. After uploading, the URLs for accessing these images are stored in the database.

      forms.py
      Python
      from django.forms import ModelForm     
      from cloudinary.forms import CloudinaryFileField
      from .models import Photo
      
      class PhotoForm(ModelForm):
          image = CloudinaryFileField()
      
          class Meta:
              model = Photo
              fields = '__all__'
      
          def __init__(self, *args, **kwargs):
             super().__init__(*args, **kwargs)
             self.fields['image'].options={
                 'tags': 'new_image',
                 'format': 'png'
      
          }

      models.py
      Python
      from django.db import models
      from cloudinary.models import CloudinaryField
      
      class Photo(models.Model):
          image = CloudinaryField('image')

      views.py
      Python
      from django.shortcuts import render, redirect
      
      from .models import Photo
      from .forms import PhotoForm
      
      def upload(request):
        context = dict( backend_form = PhotoForm())
      
        if request.method == 'POST':
          form = PhotoForm(request.POST, request.FILES)
          if form.is_valid():
              form.save()
              return redirect('display')
        return render(request, 'upload.html', context)
      
      def display(request):
          photos = Photo.objects.all()  # Retrieve all photos from the database
          return render(request, 'display.html', {'photos': photos})


      Django photo collection app

      The Django photo collection app offers a user-friendly platform for creating, customizing, and sharing photo collections, suitable for both personal and business purposes. In industries like fashion, these photo collections are often referred to as "lookbooks."

      Key features of the app include:

      • User authentication: Sign up and log in to create a personalized profile, complete with a bio and profile picture.

      • Lookbook management: Create, edit, and delete your own photo collections (lookbooks).

      • Image customization: Upload and customize images for your lookbooks using Cloudinary’s media management tools.

      • Browse collections: View all available lookbooks, with options to filter by the user who created them.

      • Profile integration: See user profile pictures displayed alongside the lookbooks they’ve created.

      This app is designed to make organizing and showcasing your photos simple and visually appealing.

      This is the Django photo collection app in action:

      Video Player is loading.
      Current Time 0:00
      Duration -:-
      Loaded: 0%
      Stream Type LIVE
      Remaining Time 0:00
       
      1x
      • descriptions off, selected
      • captions off, selected

        Below is a snippet from the codebase that outlines how to configure the necessary database tables, forms, and views for creating and displaying lookbooks along with their associated images. This includes the model setup for lookbooks and images, the forms to handle lookbook creation, and the view logic to render a lookbook using Cloudinary's helper methods for image management within an HTML template.

        lookbook_app/models.py
        Python
        from django.db import models
        from django.contrib.auth.models import User
        from cloudinary.models import CloudinaryField
        
        class Lookbook(models.Model):
            """
            Model representing a lookbook created by a user.
            """
            user = models.ForeignKey(User, on_delete=models.CASCADE)
            title = models.CharField(max_length=100)
            description = models.TextField(blank=True)
            overlay_image = CloudinaryField('overlay_images')
            orientation = models.CharField(max_length=10, choices=[('portrait', 'Portrait'), ('landscape', 'Landscape'), ('square', 'Square')], default='square')
            border_width = models.CharField(max_length=10, default='0px')
            border_color = models.CharField(max_length=10, default='black')
        
            def __str__(self):
                return self.title
        
        class LookbookImage(models.Model):
            """
            Model representing an image associated with a lookbook.
            """
            lookbook = models.ForeignKey(Lookbook, on_delete=models.CASCADE, related_name='images')
            image = CloudinaryField('images')
            transformed_image = models.URLField(blank=True, null=True)
        
            def __str__(self):
                return f"Image for {self.lookbook.title}"

        lookbook_app/forms.py
        Python
        class LookbookForm(forms.ModelForm):
            """
            Form for creating or updating a lookbook.
            """
        
            class Meta:
                model = Lookbook
                fields = ['title', 'description', 'overlay_image']
        
            def save(self, commit=True):
                instance = super().save(commit=False)
                if commit:
                    instance.save()
                return instance
        
        class LookbookImageForm(forms.ModelForm):    
            """
            Form for handling LookbookImage model.
            """
        
            class Meta:
                model = LookbookImage
                fields = ['image']
        
            def save(self, commit=True, image_url=None):
                instance = super().save(commit=False)
                if commit:
                    instance.save()
                return instance

        lookbook_app/templates/display.html
        Python
        def display(request, lookbook_id):
           lookbook = get_object_or_404(Lookbook, pk=lookbook_id)
           images = lookbook.images.all()
           return render(request, 'display.html', {'photos': images, 'lookbook': lookbook})

        lookbook_app/views.py
        Html
        {% for photo in photos %}
           <div class="gallery-col">
              <div class="gallery-image">
                  <!-- Display transformed image -->
                  <img src="{{ photo.transformed_image }}" alt="Image" class="img-fluid">
                  <div class="gallery-overlay">
                     <!-- Link to view in a new browser tab -->
                     <a href="{{ photo.transformed_image }}" target="_blank"><h5>Click to View</h5></a>
                  </div>
              </div>
           </div>
        {% endfor %}

        See the full code


        Basic Flask - image uploader and transformer

        The Basic Flask - image uploader and transformer demonstrates how you can upload images to Cloudinary and display them on a webpage with various transformations applied.

        This is the Flask image uploader and transformer app in action:

        Video Player is loading.
        Current Time 0:00
        Duration -:-
        Loaded: 0%
        Stream Type LIVE
        Remaining Time 0:00
         
        1x
        • descriptions off, selected
        • captions off, selected

          Here's an excerpt from the code that handles a user-select image passed to the backend using a form. It uploads these images to Cloudinary and then displays both the original and transformed versions on-the-fly.

          app.py
          Python
          from cloudinary.uploader import upload
          from cloudinary.utils import cloudinary_url
          from flask import Flask, render_template, request
          
          app = Flask(__name__)
          
          
          @app.route('/', methods=['GET', 'POST'])
          def upload_file():
              upload_result = None
              thumbnail_url1 = None
              thumbnail_url2 = None
              if request.method == 'POST':
                  file_to_upload = request.files['file']
                  if file_to_upload:
                      upload_result = upload(file_to_upload)
                      thumbnail_url1, options = cloudinary_url(upload_result['public_id'], format="jpg", crop="fill", width=100,
                                                               height=100)
                      thumbnail_url2, options = cloudinary_url(upload_result['public_id'], format="jpg", crop="fill", width=200,
                                                               height=100, radius=20, effect="sepia")
              return render_template('upload_form.html', upload_result=upload_result, thumbnail_url1=thumbnail_url1,
                                     thumbnail_url2=thumbnail_url2)
          
          
          if __name__ == "__main__":
              app.debug = True
              app.run()


          Flask product recommendations

          This app serves as a recommendation engine for products based on user-selected images. Users can choose product images that are auto-tagged, and the app analyzes them to identify common themes or tags. It then suggests other images with similar themes, providing recommendations for users to explore further.

          This is the Flask product recommendations app in action:

          Video Player is loading.
          Current Time 0:00
          Duration -:-
          Loaded: 0%
          Stream Type LIVE
          Remaining Time 0:00
           
          1x
          • descriptions off, selected
          • captions off, selected

            Here's an excerpt from the code that defines the /output route for processing a POST request, where it captures user-selected images. It then identifies common themes based on the images' auto-tags and suggests similarly tagged images for further exploration.

            demo.py
            Python
            ...
            @app.route("/output", methods=['POST'])
            def output():
                selected_imgs = request.form.getlist("selected_imgs")
                if not selected_imgs:
                    message = "Select at least one product image."
                    recommendations = []
                else:
                    result = all_images()
                    tag_list = []
                    for img in selected_imgs:
                        for asset in result['resources']:
                            if asset['public_id'] == img:
                                img_details = cloudinary.api.resource(img)
                                tag_list.extend(tag for tag in img_details['tags'] if tag not in ["adult", "my_products"])
                    most_frequent_tags = most_frequent(tag_list)
                    recommendations = []
                    for frequent_tag in most_frequent_tags:
                        for asset in result['resources']:
                            show = "yes"
                            img_details = cloudinary.api.resource(asset['public_id'])
                            for i in selected_imgs:
                                if i == asset['public_id']:
                                    show = "no"
                                if frequent_tag[0] in img_details['tags'] and show == "yes":
                                    url="https://res.cloudinary.com/demo/image/upload/f_auto/q_auto/c_fill_pad,g_auto,w_100,h_100/v"+str(asset["version"])+"/" +asset["public_id"]         
                                    if url not in recommendations:
                                        recommendations.append(url)
                    message = "We thought you might like to try these:"
                return render_template('output.html', recommendations=recommendations, msg=message)
            ...


            Image pre-processing and augmentation

            This Jupyter notebook shows examples of pre-processing and augmenting images for machine learning by applying transformations. You can read more about it in this blog post.

            This is the image pre-processing and augmentation Jupyter notebook in action:

            Video Player is loading.
            Current Time 0:00
            Duration -:-
            Loaded: 0%
            Stream Type LIVE
            Remaining Time 0:00
             
            1x
            • descriptions off, selected
            • captions off, selected

              Here's an excerpt from the code that establishes an upload preset tailored to pre-process images by smart-cropping them to a size of 400x400 pixels. This preset is automatically applied during the upload process. Furthermore, saturation is applied as an augmentation to enhance the flexibility of the image model that this image is being prepared for.

              samples.ipynb
              Python
              ...
              # Create an upload preset to pre-process the images:
              
              cloudinary.api.create_upload_preset(
                name = "pre-process",
                unsigned = True,  
                transformation = {"width": 400, "height": 400, "crop": "fill", "gravity": "auto", "effect": "grayscale"}
              )
              
              ...
              # Upload the images and apply the upload preset:
              
              for x in range(1,5):
                cat_num="cat"+str(x)
                cat_url="https://res.cloudinary.com/demo/image/upload/v1/blogs/python-preprocessing/"+"cat"+str(x)
                dog_num="dog"+str(x)
                dog_url="https://res.cloudinary.com/demo/image/upload/v1/blogs/python-preprocessing/"+"dog"+str(x)
                resp_cat = cloudinary.uploader.upload(cat_url, public_id = cat_num, unique_filename = False, overwrite = True, upload_preset = "pre-process")
                print(resp_cat)
                resp_dog=cloudinary.uploader.upload(dog_url, public_id = dog_num, unique_filename = False, overwrite = True, upload_preset = "pre-process")
                print(resp_dog)
              
              ...
              # Saturation
              # Adjusted the image saturation to 70:
              
              for x in range(1,3):
                id="dog" + str(x) + "_saturated"
                url="https://res.cloudinary.com/demo/image/upload/v1/blogs/python-preprocessing/"+"dog"+str(x)
                resp = cloudinary.uploader\
                .upload(url, public_id = id, unique_filename = False, overwrite = True,
                  transformation = {"width": 400, "height": 400, "crop": "fill", "gravity": "auto", "effect": "saturation:70"})
                print(resp)


              App Gallery

              The Cloudinary app gallery provides a variety of fully working apps that incorporate Cloudinary as part of the tech stack, built in various popular programming languages.

              Each app in the gallery presents an overview of the functionality, a link to the open-source repo, and complete setup instructions, so that you can grab the code and easily build your own version.

              Cloudinary app gallery

              ✔️ Feedback sent!