supercontest.views.common

Utility functions for view preprocessors.

Much of this is logic surrounding the resolution of the requested values against logical inferences for unpassed values. Also - retaining values of current view during linkbuilding for other views in nav dropdowns.

Examples, for URL path params: Season, Week, League, Stats Scope.

Module Attributes

VIEW_CACHE_TTL

How long to keep views cached, by default.

Functions

resolve_league

Called by url_defaults, this converts requested values into final values before passing them to the route.

resolve_season

Called by url_defaults, this converts requested values into final values before passing them to the route.

resolve_stats_scope

Defaults to NFL.

resolve_week

Called by url_defaults, this converts requested values into final values before passing them to the route.

service_account_only

Route decorator to confirm that the caller is authorized as a service account.

url_defaults

URL defaults are established before the route is run.

url_value_preprocessor

And then the URL value preprocessors take those resolved values, removing them as args to the route and instead attributing them to the flask global request object, g.

supercontest.views.common.VIEW_CACHE_TTL = 60

How long to keep views cached, by default. This is set to a minute frequency to match the primary invalidator for views: scores changing.

supercontest.views.common.resolve_league(requested_league: int, resolved_season: int) int

Called by url_defaults, this converts requested values into final values before passing them to the route. If the user did not request a value, the default is set by url_defaults (not this function).

Parameters:
  • requested_league – The requested league.

  • resolved_season – The resolved season.

Returns:

The resolved league.

supercontest.views.common.resolve_season(requested_season: int) int

Called by url_defaults, this converts requested values into final values before passing them to the route. If the user did not request a value, the default is set by url_defaults (not this function).

Parameters:

requested_season – The requested season.

Returns:

The resolved season.

supercontest.views.common.resolve_stats_scope(requested_stats_scope: str) str

Defaults to NFL. Also checks for unrecognized values.

Parameters:

requested_stats_scope – Which scope the link wants.

Raises:

ValueError – If an unknown stats scope is passed.

Returns:

Resolved scope for the statistics view.

supercontest.views.common.resolve_week(requested_week: int, resolved_season: int) int

Called by url_defaults, this converts requested values into final values before passing them to the route. If the user did not request a value, the default is set by url_defaults (not this function).

Parameters:
  • requested_week – The requested week.

  • resolved_season – The resolved season.

Returns:

The resolved week.

Raises:

ValueError – If unable to resolve the week.

supercontest.views.common.service_account_only(func: Callable[[P], Response]) Callable[[P], Response]

Route decorator to confirm that the caller is authorized as a service account.

Parameters:

func – The decorated function.

Returns:

The wrapper function.

supercontest.views.common.url_defaults(endpoint: str, values: dict[str, Any], league: bool, week: bool, stats_scope: bool = False)

URL defaults are established before the route is run. There are many url_for() calls in the frontend, where we build links for all the nav tabs. When a page loads, it builds these links for all the other possible links, re-using as much of the current state as possible (i.e. if you’re on the 2018 paid leaderboard, and you click 2019, it remembers you were on the lb and were filtering to the paid league).

This simply pops off the values dict and replace the requested values with resolved values. Note that flask made the design decision of using a mutable values argument intentionally. You don’t redefine and return the defaulted values, you manipulate the input values dict directly.

Note also - the final resolved values for season and week are NOT the same as rhw current_season and current_week. It’s the page the user is visiting (you can visit old seasons and weeks that are not current).

season is always required by contest views (although can be “all”).

If values are not provided, -1 is used to indicate null (for the resolvers above) for integers. For strings, it’s an emptry string.

Values of 0 are used to indicate ALL. Eg league=0 means the free league, or all leagues. season=0 means all seasons, as on statistical views.

Parameters:
  • endpoint – The endpoint of the requested path that these params are defaulting for.

  • values – The flask values.

  • league – Whether or not league should be resolved with defaults.

  • week – Whether or not week should be resolved with defaults.

  • stats_scope – Whether or not the scope of a statistics view should be resolved.

Raises:

ValueError – If an invalid scope is passed for a stats view.

supercontest.views.common.url_value_preprocessor(values: dict[str, Any] | None, league: bool, week: bool, stats_scope: bool = False)

And then the URL value preprocessors take those resolved values, removing them as args to the route and instead attributing them to the flask global request object, g. This allows them to be used by views, templates, and javascript.

Values will pass through the flask converter attached to each argument again, so although the defaults have casted the values to ints, we must do so here again (from strings). None should be empty at this point, however, so we don’t have to default to avoid missing keys.

Again, season is always required by contest views, and is a prerequisite to either week or league.

The params attribute is instantiated in the app’s preprocessor. It is used for season, week, and league - which values to “retain” when creating the links in the navbar dropdowns.

Parameters:
  • values – The flask values.

  • league – Whether or not league should be attributed to g.

  • week – Whether or not week should be attributed to g.

  • stats_scope – Whether or not the scope of a statistics view should be added to g.

Raises:

ValueError – If the flask values are empty (after my defaults and resolvers).