reddit_edgecontext

When a user initiates a request, only the service at the “edge” is directly talking to them. Baseplate provides for data that is automatically propagated from service to service so that services far from the user can know about the client too. This library describes the fields of that data.

To set the library up, create an EdgeContextFactory and pass it to the Baseplate.py framework integration you’re using:

from baseplate import Baseplate
from baseplate.lib.secrets import secrets_store_from_config
from reddit_edgecontext import EdgeContextFactory


def make_processor(app_config):
    secrets = secrets_store_from_config(app_config, timeout=60)
    edgecontext_factory = EdgeContextFactory(secrets)

    # pass edgecontext_factory to your framework's integration
    # for Thrift: baseplate.frameworks.thrift.baseplateify_processor
    # for Pyramid: baseplate.frameworks.pyramid.BaseplateConfigurator

Once that’s done, you can access the data in the edge context by using the edge_context attribute on the request object:

def my_view(request):
    return f"Hi {request.edge_context.user.id}!"

See below for all the fields available in the edge context payload.

The edge context payload

class reddit_edgecontext.EdgeContext(authn_token_validator, header)[source]

Contextual information about the initial request to an edge service.

Once the EdgeContextFactory is set up, an instance of this object will be available at request.edge_context.

event_fields()[source]

Return fields to be added to events.

Return type

Dict[str, Any]

user()[source]

User object for the current context.

oauth_client()[source]

OAuthClient object for the current context.

device()[source]

Device object for the current context.

session()[source]

Session object for the current context.

service()[source]

Service object for the current context.

origin_service()[source]

Origin object for the current context.

geolocation()[source]

Geolocation object for the current context.

request_id()[source]

RequestId object for the current context.

locale()[source]

Locale object for the current context.

attach_context(context)[source]

Attach this to the provided RequestContext.

Parameters

context (RequestContext) – request context to attach this to

Return type

None

class reddit_edgecontext.User(authentication_token: AuthenticationToken, loid_: str, cookie_created_ms: int)[source]

Wrapper for the user values in AuthenticationToken and the LoId cookie.

property authentication_token

The authentication provided for the request.

property loid_

The internal LoID associated with the request, if applicable.

property cookie_created_ms

When the authentication cookie was created, if applicable.

property id

Return the authenticated account_id for the current User.

Raises

NoAuthenticationError if there was no authentication token, it was invalid, or the subject is not an account.

Return type

Optional[str]

property is_logged_in

Return if the User has a valid, authenticated id.

Return type

bool

property roles

Return the authenticated roles for the current User.

Raises

NoAuthenticationError if there was no authentication token or it was invalid

Return type

Set[str]

has_role(role)[source]

Return if the authenticated user has the specified role.

Parameters

client_types – Case-insensitive sequence role name to check.

Raises

NoAuthenticationError if there was no authentication token defined for the current context

Return type

bool

event_fields()[source]

Return fields to be added to events.

Return type

Dict[str, Any]

property loid

The LoID associated with the request, if applicable.

Return type

str

class reddit_edgecontext.OAuthClient(authentication_token: AuthenticationToken)[source]

Wrapper for the OAuth2 client values in AuthenticationToken.

property authentication_token

The authentication token for this request.

property id

Return the authenticated id for the current client.

Raises

NoAuthenticationError if there was no authentication token defined for the current context

Return type

Optional[str]

is_type(*client_types)[source]

Return if the authenticated client type is one of the given types.

When checking the type of the current OauthClient, you should check that the type “is” one of the allowed types rather than checking that it “is not” a disallowed type.

For example:

if oauth_client.is_type("third_party"):
    ...

not:

if not oauth_client.is_type("first_party"):
    ...
Parameters

client_types (str) – Case-insensitive sequence of client type names that you want to check.

Raises

NoAuthenticationError if there was no authentication token defined for the current context

Return type

bool

event_fields()[source]

Return fields to be added to events.

Return type

Dict[str, Any]

class reddit_edgecontext.Session(id: str)[source]

Wrapper for the session values in the EdgeContext.

property id

The ID of the session this request is part of.

class reddit_edgecontext.Service(authentication_token: AuthenticationToken)[source]

Wrapper for the Service values in AuthenticationToken.

property authentication_token

The authentication token for this request.

property name

Return the authenticated service name.

Type

name string or None if context authentication is invalid

Raises

NoAuthenticationError if there was no authentication token, it was invalid, or the subject is not a service.

Return type

str

class reddit_edgecontext.AuthenticationToken[source]

Information about the authenticated user.

EdgeContext provides high-level helpers for extracting data from authentication tokens. Use those instead of direct access through this class.

property subject

Return the raw subject that is authenticated.

Return type

Optional[str]

The factory

class reddit_edgecontext.EdgeContextFactory(secrets)[source]

Factory for creating EdgeContext objects.

Every application should set one of these up. Edge services that talk directly with clients should use new() directly. For internal services, pass the object off to Baseplate’s framework integration (Thrift/Pyramid) for automatic use.

Parameters

secrets (baseplate.lib.secrets.SecretsStore) – A configured secrets store.

new(authentication_token=None, loid_id=None, loid_created_ms=None, session_id=None, device_id=None, origin_service_name=None, country_code=None, request_id=None, locale_code=None)[source]

Return a new EdgeContext object made from scratch.

Services at the edge that communicate directly with clients should use this to pass on the information they get to downstream services. They can then use this information to check authentication, run experiments, etc.

To use this, create and attach the context early in your request flow:

auth_cookie = request.cookies["authentication"]
token = request.authentication_service.authenticate_cookie(cookie)
loid = parse_loid(request.cookies["loid"])
session = parse_session(request.cookies["session"])
device_id = request.headers["x-device-id"]
request_id = request.headers["x-request-id']

edge_context = self.edgecontext_factory.new(
    authentication_token=token,
    loid_id=loid.id,
    loid_created_ms=loid.created,
    session_id=session.id,
    device_id=device_id,
    request_id=request_id,
)
edge_context.attach_context(request)
Parameters
  • authentication_token (Optional[str]) – A raw authentication token as returned by the authentication service.

  • loid_id (Optional[str]) – ID for the current LoID in fullname format.

  • loid_created_ms (Optional[int]) – Epoch milliseconds when the current LoID cookie was created.

  • session_id (Optional[str]) – ID for the current session cookie.

  • device_id (Optional[str]) – ID for the device where the request originated from.

  • origin_service_name (Optional[str]) – Name for the “origin” service handling the request from the client.

  • country_code (Optional[str]) – two-character ISO 3166-1 country code where the request orginated from.

  • request_id (Optional[str]) – The human readable form of the unique id assigned to the underlying request that this EdgeContext represents.

  • locale_code (Optional[str]) – IETF language tag representing the preferred locale for the client.

Return type

EdgeContext

from_upstream(edge_header)[source]

Create and return an EdgeContext from an upstream header.

This is generally used internally to Baseplate by framework integrations that automatically pick up context from inbound requests.

Parameters

edge_header (Optional[bytes]) – Raw payload of Edge-Request header from upstream service.

Return type

EdgeContext

Errors

exception reddit_edgecontext.NoAuthenticationError[source]

Raised when trying to use an invalid or missing authentication token.