common

This is a collection of utilities used by multiple apps in our ecosystem.

CLI Utilities

This file contains miscellaneous utilities for command-line interfaces.

common.cli_utils.pretty_print(emoji: str, msg: str)[source]

Pretty prints a message.

Parameters
  • emoji (str) – the emoji to wrap the message in

  • msg (str) – the message to wrap with the emoji

Course Configuration

This file contains various methods that can help identify a course as well as determine the level of access a user (logged in with Okpy) has to the course.

common.course_config.get_course(domain=None)[source]

Gets the course code of the course that owns the current domain, using get_domain().

Parameters

domain (str) – the domain name in question, inferred using get_domain() if omitted

Returns

the course code, such as “cs61a”

common.course_config.get_domain()[source]

Gets the domain that this request is being made on.

Returns

the domain name, based on request headers

common.course_config.get_endpoint(course=None)[source]

Gets a course’s most recent Okpy endpoint, typically the current semester’s, using get_endpoint().

Parameters

course (str) – the course code, such as “cs61a”, inferred using get_course() if omitted

Returns

the Okpy endpoint, such as “cal/cs61a/sp21”

common.course_config.get_course_id(course=None)[source]

Gets a course’s most recent Okpy course ID, typically the current semester’s, using get_endpoint_id().

Parameters

course (str) – the course code, such as “cs61a”, inferred using get_course() if omitted

Returns

the Okpy endpoint, such as 707

common.course_config.is_admin(email, course=None)[source]

Returns whether or not an email address belongs to an admin for the given course, using is_admin().

Parameters
  • email (str) – the email address in question

  • course (str) – the course code, such as “cs61a”, inferred using get_course() if omitted

Returns

True if the user is an admin, False otherwise

common.course_config.is_admin_token(access_token, course=None)[source]

Returns whether or not an Okpy access token belongs to an admin for the given course.

Parameters
  • access_token (str) – the Okpy access token in question

  • course (str) – the course code, such as “cs61a”, inferred using get_course() if omitted

Returns

True if the user is an admin, False otherwise

common.course_config.format_coursecode(course)[source]

Formats a course code is a pretty way, separating the department from the course number.

Parameters

course (str) – the course code, such as “cs61a”

Returns

prettified course code, such as “CS 61A”

Database Interface

This file contains the logic for interfacing with the 61A database backend, or for interfacing with a local database if you don’t have access to the production database (or are developing something volatile).

By default, this code assumes that you are running locally without access to the production database. As such, the default action is to create a local app.db if an application requests to use a database. In production, the environment variable DATABASE_URL is used to connect to the production database.

To develop on the production database, use ENV=DEV_ON_PROD and pass in DATABASE_PW=password, where password is the SQL password for the buildserver user. Ask a Head of Software if you need access to this.

Note

Developing on production requires the Cloud SQL Proxy. Follow the instructions at https://cloud.google.com/sql/docs/mysql/sql-proxy to install the proxy in the root directory of the repository.

common.db.connect_db(*, retries=3)[source]

Create a context that uses a connection to the current database.

Parameters

retries (int) – the number of times to try connecting to the database

Yields

a function with parameters (query: str, args: List[str] = []), where the query_str should use %s to represent sequential arguments in the args_list

Example usage

with connect_db() as db:
    db("INSERT INTO animals VALUES %s", ["cat"])
    output = db("SELECT * FROM animals")
common.db.transaction_db()[source]

Create a context that performs a transaction on current database.

The difference between this and connect_db() is that this method batches queries in a transaction, and only runs them once the context is abandoned.

Yields

a function with parameters (query: str, args: List[str] = []), where the query_str should use %s to represent sequential arguments in the args_list

Example usage

with transaction_db() as db:
    db("INSERT INTO animals VALUES %s", ["cat"])
    output = db("SELECT * FROM animals")

Hash Utilities

This file contains some utilities for hashing data.

class common.hash_utils.HashState[source]

Utility class for hashing data. Uses hashlib.md5.

Example usage

>>> state = HashState()
>>> state.update(b"hello world")
>>> state.state()
'fe0cf2fe0d7cb366190a4a80af973909'
update(data: bytes)[source]

Append some data to the current state.

Parameters

data (bytes) – the data to append

Returns

self

record(*args)[source]

Append multiple pieces of data to the current state.

Parameters

args (*str) – the data to append

Returns

self

state()[source]

Get a hex digest of the current state.

Returns

the hex digest of the current state

HTML Helpers

This file contains some helpful HTML formatting tools for a standard frontend.

Caution

Do not use this library for student-facing apps, as it is vulnerable to XSS. Only use it for quick staff-only frontends.

common.html.make_row(content, target, action='Remove')[source]

