src package

Submodules

src.app module

class src.app.Notification(data, expire_time, clients)[source]

Bases: object

Parameters:
  • data (dict)

  • expire_time (float)

  • clients (list[str])

class src.app.TestingInfo(year, event_key, infile)[source]

Bases: object

Parameters:
  • year (str)

  • event_key (str)

  • infile (Path)

apply(initial_config)[source]

Configues the app config data in memory to the testing info input

src.app.append_lines()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: [‘data’]

Appends a series of csv lines to the input data based off of the file sent via request.files

Complies with the restrict append level.

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.append_lines_nofile(lines_to_write, sending=False)[source]

Appends lines_to_write to the input csv and reprocesses the data.

This will emit a notification if restrict append level is 1

Parameters:
  • lines_to_write (list[str])

  • sending (bool)

Return type:

None

src.app.apply_change(idx)[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

For restrict append level 2: applies the idx’th queued append

Parameters:

idx (int)

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]] | tuple[~typing.Literal[‘Invalid request’], ~typing.Literal[400]]

src.app.auto_scout_simple()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns the simple auton scounting html page

Return type:

str

src.app.auton_scout()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

returns the html page for auton scouting

Return type:

str

src.app.calc_team_score()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Calculates the aggregate score based on the OPRs of the three teams

Return type:

Response

src.app.changes()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Renders page listing changes to apply for restrict append level 2

Return type:

str

src.app.clear_datain()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

deletes the input data spreadsheet

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.clear_db()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

deletes the output database

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.compile_scouting_dashboard(url)[source]

Uses jinja templating to create dashboard jsons for provisioning that cast all of the number fields to numbers

Parameters:

url (str)

Return type:

None

src.app.consume_tba_webhook()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [‘X-TBA-HMAC’], Body Keys: [‘message_type’], Files: []

Handles tba webhook authentication and resolution

Return type:

tuple[Literal[‘’], ~typing.Literal[401]] | tuple[~typing.Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.create_account()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [], Files: []

page allowing for the creation of new accounts

Return type:

tuple[Literal[‘Account created’], ~typing.Literal[200]] | str | tuple[~typing.Literal[‘Error: restricted’], ~typing.Literal[403]]

src.app.create_login()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘un’, ‘pwd’, ‘isadmin’], Files: []

Creates a new login with the specified parameters

Return type:

tuple[Literal[‘Success’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.delete_account()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘uid’], Files: []

Allows the user to delete users

Return type:

tuple[Literal[‘Account deleted.’], ~typing.Literal[200]] | tuple[~typing.Literal[‘Deletion prohibited’], ~typing.Literal[403]]

src.app.delete_change(idx)[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

For restrict append level 2: drops the idx’th queued append

Parameters:

idx (int)

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[~typing.Literal[‘Invalid request’], ~typing.Literal[400]]

src.app.delete_file()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘filepath’], Files: []

Handles deleting files for the file explorer

Return type:

tuple[Literal[‘Not allowed in local testing’], ~typing.Literal[401]] | tuple[~typing.Literal[‘Success’], ~typing.Literal[200]] | tuple[~typing.Literal[‘Error, path does not exist’], ~typing.Literal[400]]

src.app.delete_lines()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘sending’], Body Keys: [‘lines’, ‘si’, ‘mn’], Files: []

For restrict append level 1: deletes the already applied append cooresponding to the input json’s lines field using rm_row_hash()

Return type:

tuple[Literal[‘’], ~typing.Literal[200]]

src.app.dload()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [‘file’], Body Keys: [], Files: []

Sends a stream using the stream helper for the requested file to download it

Return type:

tuple[Literal[‘File not found.’], ~typing.Literal[404]] | ~werkzeug.wrappers.response.Response

async src.app.do_data_processing()[source]

Runs the process and postprocess routines

Return type:

None

src.app.download_folder()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [‘path’], Body Keys: [], Files: []

Download a data folder, such as the notes or photos directories, as a zip

Return type:

Response

src.app.edit_app_conf_page()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns a monaco page for editing the app configuration

Return type:

str

src.app.edit_file()[source]

Schema

Access: ADMIN, UrlParams: [‘filepath’], Headers: [], Body Keys: [], Files: []

Returns a monaco page for editing the file specified by the filepath urlparam

Return type:

str | tuple[Literal[‘Error, path does not exist’], ~typing.Literal[400]]

src.app.edit_yaml()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Renders the editing template for web editing the field-config.yaml file

Return type:

str

