Skip to content

Instantly share code, notes, and snippets.

View lyzadanger's full-sized avatar

Lyza Gardner lyzadanger

View GitHub Profile
lyzadanger /
Last active July 21, 2021 12:04
Hypothesis Engineering Values

Hypothesis Engineering Values

These values:

  • Capture foundational components of the technical ethos we want to cultivate at Hypothesis
  • Describe our current culture—but are also aspirational
  • Are not inflexible absolutes, nor instructive how-tos
  • Should help start conversations, not end them
  • Set a high bar, and should keep us stretching and improving
lyzadanger / Buttons.js
Created February 19, 2021 14:24
POC of Button component organization
import classnames from 'classnames';
import { SvgIcon } from '@hypothesis/frontend-shared';
* @typedef ButtonProps
* @prop {Object} [children]
* @prop {string} [icon] - name of `SvgIcon` to render in the button
* @prop {'left'|'right'} [iconPosition] - Icon positioned to left or to
* right of button text
lyzadanger /
Last active October 17, 2018 14:10
Thinking about group identifiers...

After a brief jaunt through code and a think, I think I would summarize my reluctance to try to solve the client-determined identifier need for groups using pubid as follows. This doesn’t touch on the authorization or invite bits involved with pubid, just some high-level things.

I don’t know if this is deep enough to claim that I’ve looked at how hard it would be to update pubid in all the various places, but I realize my argument stands even if group.pubid were easy to modify. I feel like it inherently does something else than the notion we’re after here. Here are my thoughts!

  • One of the current core things about pubids is that they are known to be unique for a resource across all of our data. This is reflected in their use to identify a single resource in 17 different routes in our application at present.
  • However, our need for a client-determined identifier needs to enforce uniqueness per authority — the same identifier could be reused in multiple authorities. I believe this to be a de
lyzadanger /
Created September 6, 2018 18:19
Authentication and Authorization as it pertains to LMS-relevant API endpoints

LMS-related endpoints: Authority, auth_clients, authentication, authorization, oh, my!

AuthClient and Auth’n Background

For most of our API endpoints, authentication is handled via token authentication. Every user has a unique API token (hint: you can find yours in the Settings (gear) -> Developer section from your home/activity page on h), so by sending a given API token in an Authorization: Bearer… HTTP header, an API request may be authenticated as the user who that token belongs to. Thus, an API client may retrieve groups for a given user or post an annotation as a given user. One specific user at a time.

But we also have a small set of endpoints that are only accessible with a different kind of authentication mechanism, which we call auth_client. auth_clients are special and more powerful and different: instead of being tied to a user, they are tied to an authority. This allows us to grant special privileges to known entities such that they can take actions on the set of users and r

lyzadanger /
Last active March 27, 2018 15:30
Spike: Translate groups API response to structure by organizations

A little spike demonstrating how the client might go about transforming the groups response into one organized by organization for the purposes of display in the UI.

The data here represents the current structure of the groups API response with the addition of minimal ("expanded") organization objects—presumably this would be analogous to what is available to components through groups.all().

The code does not mutate the original groups data.

lyzadanger /
Last active March 26, 2018 13:50
H API: Organizations : Groups

What we’re trying to accomplish:

Make it possible for the client to show organization icons (logo) and, at some point in the near future, organization names in the drop-down list of groups available to a user at a particular URI.

This discussion centers around how to make that possible from the API-endpoint perspective, based on what is in place now and what we know now.

What we have now


lyzadanger /
Created March 6, 2018 21:42
Evaluating the Removal of the JoinableBy access flag on the Group Model

Please note: This is entirely a technical discussion. The actual behavior of groups, per requirements, will not be affected by this

Good news (I think!)! Excluding migrations and tests, the only references to joinableBy in the codebase are:

  • The model itself
  • The group service in its create* methods
  • h.db’s __init__ where the world group is created (once) with a joinableBy of None
  • h.views.activity in one or two spots that I think Sheetal is removing as I type this

Other group-related services and views don’t give a hoot about joinableBy and I’d argue, neither should we. Removing it would simplify the “group type” matrix and relieve confusion about what “joining” actually means. There’s nothing in our data model that actually prevents a membership relationship from being created, and the fact that the creator is immediately added as a member to a new restricted group “violates” the notion of joinableBy = None anyway, in some ways.

lyzadanger /
Created February 13, 2018 14:46
Sub-classed Presenter?
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
class GroupJSONPresenter(object):
"""Present a group in the JSON format returned by API requests."""
def __init__(self, group, route_url=None): = group
lyzadanger /
Created February 8, 2018 17:02
Quick sketch of plausible surface of `ListGroupsService` service
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
class ListGroupsService(object):
A service for providing filtered lists of groups.
lyzadanger /
Created January 25, 2018 17:16
High Level Groups API Approach Ideas

What we have now

GET /profile

Returns a profile object that contains, among other things, a groups property, an Array of objects; that part of the schema looks like:

    "groups": {
      "type": "array",
 "items": {