03.github Library
03.github Library
In the Terminal
Clone the repo. Your command should look something like this:
If you’re ever needing to interact with a remote API, the chances are a
Python library has been written for it, possibly by a third party. A Google
search for python library is a good starting point.
The Github client class (github.Github) is the starting point. It’s instantiated
with an access token (which we’ll see how to get later), which works in lieu
of the username and password. Once you have an instance of Github, you
can retrieve information about the logged-in user with the get_user()
method, which returns a github.AuthenticatedUser.AuthenticatedUser
class:
We can then get information about the user, like their name:
>>> print(user.name)
Ben Shaw
Compare that to making all these requests ourselves. We’d have to parse
the data that was retrieved and figure out what API keys and IDs need to be
fed into each URL to get the data we want. Using the library means all that
hard work is done for us.
One downside that you might come across though, is that sometimes
libraries get out of date if they’re not well maintained. A service might
make changes to their API and if the library is authored by a third party
they could lag behind in updating their code to support the changes. This
doesn’t happen very often so on the balance of things, a library should be
preferred if one is available.
Now let’s see how to integrate Django with PyGithub. In particular, we’re
interested in how to make use of the user’s access token.
Django Integration
The method of setting up integration/authentication of your application
with a remote service is going to depend on your use case, and how the
remote service works. We saw back in Course 1 how to set up
authentication with Google. A client ID and key were generated and used to
authenticate our application. Sometimes this information is all you need to
work with a remote API. Other times, you also need a user key to identify
each user who’s logged in through your service.
With GitHub and Django Allauth, it’s possible for a user to log in to your site
using GitHub for authentication. You can then fetch their Allauth Social
Application Token and use it to access GitHub as them (but only with the
permissions they have granted your application). This is quite an elegant
solution as all the token handling is done for you as part of authentication.
However it does require quite a bit of setup at GitHub to register your
application – similar to the process involved for setting up an application
for Google authentication.
GitHub also allows a user to create personal tokens for authentication,
which can be revoked at any time to remove access, in case the token is
leaked. The user can feel more secure giving these tokens to a web site than
handing over their username and password. For simplicity, it’s this type of
token we’re going to use when building a site with GitHub integration.
In our example app we’ll create a Profile class to store the token. Let’s do
that now, continuing work on the course4_proj project that we created in
the last section.
Try It Out
Try It Out
First you’ll need to install PyGithub, with pip:
Then we’ll create a new app, called gh (short for GitHub; if we call it github
it will conflict with the PyGithub library). Create the app with the startapp
management command:
Open settings.py
Next, let’s set up the model for the profile. This should be a familiar process
to you, but to make it quicker you can just copy and paste this code into
models.py in the gh app.
Open gh/models.py
class Profile(models.Model):
user = models.OneToOneField(get_user_model(),
on_delete=models.CASCADE)
token = models.TextField()
def __str__(self):
return f"Profile for {self.user.username}"
Next, we’ll just use the Django Admin site to manage user profiles. The
Profile model needs to be registered in Django admin, so open admin.py in
gh and paste in this code:
Open gh/admin.py
admin.site.register(Profile)
We’ll then need to create an admin user that can log in to the admin site.
Remember this is done with the createsuperuser management command.
Do this now:
To verify that this is all working, start the Django dev server, and navigate
to the /admin/ page. Log in with the username (no email address) and
password that you created. Navigate to the Profiles list, then the Add Profile
page. Verify that you can see the form for selecting a user and entering a
token.
add profile form
View Blog
But right now, you don’t have a token! So let’s go and get one.
To continue with the setup, these steps assume you already have a GitHub
account. If not, sign up for one now, it’s free. You’ll also need to verify your
email address with GitHub; this is required.
Once your account is ready and you’ve logged in, you can visit the New
personal access token page to generate a new token. The Note doesn’t
matter as it’s just for your reference. Under Select scopes, just select repo
which will select all the repository scopes.
github token create page
Then scroll down the page and click Generate Token. On the next screen,
you’ll be shown the token. Make sure to copy it as it won’t be shown again.
Although, since you’re not using it for anything else you can just create
another new token should you misplace this one.
Now that you have the token, head back to the Django admin page and fill
in the Token field on your user’s Profile, then Save it.
Start by creating a templates directory inside the gh app, then create a file
in it called index.html. Copy and paste this content into it:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no,
initial-scale=1.0, maximum-scale=1.0, minimum-
scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Repositories</title>
</head>
<body>
<h2>{{ github_user.name }} has access to:</h2>
<ul>
{% for repository in github_user.get_repos %}
<li>{{ repository.name }}</li>
{% empty %}
<li>No repositories.</li>
{% endfor %}
</ul>
</body>
</html>
Open gh/views.py
from django.core.exceptions import PermissionDenied
from github import Github
Then implement a single view function called index. It just creates a Github
instance using the user’s token from their Profile. We have some basic
error handling in case the Profile or token is not set. Then, it passes the
GitHub user instance to the template:
def index(request):
if request.user.is_anonymous:
raise PermissionDenied("Anonymous user not allowed.")
if not request.user.profile:
raise PermissionDenied("User does not have a Profile.")
if not request.user.profile.token:
raise PermissionDenied("User Profile does not have a
token.")
g = Github(request.user.profile.token)
Open urls.py
import gh.views
path("", gh.views.index)
Start your Django dev server, and navigate to the / (index) page. You
should see a page like the one below:
repository list
View Blog
Although, you’ll see your name and the list of repositories to which you
have access.
Wrap-Up
Wrap-Up
This section was intended as a quick intro to using third-party libraries for
API interaction, and how to store user-specific authentication data. We took
a few shortcuts by using built-in Django features, like the admin
authentication system, and no UI for users to add their own token. To
summarize:
And to summarize the things that we didn’t do, but should, if we were
building this into a real site:
- Set up Django authentication instead of requiring the user to log in via
Django admin.
- Create a GUI for the user to set up their token(s).
- Add models to represent the remote objects we’re using. For example, our
own Repository model, that would allow for local caching.
- Caching to prevent multiple requests for the same user within a short
period of time.
We saw how to set up these features in the previous section, and in earlier
courses.
That brings us to the end of this module. In the next module, we’re going to
look at task queueing with the Celery library.
Pushing to GitHub
Pushing to GitHub
info
Important
You may see the following message when pushing to GitHub.
You can avoid this problem by disabling the secret scanning for your
GitHub account, but that would decrease your security.
db.sqilte3
Note, ignoring db.sqlite3 will ignore the database for the project. Any
information saved in the database (movie searches, GitHub repos, etc.)
will no longer be available when you pull from the repo. However,
Django will create a new database when you do a manage.py migrate.
Before continuing, you must push your work to GitHub. In the terminal:
git add .
git commit -m "Finish github library"
Push to GitHub:
git push