YouTube API Entegrasyonu: Django ile Video Yükleme

Yayınlanan: 2022-03-11

Kısa bir süre önce, bir müşteri için çalışıyordum, web sitelerine video incelemeleri entegre ediyordum. Yeni bir sorunu çözen motive olmuş herhangi bir geliştirici gibi, yaptığım ilk şey Google'dı ve tamamen farklı bir şeye nasıl ulaşılacağına veya modası geçmiş ve bakımsız Python paketlerine nasıl ulaşılacağına dair çok sayıda faydasız veya yanlış yönlendirilmiş yanıt buldum. Sonunda, kurşunu ve ekibi ısırdım ve her şeyi sıfırdan oluşturdum: görünümleri oluşturduk, Google'ın API'sini öğrendik, API istemcisini oluşturduk ve sonunda Django'dan programlı olarak video yüklemeyi başardık.

Bu yazıda, Django uygulamanızdan YouTube videolarını nasıl yayınlayacağınız konusunda size adım adım rehberlik etmeye çalışacağım. Bu, önce web arayüzü, ardından kodla olmak üzere Google API kimlik bilgileriyle biraz oynamayı gerektirecektir. YouTube bölümünün kendisi çok basittir. Google öğelerinin nasıl çalıştığını anlamamız gerekiyor, çünkü bazen yanıltıcı olabiliyor ve bilgiler birçok yere yayılıyor.

Önkoşullar

Çalışmaya başlamadan önce aşağıdakilere aşina olmanızı tavsiye ederim:

  • YouTube Veri API'sı: Python Hızlı Başlangıç
  • YouTube Veri API'sı: API Referansı
  • YouTube Veri API'sı: Kod Örnekleri
  • Google Python API İstemci Kitaplığı
  • Google Python API İstemci Kitaplığı: Referans Dokümanı
  • Google Python API İstemci Kitaplığı: Kod Örnekleri
  • YouTube API: Python Kod Örnekleri

Dikkat edilmesi gereken ilginç bir kod parçası, Google YouTube API Dokümanlarından aşağıdaki Python Snippet'idir:

 # Sample python code for videos.insert def videos_insert(client, properties, media_file, **kwargs): resource = build_resource(properties) # See full sample for function kwargs = remove_empty_kwargs(**kwargs) # See full sample for function request = client.videos().insert( body=resource, media_body=MediaFileUpload(media_file, chunksize=-1, resumable=True), **kwargs ) # See full sample for function return resumable_upload(request, 'video', 'insert') media_file = 'sample_video.flv' if not os.path.exists(media_file): exit('Please specify a valid file location.') videos_insert(client, {'snippet.categoryId': '22', 'snippet.defaultLanguage': '', 'snippet.description': 'Description of uploaded video.', 'snippet.tags[]': '', 'snippet.title': 'Test video upload', 'status.embeddable': '', 'status.license': '', 'status.privacyStatus': 'private', 'status.publicStatsViewable': ''}, media_file, part='snippet,status')

Başlarken

Ön koşulları okuduktan sonra, başlama zamanı. Bakalım neye ihtiyacımız var.

Aygıt kemeri

Temel olarak, sanal bir ortam oluşturalım. Şahsen pyenv'i tercih ederim. Her ikisini de ayarlamak bu yazının kapsamı dışındadır, bu yüzden aşağıda bazı pyenv komutları göndereceğim ve eğer tercihiniz virtualenv ise, komutları buna göre değiştirmekten çekinmeyin.

Bu yazıda Python 3.7 ve Django 2.1 kullanacağım.

 ➜ ~/projects $ mkdir django-youtube ➜ ~/projects $ cd django-youtube ➜ ~/projects/django-youtube $ pyenv virtualenv 3.7.0 djangoyt ➜ ~/projects/django-youtube $ vim .python-version

Bunu içeriğe koyalım (sadece pyenv kullanırsanız, klasöre girdiğinizde otomatik olarak etkinleşir):

 djangoyt