src.app.ensure_untracked_dirs()[source]

Ensures that the upload and output directories exist.

It is wrapped in a function because these directories can change at runtime.

Return type:

None

src.app.events_from_team()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

returns a list of events from the inputted team

Return type:

Response

src.app.explore()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns a web file tree for browsing files

Return type:

str

src.app.get_app_config()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns the app configuration for the editor at /edit-app-conf to read

Return type:

Response

src.app.get_current_event()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

returns the event key currently loaded into the app

Return type:

str | Any

src.app.get_fa_icon(name)[source]

Gets the font-awesome icon cooresponding to the file extension

Parameters:

name (str)

Return type:

str

src.app.get_log()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘log’], Body Keys: [], Files: []

Returns the contents of the specified log

Return type:

tuple[str, Literal[200]] | tuple[str, ~typing.Literal[400]]

src.app.get_note_tables()[source]

Schema

Access: OPEN, UrlParams: [‘team’], Headers: [], Body Keys: [], Files: []

returns a tabulated dictionary of each scouters’ notes for a team

Return type:

Response

src.app.get_notes()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [‘match’, ‘team’, ‘pre’], Body Keys: [], Files: []

returns the text content of the specified note

Return type:

str | tuple[Literal[‘File not found’], ~typing.Literal[400]]

src.app.get_picklist()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns a dictionary representing the picklist for the specified user

Return type:

Response | tuple[Literal[‘File not found’], ~typing.Literal[400]]

src.app.get_tba_key()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

returns the current TBA api key and whether or not it is good

Return type:

Response

src.app.get_team_indicies()[source]

Schema

Access: OPEN, UrlParams: [‘team’], Headers: [], Body Keys: [], Files: []

gets the list of indicies (a range) of the valid photos for a team, ie. [0, 1] for a team with 2 photos

Return type:

Response | tuple[str, Literal[500]] | tuple[~typing.Literal[‘Error: invalid request’], ~typing.Literal[400]]

src.app.get_team_pics()[source]

Schema

Access: OPEN, UrlParams: [‘team’], Headers: [], Body Keys: [], Files: []

Return the uploaded picture cooresponding to the team given in the ?team urlparam

Return type:

Response | tuple[Literal[‘Error, team picture not found’], ~typing.Literal[400]] | tuple[str, ~typing.Literal[500]] | tuple[~typing.Literal[‘Error: invalid request’], ~typing.Literal[400]]

src.app.get_user_display()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [‘id’], Body Keys: [], Files: []

Returns the pill display for a user

Return type:

str

src.app.handle_401(e)[source]

Handles a 401 (not logged in) error

Parameters:

e (Exception)

Return type:

str | tuple[str, Literal[401]]

src.app.handle_403(e)[source]

Handles a 403 (page restricted) error

Parameters:

e (Exception)

Return type:

str | tuple[Literal[‘Error: restricted’], ~typing.Literal[403]]

src.app.handle_404(e)[source]

Custom 404 (page not found) handler

Parameters:

e (Exception)

Return type:

str | tuple[Literal[‘Error: page not found’], ~typing.Literal[404]]

src.app.handle_exception(e)[source]

Dampens the app’s explosion

Parameters:

e (Exception)

Return type:

str | tuple[str, Literal[500]]

src.app.handle_mesh_line(message)[source]

This function is a consumer for a meshtastic message (line of csv) and will append it to the csv much like append_lines()

Parameters:

message (str)

Return type:

None

src.app.handle_tba_webhook(notification_json)[source]

Consumes a tba webhook push request and performes actions based on message_type.

  • match_score: runs peridoc fetch

  • schedule_updated: loads event data

  • ping: sends notification

  • broadcast: sends notification

  • verification: sends notification

Parameters:

notification_json (dict)

Return type:

None

src.app.health()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Health check, primarily so that QRScout can know its url is correct

Return type:

tuple[Literal[‘No event data’], ~typing.Literal[200]] | tuple[~typing.Literal[‘Sentinel is watching’], ~typing.Literal[200]]

src.app.jobs()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns a dictionary of active Events running from the processor

Return type:

Response

src.app.load_event_data()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘event’], Body Keys: [], Files: []

loads in the data for the specified event

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]] | tuple[~typing.Literal[‘Invalid event key’], ~typing.Literal[400]]

src.app.log_request()[source]

logs the method and path of the request

Return type:

None

src.app.login()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Sends login page and validates login un/pw

Return type:

