> ## Documentation Index
> Fetch the complete documentation index at: https://cloudinary.com/documentation/llms.txt
> Use this file to discover all available pages before exploring further.

# Python sample projects


[app-gallery-link]: https://app-gallery.cloudinary.com/gallery?tag=Python

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](code_explorers) too!

## Django photo album

The [Django photo album app](https://github.com/cloudinary/cloudinary-django-sample/tree/master/photo_album) 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:

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)
```

> **See the full code**:
>
> * [Explore the Django photo album app on GitHub](https://github.com/cloudinary/cloudinary-django-sample/tree/master/photo_album).

## Django form and model helpers

The [django_cloudinary_app](https://github.com/cloudinary-devs/my-django-app/tree/main/django_cloudinary_app) folder in the [my-django-app](https://github.com/cloudinary-devs/my-django-app/tree/main) 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](django_image_and_video_upload#django_forms_and_models).  

Furthermore, within the [my-django-app](https://github.com/cloudinary-devs/my-django-app/tree/main) repository, you'll find a [django_app](https://github.com/cloudinary-devs/my-django-app/tree/main/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:

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})
```

> **See the full code**:
>
> * [Explore the Django form and model helpers app on GitHub](https://github.com/cloudinary-devs/my-django-app/tree/main).

## Django photo collection app

The [Django photo collection app](https://github.com/cloudinary-devs/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:

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**:
>
> * [Explore the Django photo collection app on GitHub](https://github.com/cloudinary-devs/django_photo_collection_app).

> * [Read an article about the Django photo collection app on Hackernoon](https://hackernoon.com/how-to-build-a-dynamic-photo-collection-app-with-django).

> * Watch YouTube videos showcasing key app features, including [user authentication](https://www.youtube.com/watch?v=AjuhceU7Mk8), [profile creation](https://www.youtube.com/watch?v=ld_dNwMBzX0), and [creating](https://www.youtube.com/watch?v=j9c26igy4WM) and [displaying](https://www.youtube.com/watch?v=5MoMqNgqqIQ) photo collections.

---

## Basic Flask - image uploader and transformer

The [Basic Flask - image uploader and transformer](https://github.com/cloudinary/pycloudinary/tree/master/samples/basic_flask) 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:

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()
```

> **See the full code**:
>
> * [Explore the Flask image uploader and transformer app on GitHub](https://github.com/cloudinary/pycloudinary/tree/master/samples/basic_flask).

## 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](ai_in_action#content_analysis_for_auto_tagging), 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. You can read more about it in this [blog post](https://cloudinary.com/blog/how-to-offer-e-commerce-product-recommendations-using-python-and-auto-tagging). 

This is the Flask product recommendations app in action: 

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)
...
```

> **See the full code**:
>
> * [Explore the Flask product recommendation app on GitHub](https://github.com/cloudinary-devs/python_product_recommendations).

## Image pre-processing and augmentation

This Jupyter notebook shows examples of pre-processing and augmenting images for machine learning by applying [transformations](django_image_manipulation). You can read more about it in this [blog post](https://cloudinary.com/blog/preprocess-images-for-deep-learning-in-python).

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

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)
```

> **See the full code**:
>
> * [Explore the image pre-processing and augmentation Jupyter notebook on GitHub](https://github.com/cloudinary-devs/image-preprocessing).

> * [Open the Jupyter notebook](https://colab.research.google.com/github/cloudinary-devs/image-preprocessing/blob/main/samples.ipynb).

## App Gallery
The [Cloudinary app gallery][app-gallery-link] 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.

  
    
  