Bağımlılıkları yükleme:

 ➜ ~/projects/django-youtube $ pip install google-api-python-client google-auth\ google-auth-oauthlib google-auth-httplib2 oauth2client Django unipath jsonpickle

Şimdi Django projemize başlama zamanı:

 ➜ ~/projects/django-youtube $ django-admin startproject django_youtube .

Bazı Google Config için duraklat

Google API'lerini kullanabilmemiz için proje kimlik bilgilerimizi şimdi yapılandıralım.

1. Adım. Aşağıdaki URL'ye gidin:

https://console.developers.google.com/apis/library/youtube.googleapis.com

Adım 2. Yeni bir proje oluşturun.

Yeni bir proje oluştur

Adım 3. "API'leri ve Hizmetleri Etkinleştir"i tıklayın.

API'leri ve Hizmetleri etkinleştirin.

4. Adım. YouTube Data API v3'ü bulun ve "Etkinleştir"i tıklayın.

YouTube Data API v3'ü bulun ve "Etkinleştir"i tıklayın.

Adım 5. Kimlik bilgileri hakkında bir mesaj almalısınız.

kimlik bilgileri hakkında bir mesaj

6. Adım. Sağ taraftaki "Kimlik bilgileri oluştur" mavi düğmesine tıklayın, aşağıdaki ekranı görmelisiniz:

"Kimlik bilgileri oluştur" mavi düğmesine tıklayın

Adım 7. Web sunucusu, Kullanıcı Verileri'ni seçin:

Web sunucusunu, Kullanıcı Verilerini seçin

Adım 8. Yetkili JS kaynaklarını ekleyin ve URI'leri yeniden yönlendirin. Sonuna kadar devam edin:

Yetkili JS kaynakları ekleyin ve URI'leri yeniden yönlendirin.

Tamam, kimlik bilgilerimizi ayarladık. Kimlik bilgilerini JSON biçiminde indirebilir veya İstemci Kimliği ve İstemci Sırrını kopyalayabilirsiniz.

Django'ya geri dön

İlk Django uygulamamızı başlatalım. Genelde "çekirdek" olarak adlandırırım:

 (djangoyt) ➜ ~/projects/django-youtube $ python manage.py startapp core

Şimdi ana sayfa isteklerini çekirdek uygulamamıza yönlendirmek için kök urls.py dosyamıza aşağıdakini ekleyelim:

 # <root>/urls.py from django.urls import path, include path('', include(('core.urls', 'core'), namespace='core')),

Çekirdek uygulamada, bazı yapılandırmalarla birlikte başka bir urls.py dosyasına sahip olalım:

 # core/urls.py from django.conf import settings from django.conf.urls.static import static from django.urls import path from .views import HomePageView urlpatterns = [ path('', HomePageView.as_view(), name='home') ] if settings.DEBUG: urlpatterns += static( settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static( settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

HomePageView işaret eden boş bir yol olduğunu görün. Biraz kod ekleme zamanı.

Şimdi sadece çalıştığını görmek için basit bir TemplateView yapalım.

 # core/views.py from django.shortcuts import render from django.views.generic import TemplateView class HomePageView(TemplateView): template_name = 'core/home.html'

Ve elbette temel bir şablona ihtiyacımız var:

 # core/templates/core/home.html <!DOCTYPE html> <html> <body> <h1>My First Heading</h1> <p>My first paragraph.</p> </body> </html>

Bazı ayar düzeltmeleri yapmamız gerekiyor:

 # settings.py from unipath import Path # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = Path(__file__).parent INSTALLED_APPS 'core', STATIC_ROOT = BASE_DIR.parent.child('staticfiles') STATIC_URL = '/static/' MEDIA_ROOT = BASE_DIR.parent.child('uploads') MEDIA_URL = '/media/'

Şimdi bir YoutubeForm oluşturalım ve onu form_class olarak ekleyelim:

 # core/views.py from django import forms from django.views.generic.edit import FormView class YouTubeForm(forms.Form): pass class HomePageView(FormView): template_name = 'core/home.html' form_class = YouTubeForm

