sheetsync: Make the middleware interface explicit with a base class

The main purpose here is just documentation, so it's clear what the semantics of a middleware is.
pull/401/head
Mike Lang 3 months ago committed by Mike Lang
parent 3ffbefea4f
commit e9b6e27598

@ -0,0 +1,35 @@
class Middleware:
"""A common interface for connecting sheetsync to a "sheet" source,
including specifics for a certain row type."""
def get_rows(self):
"""Fetch rows from the sheet, parsed into a list of dicts.
The returned dicts have the following guarenteed keys:
id: A unique identifier for the row
sheet_name: The worksheet associated with the row.
The concept of a worksheet is not common to all backends, but some identifying string
is still required.
_parse_errors: A list of error messages encountered when parsing, to be surfaced to the
user if possible.
In addition to the list of dicts, should return an "is_full" boolean which is True
if all rows were fetched or False if only some subset was fetched (eg. for quota management reasons).
Returns (is_full, rows).
"""
raise NotImplementedError
def write_value(self, row, key, value):
"""Write key=value to the given row. Takes the full row object so any identifying info
can be read from it as needed."""
raise NotImplementedError
def mark_modified(self, row):
"""Called if any sync action was performed due to this row.
Intended as a way to keep track of recently-changed rows for quota optimization."""
pass
def create_row(self, worksheet, id):
"""Create a new row with given id in the given worksheet and return it.
Only used for reverse sync."""
raise NotImplementedError

@ -7,6 +7,8 @@ from monotonic import monotonic
import common import common
from common.googleapis import GoogleAPIClient from common.googleapis import GoogleAPIClient
from .middleware import Middleware
class SheetsClient(object): class SheetsClient(object):
"""Manages Google Sheets API operations""" """Manages Google Sheets API operations"""
@ -70,7 +72,7 @@ class SheetsClient(object):
return ''.join(digits) return ''.join(digits)
class SheetsMiddleware(): class SheetsMiddleware(Middleware):
# How many syncs of active sheets to do before checking inactive sheets. # How many syncs of active sheets to do before checking inactive sheets.
# By checking inactive sheets less often, we stay within our API limits. # By checking inactive sheets less often, we stay within our API limits.
# For example, 4 syncs per inactive check * 5 seconds between syncs = 20s between inactive checks # For example, 4 syncs per inactive check * 5 seconds between syncs = 20s between inactive checks

@ -6,6 +6,9 @@ import requests
from common.dateutil import parse_utc_only from common.dateutil import parse_utc_only
from .middleware import Middleware
class StreamLogClient(): class StreamLogClient():
"""Client for Stream Log server""" """Client for Stream Log server"""
@ -41,7 +44,7 @@ class StreamLogClient():
return None return None
class StreamLogMiddleware: class StreamLogMiddleware(Middleware):
def __init__(self, client): def __init__(self, client):
self.client = client self.client = client
# Maps DB column names to streamlog fields. # Maps DB column names to streamlog fields.
@ -121,9 +124,3 @@ class StreamLogMiddleware:
if key in self.column_encode: if key in self.column_encode:
value = self.column_encode[key](value) value = self.column_encode[key](value)
self.client.write_value(row["id"], self.write_map[key], value) self.client.write_value(row["id"], self.write_map[key], value)
def mark_modified(self, row):
pass # not a concept we have
def create_row(self, worksheet, id):
raise NotImplementedError

Loading…
Cancel
Save