Create a form with value content that POSTs to target when the button labeled action is pressed.

Parameters
  • content (str - HTML) – the body of the form

  • target (str) – the URL to POST to

  • action (str) – the label of the submit button

Returns

a string representing the HTML form

common.html.html(out)[source]

Adds some styling to the HTML body out.

Specifically, adds a header of the form “61A App Name” and prepends the SPCSS stylesheet (https://cdn.jsdelivr.net/npm/spcss@0.5.0).

Parameters

out (str) – the original HTML

Returns

a string representing the stylized HTML.

common.html.error(out)[source]

Formats a page representing an error.

Specifically, preformats the error message and adds a red header, with some instructions on who to contact for help.

Parameters

out (str) – the error message

Returns

a string representing the stylized HTML.

Job Routing

This file contains a decorator utility to add URL rules for recurring actions.

common.jobs.job(app: flask.Flask, endpoint)[source]

Adds a URL rule for a recurring job at /jobs/<endpoint>.

Parameters
  • app (Flask) – the app the method belongs to

  • endpoint (str) – the endpoint to route to the method

Returns

a decorator which can be applied to a function to bind it to /jobs/<endpoint>

OAuth Client

This file contains some utilities for Okpy OAuth communication.

common.oauth_client.get_user()[source]

Get some information on the currently logged in user.

Returns

a dictionary representing user data (see here for an example)

common.oauth_client.is_logged_in()[source]

Get whether the current user is logged into the current session.

Returns

True if the user is logged in, False otherwise

common.oauth_client.is_staff(course)[source]

Get whether the current user is enrolled as staff, instructor, or grader for course.

Parameters

course (str) – the course code to check

Returns

True if the user is on staff, False otherwise

common.oauth_client.is_enrolled(course, *, roles=None)[source]

Check whether the current user is enrolled as any of the roles for course.

Parameters
  • course (str) – the course code to check

  • roles (list-like) – the roles to check for the user

Returns

True if the user is any of roles, False otherwise

common.oauth_client.login()[source]

Store the current URL as the redirect target on success, then redirect to the login endpoint for the current app.

Returns

a redirect() to the login endpoint for the current Flask app.

common.oauth_client.create_oauth_client(app: flask.Flask, consumer_key, secret_key=None, success_callback=None, return_response=None)[source]

Add Okpy OAuth for consumer_key to the current app.

Specifically, adds an endpoint /oauth/login that redirects to the Okpy login process, /oauth/authorized that receives the successful result of authentication, /api/user that acts as a test endpoint, and a tokengetter().

Parameters
  • app (Flask) – the app to add OAuth endpoints to

  • consumer_key (str) – the OAuth client consumer key

  • secret_key (str) – the OAuth client secret, inferred using get_secret() if omitted

  • success_callback (func) – an optional function to call upon login

  • return_response (func) – an optional function to send the OAuth response to

Secrets

This file contains some utilities to create/get secrets for an app.

common.secrets.get_master_secret()[source]

Get APP_MASTER_SECRET from the environment using os.getenv().

Returns

the master secret

common.secrets.new_secret()[source]

Get a new 64-character secret, with each character a random uppercase letter or a digit.

Returns

the randomly-generated secret

Shell Utilities

This file contains some utilities to communicate with a shell.

common.shell_utils.sh(*args, env={}, capture_output=False, stream_output=False, quiet=False, shell=False, cwd=None, inherit_env=True)[source]

Run a command on the command-line and optionally return output.

Parameters
  • args (*str) – a variable number of arguments representing the command to pass into Popen or run()

  • env (dict) – environment variables to set up the command environment with

  • capture_output (bool) – a flag to return output from the command; uses Popen

  • stream_output (bool) – a flag to stream output from the command; uses run()

  • quiet (bool) – a flag to run the command quietly; suppressed printed output

  • shell (bool) – a flag to run the command in a full shell environment

  • cwd (str) – the working directory to run the command in; current directory is used if omitted

  • inherit_env (bool) – a flag to include os.environ in the environment; True by default

Warning

Only one of capture_output and stream_output can be True.

url_for

This file creates a new url_for method to improve upon the default url_for().

common.url_for.get_host()str[source]

Get the current host URL from request headers.

Returns

X-Forwarded-For-Host or Host

Note

61A apps use X-Forwarded-For-Host, which is not a standard header, for legacy reasons. This may be fixed in the future, but not for now.

common.url_for.url_for(*args, **kwargs)str[source]

Return the absolute URL target for the requested method.

Uses url_for() to get the relative endpoint, then prepends the host from get_host() to the URL to make it absolute.

All arguments are passed directly into url_for().

Returns

the absolute target URL