Uygulamanızı şimdi çalıştırmayı deneyin, sayfa şöyle görünecektir:

Sayfa önizlemesi

Yetkilendirmeyi Duraklat

Her şeyden önce, kimlik bilgilerinizi saklamak için bir model oluşturmanız gerekir. Bir dosya, önbellek sistemi veya başka bir depolama çözümü aracılığıyla yapabilirsiniz, ancak bir veritabanı makul ve ölçeklenebilir görünüyor ve ayrıca isterseniz kullanıcı başına kimlik bilgilerini depolayabilirsiniz.

Devam etmeden önce, bir ayarlama yapılması gerekiyor - kullanmamız gereken Django 2.1'i destekleyen oauth2client çatalı var. Yakında resmi desteğimiz olacak, ancak bu arada çatal değişikliklerini inceleyebilirsiniz. Onlar çok basit.

 pip install -e git://github.com/Schweigi/[email protected]#egg=oauth2client Because of compatibility with Django 2.1

settings.py gidin ve önceki adımlarda Google'dan aldığınız Müşteri Kimliğini ve Müşteri Sırrını yerleştirin.

 # settings.py GOOGLE_OAUTH2_CLIENT_ GOOGLE_OAUTH2_CLIENT_SECRET = '<your client secret>'

Dikkat: kodunuzda sır saklamanız önerilmez . Bunu sadece bir gösteri olarak yapıyorum. Uygulama dosyalarında gizli kodlamaları değil, üretim uygulamanızda ortam değişkenlerini kullanmanızı öneririm. Alternatif olarak, JSON'u Google'dan indirdiyseniz, yukarıdaki ayarlar yerine yolunu da belirtebilirsiniz:

 GOOGLE_OAUTH2_CLIENT_SECRETS_JSON = '/path/to/client_id.json'

Oauth2client paketi, kullanabileceğimiz bir CredentialsField ile zaten çok sayıda işlevsellik sağlıyor. Daha sağlam olmamız için yabancı anahtar ve oluşturulan/değiştirilen tarihler gibi daha fazla alan eklemek mümkündür, ancak basit kalalım.

Kimlik bilgilerini saklamak için basit model:

 # core/models.py from django.db import models from oauth2client.contrib.django_util.models import CredentialsField class CredentialsModel(models.Model): credential = CredentialsField()

Taşıma oluşturma ve taşıma zamanı:

 (djangoyt) ➜ ~/projects/django-youtube $ ./manage.py makemigrations core (djangoyt) ➜ ~/projects/django-youtube $ ./manage.py migrate

Şimdi uygulamamızı yetkilendirebilmek için API görünümlerimizi değiştirelim:

core/urls.py dosyamıza, ilk yetkilendirme görünümü için başka bir giriş ekleyelim:

 # core/urls.py from .views import AuthorizeView, HomePageView urlpatterns = [ # [...] path('authorize/', AuthorizeView.as_view(), name='authorize'), ]

Böylece AuthorizeView'ın ilk bölümü şöyle olacaktır:

 # core/views.py from django.conf import settings from django.shortcuts import render, redirect from django.views.generic.base import View from oauth2client.client import flow_from_clientsecrets, OAuth2WebServerFlow from oauth2client.contrib import xsrfutil from oauth2client.contrib.django_util.storage import DjangoORMStorage from .models import CredentialsModel # [...] class AuthorizeView(View): def get(self, request, *args, **kwargs): storage = DjangoORMStorage( CredentialsModel, 'id', request.user.id, 'credential') credential = storage.get() flow = OAuth2WebServerFlow( client_id=settings.GOOGLE_OAUTH2_CLIENT_ID, client_secret=settings.GOOGLE_OAUTH2_CLIENT_SECRET, scope='https://www.googleapis.com/auth/youtube', redirect_uri='http://localhost:8888/oauth2callback/') # or if you downloaded the client_secrets file '''flow = flow_from_clientsecrets( settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON, scope='https://www.googleapis.com/auth/youtube', redirect_uri='http://localhost:8888/oauth2callback/')'''