tuple[Literal[‘Login Successful’], ~typing.Literal[200]] | tuple[~typing.Literal[‘Invalid Credentials’], ~typing.Literal[401]] | str

src.app.login_override()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [‘key’], Files: []

Handles the login override on the login screen

Return type:

tuple[Literal[‘Login Override Successful’], ~typing.Literal[200]] | tuple[~typing.Literal[‘Invalid Credentials’], ~typing.Literal[401]]

src.app.logout()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Logs out the user

Return type:

Response

src.app.main()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Renders homepage html template, passes the public key to the client to bind the service worker

Return type:

str

src.app.make_comment()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Handles making a comment on a picklist team

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[~typing.Literal[‘File not found’], ~typing.Literal[404]]

src.app.manage_accounts()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

page for viewing and deleting accounts

Return type:

str

src.app.matches_in_comp()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

returns the list of matches in the currently loaded competition

Return type:

Response

src.app.mesh_listen()[source]

Binds handle_mesh_line() to the meshtastic port (listens for meshages)

Return type:

None

src.app.multi_view()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns an html page for comparing teams with grafana iframes

Return type:

str

src.app.n3()[source]

Schema

Access: OPEN, UrlParams: [‘mkey’], Headers: [], Body Keys: [], Files: []

Returns the next app.config["NEXT_N_MATCHES_NUMBER"] (currently 3, hence the name) matches after ?mkey that contain ?team

where ?x is the url parameter named x

Return type:

Response

src.app.notify_q()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘X-Cid’], Body Keys: [], Files: []

pop the queue of notifications for frontend to consume and notify the user

Return type:

Response | tuple[Literal[‘Error, invalid cid’], ~typing.Literal[400]] | tuple[~typing.Literal[‘No notifications in queue’], ~typing.Literal[204]]

src.app.percent()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Rest passthrough for other-metrics.json, named percent because its current data is the percentage of teams scouted.

Return type:

Response | str

src.app.picklist()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns a page to make a picklist

Return type:

str

src.app.pit_scout()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns the pit scouting html page

Return type:

str

src.app.read_log()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns a readonly monaco page for viewing the specified log

Return type:

str

src.app.reload_js()[source]

Updates the copy of the other-metrics.json file in memory (used for percent() endpoint) to use the newest file

Return type:

None

src.app.rename_file()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘old’, ‘new’], Files: []

Handles renaming of files for the file explorer

Return type:

tuple[Literal[‘Not allowed in local testing’], ~typing.Literal[401]] | tuple[~typing.Literal[‘Success’], ~typing.Literal[200]] | tuple[~typing.Literal[‘Error, path does not exist’], ~typing.Literal[400]]

src.app.render_template_style(template, **context)[source]

Renders the input template with the given context and also the accent and text colors of the app

Parameters:
  • template (str | Template | list[str | Template])

  • context (Any)

Return type:

str

src.app.reprocess()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Reprocesses the data with no additional inputs; for testing or manual csv changes

Return type:

