GitHub i Django
W jednym z djangowych projektów chciałem wyświetlać na stronie informacje o ostatnim commicie z repozytorium Gita. GitHub daje do tego eleganckie REST-owe API, więc pozostało tylko podpiąć wywołanie API pod szablon Django.
Żeby nie babrać się samemu z wywołaniami łebserwisu, dekodowaniem wyników itp., poszukałem jakiejś Pythonowej biblioteki (zgodnie z wielokrotnie sprawdzającą się zasadą, że do wszystkiego jest jakiś moduł Pythona ;) ). Na GitHubie znalazłem nawet dwie propozycje, postanowiłem skorzystać z tej drugiej - python-github2. Link do PyPI wprawdzie nie działa, przez easy_install
też nie mogłem zainstalować, ale przecież jest repozytorium. No to instalujemy:
git clone git://github.com/ask/python-github2.git
cd python-github2
python setup.py build
python setup.py install
Czyli nic strasznego, zwykła procedura instalacji. Przykłady użycia są w pliku README w repozytorium. Zasada jest taka: tworzymy jeden obiekt klasy Github, podając nazwę użytkownika i token, a właściwe wywołania API są wykonywane dopiero później, gdy odwołamy się do którejś z metod obiektów składowych. Przykładowo:
from github2.client import Github github = Github(username="...", api_token=".......") repo = github.repos.show("uzytkownik/repozytorium")
Nazwę użytkownika i token do API zdefiniowałem w głównym pliku settings.py
projektu w zmiennych GITHUB_USER
i GITHUB_API_TOKEN
. Pozostała kwestia pożenienia tego wszystkiego z szablonem. Rozsądne rozwiązanie to utworzenie własnego znacznika szablonu. Tak też zrobiłem, wykorzystując inclusion_tag. Dlaczego akurat tak? Bo chciałem mieć możliwość konfigurowania, które dokładnie informacje o commicie chcę pokazywać. Definicja znacznika znajduje się w katalog_aplikacji\templatetags\github.py
(należy pamiętać o dodaniu aplikacji do krotki INSTALLED_APPS
w ustawieniach projektu).
from github2.client import Github from django import template from django.conf import settings register = template.Library() @register.inclusion_tag("tools/commit.html") def last_commit(repository, branch): try: github = Github(settings.GITHUB_USER, settings.GITHUB_API_TOKEN) commits = github.commits.list(repository, branch) return {'commit': commits[0]} except: return {'commit': None}
Funkcja ma dwa argumenty, jeden określa nazwę repozytorium (włącznie z nazwą użytkownika, np. "zsiciarz/aquila"), a drugi gałąź w repo. Żeby cokolwiek było wyświetlone, należy utworzyć szablon tools/commit.html
. Słownik zwracany przez funkcję znacznika stanowi kontekst szablonu. Zatem mamy dostęp do zmiennej o nazwie commit
. Przykładowy szablon przedstawiam poniżej.
{% if commit %} <p class="github_message">{{ commit.message }}</p> <footer> <ul> <li>Committed by <strong>{{ commit.author.login }}</strong> <time>{{ commit.committed_date }}</time></li> <li><a href="{{ commit.url }}">See at GitHub</a></li> </ul> </footer> {% else %} <p>Sorry, GitHub returned an error.</p> {% endif %}
Możemy teraz w elegancki sposób pokazać informacje o commicie za pomocą naszego znacznika.
{% load github %} {% last_commit "uzytkownik/repozytorium" "master" %}