Ve sonra ikinci kısım:

 if credential is None or credential.invalid == True: flow.params['state'] = xsrfutil.generate_token( settings.SECRET_KEY, request.user) authorize_url = flow.step1_get_authorize_url() return redirect(authorize_url) return redirect('/')

Bu nedenle, kimlik bilgisi yoksa veya kimlik bilgisi geçersizse, bir tane oluşturun ve ardından onu yetkilendirme URL'sine yönlendirin. Aksi takdirde, bir video yükleyebilmemiz için ana sayfaya gitmeniz yeterli!

Şimdi görünüme erişelim ve ne olduğunu görelim:

yetkilendirme hatası

O sayfaya gitmeden önce bir kullanıcı oluşturalım.

 (djangoyt) ➜ ~/projects/django-youtube $ python manage.py createsuperuser Username (leave blank to use 'ivan'): ivan Email address: ivan***@mail.com Password: Password (again): This password is too short. It must contain at least 8 characters. Bypass password validation and create user anyway? [y/N]: y Superuser created successfully.

Ayrıca /admin ile giriş yapalım. Ardından /authorize/ görünümümüze tekrar erişelim.

giriş yapalım

yetki

O zamanlar,

404 hata

Tamam, uzun zaman önce Google ile yapılandırdığımız geri arama URL'sine yönlendirmeyi denedi. Şimdi geri arama görünümünü uygulamamız gerekiyor.

Core/urls.py dosyamıza bir girdi daha ekleyelim:

 # core/urls.py from .views import AuthorizeView, HomePageView, Oauth2CallbackView urlpatterns = [ # [...] path('oauth2callback/', Oauth2CallbackView.as_view(), name='oauth2callback') ]

Ve başka bir görünüm:

 # core/views.py # the following variable stays as global for now flow = OAuth2WebServerFlow( client_id=settings.GOOGLE_OAUTH2_CLIENT_ID, client_secret=settings.GOOGLE_OAUTH2_CLIENT_SECRET, scope='https://www.googleapis.com/auth/youtube', redirect_uri='http://localhost:8888/oauth2callback/') # or if you downloaded the client_secrets file '''flow = flow_from_clientsecrets( settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON, scope='https://www.googleapis.com/auth/youtube', redirect_uri='http://localhost:8888/oauth2callback/')''' # [...] class Oauth2CallbackView(View): def get(self, request, *args, **kwargs): if not xsrfutil.validate_token( settings.SECRET_KEY, request.GET.get('state').encode(), request.user): return HttpResponseBadRequest() credential = flow.step2_exchange(request.GET) storage = DjangoORMStorage( CredentialsModel, 'id', request.user.id, 'credential') storage.put(credential) return redirect('/')

Not: Akış, AuthorizeView'ın dışına taşınarak global hale geldi. İdeal olarak, bunu AuthorizeView altında oluşturmalı ve bir önbelleğe kaydetmeli, ardından geri aramada almalısınız. Ancak bu, bu yazının kapsamı dışındadır.

AuthorizeView'ın get yöntemi şimdi:

 def get(self, request, *args, **kwargs): storage = DjangoORMStorage( CredentialsModel, 'id', request.user.id, 'credential') credential = storage.get() if credential is None or credential.invalid == True: flow.params['state'] = xsrfutil.generate_token( settings.SECRET_KEY, request.user) authorize_url = flow.step1_get_authorize_url() return redirect(authorize_url) return redirect('/')

Benzer uygulamaları buradan inceleyebilirsiniz. oauth2client paketinin kendisi görünümler sağlar, ancak özellikle özel Oauth görünümümü uygulamayı tercih ederim.

  • https://github.com/google/google-api-python-client/blob/master/samples/django_sample/plus/views.py
  • https://github.com/google/oauth2client/blob/master/oauth2client/contrib/django_util/views.py

