Bunny.net is a fast and reliable CDN. I'm going to show you how to set up and start using Bunny.net in your next Django project.
Bunny.net Setup
Go to bunny.net and login. Click on the Storage icon and then on Add Storage Zone. Give your storage zone a name and select the geolocations that best fit your need. In this guide I'll call my zone myzone
in location New York.
Once created you'll be redirected to the File Manager for your zone. Click on the Connect Pull Zone button in the top right. Again, give it a name (I like to keep names of my zones consistent) and select that options that best fit your CDN needs.
Django Setup
We assume that you've already created and done a the bare minimum of setting up a new django project.
We'll first edit our settings.py
and include some new attributes. In bunny.net, under Storage, click FTP & API Access. Copy the Username and Password found on the page and save them as attributes in your settings.
I also went ahead and set the default file storage to a BunnyStorage
class (that we'll create below) and changed the media url to that of the respective pull zone we created.
# Media files
#
DEFAULT_FILE_STORAGE = 'myapp.storage.BunnyStorage'
MEDIA_URL = 'https://myzone.b-cdn.net/myzone/media/'
# Bunny.net CDN Access
#
BUNNY_ZONENAME = 'myzone'
BUNNY_PASSWORD = 'arandom-string-of-numbersand-letters'
As of Feb. 2021, Bunny.net does not have an official Python API. However, they do link NiveditJain's library as a stable library. It's just a single file so we'll just wget
it into our django project folder (where manage.py is saved) and import it relatively to our custom storage module.
cd myproject
wget https://raw.githubusercontent.com/NiveditJain/BunnyCDNStorageLib/master/BunnyCDNStorage.py
Important!
You must edit the BunnyCDNStorage.py
file before proceeding! Change the upload_file
method to the one below.
def upload_file(self,cdn_path,file_name,file_data):
"""
uploads your files to cdn server \n
cdn_path - directory to save in CDN \n
filename - name to save with cdn \n
if none it will look for file in present working directory
"""
if(cdn_path[-1]=='/'):
cdn_path=cdn_path[:-1]
request_url=self.base_url+cdn_path+'/'+file_name
response=requests.request("PUT",request_url,data=file_data,headers=self.headers)
return(response.json())
Once done, change directory into the django app you'd like to associate the storage backend to and create a new file storage.py
.
The django docs provide in-depth documentation of writing custom storage backends. So, if you want to get a deeper understanding of what we're doing exactly, you should check those pages out.
Our storage backend consists of a single class and five methods.
In myapp/storage.py
,
from django.conf import settings
from django.core.files.images import ImageFile
from django.core.files.storage import Storage
import BunnyCDNStorage
class BunnyStorage(Storage):
def __init__(self):
self.conn = BunnyCDNStorage.CDNConnector(
settings.BUNNY_PASSWORD,
settings.BUNNY_ZONENAME,
storage_zone_region='ny'
)
def _open(self, name, mode='rb'):
f = self.conn.get_file(name)
return ImageFile(f)
def _save(self, name, content):
self.conn.upload_file('/media/', name, content)
return name
def delete(self, name):
self.conn.remove(name)
def exists(self, name):
try:
self.conn.get_file(name)
except ValueError:
return False
return True
def listdir(self, path):
pass
def size(self, name):
pass
def url(self, name):
return f'https://myzone.b-cdn.net/media/{name}'
And that's it! Until Bunny.net releases an official Python API and a standard Django package is released, this is kind of the best we got right now... Happy coding!
Top comments (2)
Hi, thanks for very valuable and useful post! All works fine for me except for uploading new files from admin panel. Maybe I should make connection to bunny storages in settings file in some way?
Hi Armen, I'm incredibly sorry about getting back to you so late. A lot has changed in my life since publishing this (new job, moving... etc). I've since written a library (github.com/willmeyers/django-bunny...) that is much more stable than this. If you're still having issues feel free to raise an issue and we can take a closer look at what's going on. Thanks for commenting and again so sorry for the very late reply!