Reference Guides

The Core App

The core app is where the home page and the pages found in the HCI’s footer are housed. It is also used to house modules that aren’t app-specific. For example, it houses a custom UserProfile model that extends the Django User model. This UserProfile model isn’t specific to any app.

core.admin

Configures the admin site for the core app.

class core.admin.UserProfileAdmin(model, admin_site)

Configures the UserProfile model in the admin site.

core.apps

Provides the configuration for the core app.

class core.apps.CoreConfig(app_name, app_module)

Configures the core app.

core.crud

Centralizes create, read, update, and delete logic for the core app.

core.crud.create_user_profile(*, username: str, email_verified: bool, photo_url: str, display_name: str, provider: str) tuple[UserProfile, User] | None

Creates a UserProfile object in the database.

Parameters:
  • username – The User object’s username.

  • email_verified – Whether the user’s email has been verified.

  • photo_url – A URL for the user’s profile picture.

  • display_name – The user’s display name.

  • provider – The method used to log the user in, e.g., Google.

Returns:

A tuple containing the UserProfile object and the User object in the database with the given username. If the User object doesn’t exist yet, we return None.

core.crud.read_user_profile(username: str) tuple[UserProfile, User] | None

Reads a UserProfile object from the database.

Parameters:

username – The User object’s username.

Returns:

A tuple containing the UserProfile object and the User object in the database with the given username. If either the UserProfile object or the User object can’t be found, we return None.

core.crud.update_user_profile(*, username: str, email_verified: bool, photo_url: str, display_name: str, provider: str) tuple[UserProfile, User] | None

Updates a UserProfile object in the database.

Parameters:
  • username – The User object’s username.

  • email_verified – Whether the user’s email has been verified.

  • photo_url – A URL for the user’s profile picture.

  • display_name – The user’s display name.

  • provider – The method used to log the user in, e.g., Google.

Returns:

A tuple containing the newly updated UserProfile object and the User object in the database with the given username. If the UserProfile object or the User object doesn’t exist, we return None.

core.models

Houses database models for the core app.

class core.models.UserProfile(*args, **kwargs)

Extends the built-in Django User model with additional information.

exception DoesNotExist
exception MultipleObjectsReturned

core.urls

Configures URLs for the core app.

core.views

Provides views for the core app.

core.views.about(request: HttpRequest) HttpResponse

Returns the about page.

core.views.acknowledgements(request: HttpRequest) HttpResponse

Returns the acknowledgements page.

core.views.citing(request: HttpRequest) HttpResponse

Returns the citing page.

core.views.collaborators(request: HttpRequest) HttpResponse

Returns the collaborators page.

core.views.contact(request: HttpRequest) HttpResponse

Returns the contact page.

core.views.downloads(request: HttpRequest) HttpResponse

Returns the downloads page.

core.views.help_(request: HttpRequest) HttpResponse

Returns the help page.

core.views.home(request: HttpRequest) HttpResponse

Returns the home page.

The Firebase App

The firebase app houses code related to using Google’s Firebase service for authentication.

firebase.apps

Provides the configuration for the firebase app.

class firebase.apps.FirebaseConfig(app_name, app_module)

Configures the firebase app.

ready() None

Sets up the Firebase Admin SDK.

firebase.backends

Provides authentication backends for the firebase app.

class firebase.backends.FirebaseBackend

Enables authentication via Google’s Firebase authentication service.

authenticate(request: HttpRequest | None, **kwargs: Any) User | None

Authenticates the user based on the provided ID token.

Parameters:
  • request – The HttpRequest object.

  • kwargs – Keyword arguments containing id_token, the JSON Web Token that needs to be verified using the Firebase Admin SDK.

Returns:

The User object for the authenticated user or None if we were unable to authenticate the user.

get_user(user_id: str) User | None

Returns a user based on the provided user_id.

firebase.clients

Centralizes interactions with external data providers for the firebase app.

firebase.clients.get_token_info(id_token: str | None) dict | None

Returns the info from the ID token obtained from the frontend.

firebase.crud

Centralizes create, read, update, and delete logic for the firebase app.

firebase.crud.create_firebase_user(uid: str, email: str) User

Creates a Firebase User object in the database.

Parameters:
  • uid – The user ID from Firebase.

  • email – An email string, e.g., foo@bar.org.

Returns:

The User object in the database with the given uid. If the User object already exists in the database, that User object is returned.

firebase.crud.read_firebase_user(uid: str) User | None

Reads a Firebase User object from the database.

Parameters:

uid – The user ID from Firebase.

Returns:

The User object in the database with the given uid. If the User object doesn’t exist in the database, None is returned.

firebase.crud.update_firebase_user(uid: str, email: str) User | None

Updates a User object with information from Firebase.

Parameters:
  • uid – The user ID from Firebase.

  • email – An email string, e.g., foo@bar.org.

Returns:

The User object with updated information passed to the function. If the User object doesn’t exist in the database, None is returned.

firebase.urls

Configures URLs for the core app.

firebase.views

Provides views for the firebase app.

firebase.views.edit_profile(request: HttpRequest) HttpResponse

Returns the edit profile page for the user.

firebase.views.login_(request: HttpRequest) HttpResponse

Returns the login page.

firebase.views.logout_(request: HttpRequest) HttpResponse

Returns the home page after logging the user out.

firebase.views.signup(request: HttpRequest) HttpResponse

Returns the signup page.

firebase.views.verify(request: HttpRequest) JsonResponse

Verifies an ID token obtained from the OAuth provider.

Parameters:

request – The HttpRequest object.

Returns:

A JsonResponse object containing a boolean indicating whether the token is valid.

firebase.views.view_profile(request: HttpRequest) HttpResponse

Returns the view profile page for the user.

Code Conventions

This reference guide describes the code conventions we follow in developing the HCI. Lint rules enforce most of our conventions automatically, but there are still some conventions to be aware of.

Comments

Don’t write obvious comments. The image below shows what not to do.

A picture of a stop sign with another sign pointing to it with the text: "This is a stop sign"

Docstring Comments

When you’re reading code, whether the code is part of a module, class, or function, the question you usually ask yourself is: “What does this code do?” The answer to that question should be in the docstring.

The “top-level” docstring for a module, class, or function should almost always be something along the lines of:

  • “Provides a way to…”

  • “Enables the…”

  • “Configures a…”

TODO Comments

  • Try to avoid writing these “I’ll do it later” comments.

  • There are lint rules set up to prevent TODO comments, so you have to jump through some hoops to get them into the code base.

  • TODO comments must have an author.

  • TODO comments must be accompanied by a link to a GitHub issue.

Here’s an example:

# TODO(Liam): Fix the foo feature. Tracked in https://github.com/org/repo/issue/123.

Lint Ignore Comments

If you ignore a lint rule, you must provide a justification for doing so. Generally speaking, it’s better to just fix the problematic code.

Here’s an example:

from .base import (  # noqa: F401 (We don't care about unused imports in this context.)

Type Hint Ignore Comments

If you ignore type hints, you must provide a justification for doing so. Generally speaking, it’s better to just fix the problematic code.

Here’s an example:

service = FooService(client=client)  # pyright: ignore[reportArgumentType] (We are using a mock client for our test.)