Şimdi /authorize/ URL'sini tekrar denerseniz, OAuth akışının çalışması gerekir. Bu çalışmaya değip değmediğini görme ve videomuzu yükleme zamanı! HomePageView önce kimlik bilgilerini kontrol edecek ve her şey yolundaysa, videomuzu yüklemeye hazırız.

HomePageView için yeni kodumuzun nasıl görüneceğini kontrol edelim:

 import tempfile from django.http import HttpResponse, HttpResponseBadRequest from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload class HomePageView(FormView): template_name = 'core/home.html' form_class = YouTubeForm def form_valid(self, form): fname = form.cleaned_data['video'].temporary_file_path() storage = DjangoORMStorage( CredentialsModel, 'id', self.request.user.id, 'credential') credentials = storage.get() client = build('youtube', 'v3', credentials=credentials) body = { 'snippet': { 'title': 'My Django Youtube Video', 'description': 'My Django Youtube Video Description', 'tags': 'django,howto,video,api', 'categoryId': '27' }, 'status': { 'privacyStatus': 'unlisted' } } with tempfile.NamedTemporaryFile('wb', suffix='yt-django') as tmpfile: with open(fname, 'rb') as fileobj: tmpfile.write(fileobj.read()) insert_request = client.videos().insert( part=','.join(body.keys()), body=body, media_body=MediaFileUpload( tmpfile.name, chunksize=-1, resumable=True) ) insert_request.execute() return HttpResponse('It worked!')

Ve yeni şablon:

 {# core/templates/core/home.html #} <!DOCTYPE html> <html> <body> <h1>Upload your video</h1> <p>Here is the form:</p> <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="Submit"> </form> </body> </html>

Video alanını YouTubeForm'a eklemeyi unutmayın:

 class YouTubeForm(forms.Form): video = forms.FileField()

İşte başlıyoruz!

Formu yükle

Ardından, YouTube hesabınızın Studio sayfasını kontrol edin (bir kanalınızın olması önemlidir):

yüklenen video

işte!

Kapanış Notları

Kodun biraz iyileştirilmesi gerekiyor, ancak bu iyi bir başlangıç ​​noktası. Umarım Google'ın YouTube API Entegrasyon sorunlarının çoğuna yardımcı olmuştur. Burada dikkat edilmesi gereken birkaç önemli nokta daha var:

  • Yetkilendirme için, uygulamanızın video yüklemesine izin verecek kullanıcı için oturum açma ve ek izinler istemeniz önemlidir.
  • Akış değişkeninin global olmaktan çıkarılması gerekir. Bir üretim ortamında güvenli değildir. Örneğin, ilk görünüme erişen kullanıcı kimliğine veya oturuma göre önbelleğe almak daha iyidir.
  • Google, yalnızca ilk yetkilendirmeyi yaptığınızda bir yenileme belirteci sağlar. Dolayısıyla bir süre sonra, çoğunlukla bir saat sonra, jetonunuzun süresi dolacak ve onların API'si ile etkileşime invalid_grant yanıtları almaya başlayacaksınız. Halihazırda bir istemciye yetki vermiş olan aynı kullanıcıyı yeniden yetkilendirmek, yenileme jetonunuzu garanti etmez. Google Hesapları sayfanızdan başvuruyu iptal etmeniz ve ardından yetkilendirme işlemini tekrar yapmanız gerekmektedir. Bazı durumlarda, belirteci yenilemeye devam etmek için bir görevi çalıştırmanız gerekebilir.
  • Doğrudan istekle ilgili bir kullanıcı kimlik bilgisi kullandığımızdan, görüşümüze göre oturum açmamız gerekiyor.

Akış Değişimi Hatası

Yükleme çok zaman alır ve bunu ana başvuru sürecinizde yapmak, yükleme gerçekleşirken tüm uygulamanın engellenmesine neden olabilir. Doğru yol, onu kendi sürecine taşımak ve yüklemeleri eşzamansız olarak işlemek olacaktır.

Kafası karışmış? Olmayın, Python için Kereviz'de Arka Plan İş İş Akışını Düzenleme bölümünde daha fazlasını okuyun.