tuple[Literal[‘Data reloaded.’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.reset_dash()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

recompiles the grafana dashboards based on the templates

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.restart()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Kills the app for restarting with always-restart in docker compose

Return type:

NoReturn

src.app.rm_row_hash(hashes)[source]

Deletes rows of data from the input csv by matching their hashes with the ones provided and then reprocesses the data

Parameters:

hashes (list[str])

Return type:

None

src.app.run_async_task(coro)[source]

Runs a coroutine as a sepearte asyncronous thread

Return type:

None

src.app.run_process()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘process’], Files: []

runs the process specified by process in the request body.

  • load_event_data: loads event data

  • perform_periodic_calls: performs periodic calls

  • do_data_processing: performs data processing

Return type:

tuple[Literal[‘Error, invalid process requested’], ~typing.Literal[400]] | tuple[~typing.Literal[‘Process requested’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.save_app_config()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Consumes an app configuration json, saves it, and applies it

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.save_auto(filestorage, match)[source]

saves a picture generated from auton scouting

Parameters:

match (str)

Return type:

None

src.app.save_auto_simple()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Handles the submission of the simple auton scouting form

Return type:

tuple[Literal[‘Success’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.save_file()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘code’, ‘path’], Files: []

Saves the file

Return type:

Response

src.app.save_notes()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [‘team’, ‘data’, ‘match’, ‘pre’], Files: []

saves scouter notes for a team

Return type:

Response

src.app.save_photo(filestorage, team)[source]

saves the given filestorage to PHOTO_STORAGE/{team}.ext where ext is the extension of filestorage

Parameters:

team (str)

Return type:

None

src.app.save_picklist()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Handles saving a picklist

Return type:

tuple[Literal[‘Success’], ~typing.Literal[200]]

src.app.save_pit()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Handles the submission of the pit scouting form

Return type:

tuple[Literal[‘Success’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.save_yaml()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘code’], Files: []

A file consumer that saves the field-config.yaml file during web editing

Return type:

Response

src.app.send_change_notification(lines=None)[source]

Sends a notification.

If ‘lines’ is None, this will send a notification letting the user know that new changes are avaliable (restrict append level is 2) with a link to changes().

If ‘lines’ is not None, restrict append level is assumed to be 1 and a new notification that’s body has lines and a link to remove lines from the input data will be sent.

Parameters:

lines (str | None)

Return type:

None

src.app.send_generic_notification(data)[source]

sends a notification with title/body/etc. specified by data. The icon is added by this function.

Parameters:

data (dict)

Return type:

None

src.app.send_sw()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Passthrough for the service worker so that the client can fetch it

Return type:

Response

src.app.set_creds()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘un’, ‘pwd’, ‘isadmin’], Files: []

Add or overwrite a login

Return type:

tuple[Literal[‘Success’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.set_tba_key()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘key’], Files: []

verifies the inputted api key sent via json[“key”], applies it and writes it to tba.txt, and reprocesses data

Return type:

tuple[Literal[‘Bad TBA key’], ~typing.Literal[400]] | tuple[~typing.Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.set_tba_whook_key()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [‘key’], Files: []

Sets the tba webhook secret based of of the one specified in the TBA webhook registration on the account page

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.start_loop(loop)[source]

This function starts the main thread for running events

Parameters:

loop (AbstractEventLoop)

Return type:

None

src.app.take_notes()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

returns the html page for note taking

Return type:

str

src.app.teams_in_match()[source]

Schema

Access: LOGIN, UrlParams: [‘mkey’], Headers: [], Body Keys: [], Files: []

returns a list of the teams in the specified match

Return type:

Response | tuple[Literal[‘Error, match not in data’], ~typing.Literal[404]]

src.app.test_mesh()[source]

Schema

Access: ADMIN, UrlParams: [‘m’], Headers: [], Body Keys: [], Files: []

Debug endpoint to test the meshtastic listener without a mesh radio

Return type:

str

src.app.test_notification()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Sends a test notification to the server

Return type:

tuple[Literal[‘Sent’], ~typing.Literal[200]]

src.app.test_tba_key()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘key’], Body Keys: [], Files: []

tests whether or not the given TBA api key is valid, returning a string ‘true’ for good and ‘false’ for bad

Return type:

tuple[Literal[‘true’], ~typing.Literal[200]] | tuple[~typing.Literal[‘false’], ~typing.Literal[200]]

src.app.update_like()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [‘list’, ‘pick’, ‘team’, ‘like’], Body Keys: [], Files: []

Handles liking/disliking a picklist team

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[~typing.Literal[‘File not found’], ~typing.Literal[400]]

src.app.upload_auto()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘mkey’], Body Keys: [], Files: [‘photo’]

Saves a picture generated by the auton scouting

Return type:

tuple[Literal[‘Saved!’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]] | None

src.app.upload_file()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [], Body Keys: [], Files: [‘data’]

Overrides the current input data with an uploaded file from the frontend and reprocesses the data

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.upload_folder()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘folderPath’], Body Keys: [], Files: [‘data’]

Upload a zipped folder containing notes, photos, etc.

Note

Zipped folders may be too large to upload when the server is running on cloudflare, etc.

Return type:

tuple[Literal[‘Error, no selected file’], ~typing.Literal[400]] | tuple[~typing.Literal[‘Invalid Zip file’], ~typing.Literal[400]] | tuple[~typing.Literal[‘File uploaded successfully’], ~typing.Literal[200]]

src.app.upload_other_files()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘name’], Body Keys: [], Files: [‘data’]

Handles file uploading for dataout files such as pit scouting data

Return type:

tuple[Literal[‘’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]]

src.app.upload_photo()[source]

Schema

Access: ADMIN, UrlParams: [], Headers: [‘team’], Body Keys: [], Files: [‘photo’]

Save a photo for the cooresponding team

Return type:

tuple[Literal[‘Saved!’], ~typing.Literal[200]] | tuple[str, ~typing.Literal[500]] | None

src.app.view_file()[source]

Schema

Access: ADMIN, UrlParams: [‘filepath’], Headers: [], Body Keys: [], Files: []

Returns a stream of the file specified by ?filepath, primarily for viewing images

Return type:

Response | tuple[Literal[‘Error, path does not exist’], ~typing.Literal[400]]

src.app.view_picklist()[source]

Schema

Access: LOGIN, UrlParams: [‘list’], Headers: [], Body Keys: [], Files: []

Returns an html page to view a picklist and comment/rate teams

Return type:

str

src.app.view_picklists()[source]

Schema

Access: LOGIN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns an html page displaying all of the submitted picklists

Return type:

str

src.app.whoami()[source]

Schema

Access: OPEN, UrlParams: [], Headers: [], Body Keys: [], Files: []

Returns a dictionary specifying the logged_in status of the user, and un/id/isadmin if applicable

Return type:

Response

src.apputils module

class src.apputils.PathUtils[source]

Bases: object

class FileSet(origin_path)[source]

Bases: object

Parameters:

origin_path (Path)

relative_to_origin(*paths)[source]
Parameters:

paths (str | Path)

search(search_pattern, *subpath)[source]
Parameters:

search_pattern (str)

Return type:

Iterator[Path]

set_origin(origin_path)[source]
Parameters:

origin_path (Path)

file_set = <src.apputils.PathUtils.FileSet object>
grafana_dashboard_posix_root = '/var/lib/grafana/dashboards'
relative_to_origin(*paths)
Parameters:

paths (str | Path)

search(search_pattern, *subpath)
Parameters:

search_pattern (str)

Return type:

Iterator[Path]

class src.apputils.TBADataDynamic(ranks={}, copr={}, curr_oprs={})[source]

Bases: object

class src.apputils.TBADataStatic(teams=[], team_info={}, schedule={}, opr={})[source]

Bases: object

src.apputils.can_cast(x, _type)[source]
Parameters:
  • x (Any)

  • _type (type)

Return type:

bool

src.apputils.change_un_pwd_admin(current_secret_key, newun, newpwd)[source]

updates the username and password

Parameters:
  • current_secret_key (str)

  • newun (str)

  • newpwd (str)

Return type:

None

src.apputils.change_un_pwd_viewer(current_secret_key, newun, newpwd)[source]

updates the username and password

Parameters:
  • current_secret_key (str)

  • newun (str)

  • newpwd (str)

Return type:

None

src.apputils.clear_pictures()[source]
Return type:

None

src.apputils.data_in_exists()[source]

checks whether the data_in file exists for app based on its config

Return type:

bool

src.apputils.exception_format(e)[source]

Gets the stack frame where the exception ACTUALLY occured (deepest frame not in a dependecy)

Parameters:

e (Exception)

Return type:

str

src.apputils.generate_ssl_sign()[source]

useless?

Return type:

None

src.apputils.get_event_team_oprs(event_key, api_key)[source]
Return type:

dict[Any, Any] | Any

src.apputils.get_num_team_pics(team, photo_dir)[source]
Return type:

int

src.apputils.get_tasks_snapshot(loop=None)[source]

Returns a snapshot of all asyncio tasks without blocking. Can be called from synchronous code.

Return type:

dict

src.apputils.get_tba_coprs(event_key, api_key, config_data)[source]
Return type:

dict

src.apputils.get_tba_events(key, year, team)[source]
Return type:

list[dict]

src.apputils.get_tba_images(api_key, year, teams)[source]
Return type:

None

src.apputils.get_tba_opr(event_key, api_key, year, teams)[source]

returns a dictionary of each team to their cooresponding opr at their last competition

Return type:

dict

src.apputils.get_tba_ranks(event_key, api_key, teams)[source]

returns a dictionary mapping each team to a tuple of their rank and rps

Return type:

dict

src.apputils.has_internet()[source]

pings google for 10 seconds and returns whether it’s okay

Return type:

bool

src.apputils.invert_jeson(jeson)[source]
Parameters:

jeson (dict)

Return type:

dict

src.apputils.is_iterable(x)[source]
Parameters:

x (Any)

Return type:

bool

src.apputils.line_str_hash(row)[source]

Hashes a line of text with sha256

Parameters:

row (str)

Return type:

str

src.apputils.load_tba_data_dynamic(event_key, api_key, config_data, teams_list)[source]
Return type:

TBADataDynamic

src.apputils.load_tba_data_static(event_key, api_key, year, last_opr_disabled)[source]

Loads up the teams and schedule for event_key and returns a tuple (teams, schedule)

Return type:

TBADataStatic

src.apputils.read_secrets()[source]

Reads the different secrets of the repo: admin creds, flask secret key, and tba auth key in that order

Return type:

tuple[str, str, str]

src.apputils.safer_replace(src, dest)[source]

os.replace dies sometimes

Return type:

None

src.apputils.set_auth_key(key)[source]

sets the tba key to key

Parameters:

key (str)

Return type:

None

src.apputils.set_tba_whook_key(hmac)[source]
Parameters:

hmac (str)

Return type:

None

src.apputils.stream(file)[source]

Return a stream which reads a file in chunks; used for downloading in case files get big

Return type:

Generator[bytes, Any, None]

src.apputils.tba_health()[source]

pings tba for 10 seconds and returns whether it’s okay

Return type:

bool

src.apputils.test_tba_key(key)[source]

pings tba/api/v3/status with the key given to see if the key is good

Parameters:

key (str)

Return type:

bool

src.apputils.yaml_check_schema_raise_errors(yamldata)[source]
Return type:

None

src.auth module

class src.auth.CreateAccount(*args, **kwargs)[source]

Bases: FlaskForm

Form used on the login page to log in

password = <UnboundField(PasswordField, ('Password',), {'validators': [<wtforms.validators.DataRequired object>], 'render_kw': {'placeholder': 'Enter password...'}})>
submit = <UnboundField(SubmitField, ('Create Account',), {})>
username = <UnboundField(StringField, ('Username',), {'validators': [<wtforms.validators.DataRequired object>], 'render_kw': {'placeholder': "Enter username (ie. 'Frodo Baggins')..."}})>
class src.auth.LoginForm(*args, **kwargs)[source]

Bases: FlaskForm

Form used on the login page to log in

password = <UnboundField(PasswordField, ('Password',), {'validators': [<wtforms.validators.DataRequired object>]})>
submit = <UnboundField(SubmitField, ('Log in',), {})>
username = <UnboundField(StringField, ('Username',), {'validators': [<wtforms.validators.DataRequired object>]})>
src.auth.add_user_to_db(username, password, is_admin=False)[source]
Return type:

None

src.auth.delete_user(my_uid, uid)[source]
Return type:

bool

src.auth.display_user(id)[source]
Parameters:

id (str)

Return type:

str

src.auth.generate_login_db(un, pwd)[source]
Return type:

None

src.auth.generate_random_color(isadmin)[source]
Parameters:

isadmin (bool)

Return type:

str

src.auth.get_can_delete_user(user_uid, uid_to_delete)[source]
Return type:

bool

src.auth.get_password_is_admin(password)[source]
Return type:

Any | bool

src.auth.get_table_exists()[source]
Return type:

bool

src.auth.get_user_from_db(uid)[source]
Return type:

| None

src.auth.get_user_from_db_unpw(un, pwd)[source]
Return type:

| None

src.auth.get_user_is_admin(user)[source]
Parameters:

user (UserMixin)

src.auth.get_users()[source]
Return type:

list[tuple]

src.auth.init_loginm_app(app)[source]

Registers a login manager for admin to the flask app

Parameters:

app (Flask)

Return type:

None

src.auth.override_get_admin()[source]
Return type:

| None

src.auth.require_admin(f)[source]

Ensures that the user is logged into an admin account on the modifiee endpoint

src.auth.text_slug(text)[source]
Parameters:

text (str)

Return type:

str

class src.auth.(id, un, pwd, isadmin, color)[source]

Bases: UserMixin

A user

src.endpoint_schemas module

class src.endpoint_schemas.EndpointAccess(*values)[source]

Bases: Enum

ADMIN = 2
LOGIN = 1
OPEN = 0
class src.endpoint_schemas.EndpointSchema(access, check_json=False, headers=[], args=[], json=[], files=[])[source]

Bases: object

Specifies the access mode and args/headers/body keys required for the endpoint, checking them via flask routing wrappers

Parameters:
  • access (EndpointAccess)

  • check_json (bool)

  • headers (list[str])

  • args (list[str])

  • json (list[str])

  • files (list[str])

static wrap_flask_routing(flask_route_method)[source]

Wraps a flask routing wrappers (app.get/post/etc) to automatically apply the verify_schema wrapper to wrapped functions

src.endpoint_schemas.wrap_flask_routing(flask_route_method)

Wraps a flask routing wrappers (app.get/post/etc) to automatically apply the verify_schema wrapper to wrapped functions

Module contents

Subpackages