Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Default function for schemas #26

Merged
merged 43 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
714bbff
Add an abstract 'Default' property to Schema base class, so all other…
LswaN58 Oct 16, 2024
832a708
Merge branch 'main' into issue/1-add-defaults-for-schemas
LswaN58 Oct 16, 2024
7a00c72
Duh, should be a classmethod, not a property.
LswaN58 Oct 16, 2024
80c8e2c
Modify earlier 'DEFAULT' prototype to match new 'Default' required by…
LswaN58 Oct 16, 2024
d3d5abd
Add a placeholder Default function to IndexingSchema.
LswaN58 Oct 16, 2024
096369b
Merge changes from main.
LswaN58 Oct 16, 2024
23cb82b
Remove an empty line.
LswaN58 Oct 16, 2024
c446574
Missed a place where DEFAULT should become Default.
LswaN58 Oct 16, 2024
04c26a1
Merge changes from main.
LswaN58 Oct 30, 2024
5c1603f
TestConfigSchema should use Default, not DEFAULT.
LswaN58 Oct 30, 2024
c36723e
Default should return class instance, not Self, apparently. Self does…
LswaN58 Oct 30, 2024
e2d5221
Add an init for the test config folder.
LswaN58 Oct 30, 2024
faa22e0
Since we're not using Self hint, remove its import.
LswaN58 Oct 30, 2024
cfeb0b1
Add Default() to each of the data source schemas.
LswaN58 Oct 30, 2024
3f2e464
Add default for config-related schemas.
LswaN58 Oct 30, 2024
4d4568c
Use defaults in the FromDicts.
LswaN58 Oct 30, 2024
f72d65b
Set up dataset-related schemas with Default().
LswaN58 Oct 30, 2024
f59c55d
Add some todos for better ways of doing FromDict and ElementFromDict.
LswaN58 Oct 30, 2024
68e40fc
Missed a Default() for a class in FileListSchema module.
LswaN58 Oct 30, 2024
1388adb
Add defaults for table schemas.
LswaN58 Oct 30, 2024
a9b7a53
Add a basic default for AggregateSchema, but so far without content.
LswaN58 Oct 31, 2024
189fc0c
Merge changes from masater.
LswaN58 Oct 31, 2024
f727123
Some changes missed when switching FromDict to use cls.
LswaN58 Oct 31, 2024
18166f0
Convert some FromDicts to use cls instead of full class name.
LswaN58 Nov 4, 2024
0774ebd
Add default to DataElementSchema.
LswaN58 Nov 4, 2024
e49eeff
Have DataElementSchema use defaults in FromDict.
LswaN58 Nov 4, 2024
52775cf
Add defaults for DetectorSchema and DetectorMapSchema.
LswaN58 Nov 4, 2024
173b5d8
Turn f-strings with no params to regular strings.
LswaN58 Nov 4, 2024
9398ad0
Turn another f-string with no params to regular string, and remove un…
LswaN58 Nov 4, 2024
0a1a4d7
Add defaults for EventSchema and FeatureMapSchema.
LswaN58 Nov 4, 2024
d69a914
Add default and clean up SubfeatureSchema.
LswaN58 Nov 4, 2024
ec3e71e
Add default function to GameSchema - fortunately already had class de…
LswaN58 Nov 4, 2024
95f9d91
Finish moving todos up to class block.
LswaN58 Nov 4, 2024
98bfc69
Add defaults to GameState and PerCount schemas.
LswaN58 Nov 4, 2024
2f2b132
Remove some unused imports.
LswaN58 Nov 4, 2024
93d1c6e
Remove unused import.
LswaN58 Nov 4, 2024
92ba14d
Add some todos for TableSchema.
LswaN58 Nov 4, 2024
f032d09
Don't worry about 'dangerous' defaults, for now.
LswaN58 Nov 4, 2024
930aedf
Merge branch 'main' into issue/1-add-defaults-for-schemas
LswaN58 Nov 28, 2024
1971b48
Fix for stray comma.
LswaN58 Nov 28, 2024
5b87e0f
Fix for copy-pasted return type.
LswaN58 Nov 28, 2024
cd0ef07
Replace some hardcoded references to the class with a cls instead.
LswaN58 Nov 28, 2024
4cc388d
A few more substitutions of cls for full class name.
LswaN58 Nov 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ disable=raw-checker-failed,
bad-inline-option,
line-too-long,
unnecessary-pass,
import-error
import-error,
dangerous-default-value

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down
43 changes: 42 additions & 1 deletion src/ogd/common/schemas/Schema.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# import standard libraries
import abc
import logging
from typing import Any, Callable, Dict, List, Optional, Self
from typing import Any, Callable, Dict, List, Optional
# import local files
from ogd.common.utils.Logger import Logger

Expand All @@ -17,6 +17,30 @@ def AsMarkdown(self) -> str:
@classmethod
@abc.abstractmethod
def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging.Logger]=None)-> "Schema":
"""_summary_

TODO : Make classmethod, slightly simplifies how we access default values

:param name: _description_
:type name: str
:param all_elements: _description_
:type all_elements: Dict[str, Any]
:param logger: _description_, defaults to None
:type logger: Optional[logging.Logger], optional
:return: _description_
:rtype: Schema
"""
pass

@classmethod
@abc.abstractmethod
def Default(cls) -> "Schema":
"""Property to get an instance of the Schema with default member values.

Note that these defaults may or may not be a usable configuration.
:return: A schema with default member values.
:rtype: Self
"""
pass

# *** BUILT-INS & PROPERTIES ***
Expand Down Expand Up @@ -53,6 +77,23 @@ def NonStandardElementNames(self) -> List[str]:

@classmethod
def ElementFromDict(cls, all_elements:Dict[str, Any], element_names:List[str], parser_function:Callable, default_value:Any, logger:Optional[logging.Logger]=None) -> Any:
"""_summary_

TODO : Redo this concept in a way that we can still get type safety by directly calling parse functions in individual schema classes.

:param all_elements: _description_
:type all_elements: Dict[str, Any]
:param element_names: _description_
:type element_names: List[str]
:param parser_function: _description_
:type parser_function: Callable
:param default_value: _description_
:type default_value: Any
:param logger: _description_, defaults to None
:type logger: Optional[logging.Logger], optional
:return: _description_
:rtype: Any
"""
for name in element_names:
if name in all_elements:
return parser_function(all_elements[name])
Expand Down
24 changes: 21 additions & 3 deletions src/ogd/common/schemas/configs/GameSourceSchema.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
from typing import Any, Dict, List, Optional, Union
# import local files
from ogd.common.schemas.configs.data_sources.DataSourceSchema import DataSourceSchema
from ogd.common.schemas.configs.data_sources.BigQuerySourceSchema import BigQuerySchema
from ogd.common.schemas.Schema import Schema
from ogd.common.utils.Logger import Logger

class GameSourceSchema(Schema):

_DEFAULT_SOURCE_NAME = "OPENGAMEDATA_BQ"
_DEFAULT_DB_NAME = "UNKNOWN GAME"
_DEFAULT_TABLE_NAME = "_daily"
_DEFAULT_TABLE_SCHEMA = "OPENGAMEDATA_BIGQUERY"

# *** BUILT-INS & PROPERTIES ***

"""A simple Schema structure containing configuration information for a particular game's data.
Expand Down Expand Up @@ -66,6 +72,18 @@ def AsMarkdown(self) -> str:
ret_val = f"{self.Name}: _{self.TableSchema}_ format, source {self.Source.Name if self.Source else 'None'} : {self.DatabaseName}.{self.TableName}"
return ret_val

@classmethod
def Default(cls) -> "GameSourceSchema":
return GameSourceSchema(
name="DefaultGameSourceSchema",
source_name=cls._DEFAULT_SOURCE_NAME,
source_schema=BigQuerySchema.Default(),
db_name=cls._DEFAULT_DB_NAME,
table_name=cls._DEFAULT_TABLE_NAME,
table_schema=cls._DEFAULT_TABLE_SCHEMA,
other_elements={}
)

@classmethod
def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging.Logger], data_sources:Dict[str, DataSourceSchema]) -> "GameSourceSchema":
"""Create a GameSourceSchema from a given dictionary
Expand Down Expand Up @@ -97,7 +115,7 @@ def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging
_source_name = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["source"],
parser_function=cls._parseSource,
default_value="UNKNOWN"
default_value=GameSourceSchema._DEFAULT_SOURCE_NAME
)
if _source_name in data_sources.keys():
_source_schema = data_sources[_source_name]
Expand All @@ -113,12 +131,12 @@ def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging
_table_name = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["table"],
parser_function=cls._parseTableName,
default_value="UNKNOWN"
default_value=GameSourceSchema._DEFAULT_TABLE_NAME
)
_table_schema = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["schema"],
parser_function=cls._parseTableSchemaName,
default_value="UNKNOWN"
default_value=GameSourceSchema._DEFAULT_TABLE_SCHEMA
)

_used = {"source", "database", "table", "schema"}
Expand Down
19 changes: 16 additions & 3 deletions src/ogd/common/schemas/configs/IndexingSchema.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
from ogd.common.utils.Logger import Logger

class FileIndexingSchema(Schema):
_DEFAULT_LOCAL_DIR = Path("./data/")
_DEFAULT_REMOTE_URL = "https://fieldday-web.ad.education.wisc.edu/opengamedata/"
_DEFAULT_TEMPLATE_URL = "https://github.com/opengamedata/opengamedata-samples"

# *** BUILT-INS & PROPERTIES ***

Expand All @@ -30,6 +33,16 @@ def TemplatesURL(self) -> str:

# *** IMPLEMENT ABSTRACT FUNCTIONS ***

@classmethod
def Default(cls) -> "FileIndexingSchema":
return FileIndexingSchema(
name = "DefaultFileIndexingSchema",
local_dir = cls._DEFAULT_LOCAL_DIR,
remote_url = cls._DEFAULT_REMOTE_URL,
templates_url = cls._DEFAULT_TEMPLATE_URL,
other_elements = {}
)

@classmethod
def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging.Logger]=None)-> "FileIndexingSchema":
_local_dir : Path
Expand All @@ -46,17 +59,17 @@ def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging
_local_dir = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["LOCAL_DIR"],
parser_function=cls._parseLocalDir,
default_value=Path("./data/")
default_value=FileIndexingSchema._DEFAULT_LOCAL_DIR
)
_remote_url = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["REMOTE_URL"],
parser_function=cls._parseRemoteURL,
default_value=None
default_value=FileIndexingSchema._DEFAULT_REMOTE_URL
)
_templates_url = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["TEMPLATES_URL"],
parser_function=cls._parseTemplatesURL,
default_value="https://github.com/opengamedata/opengamedata-samples"
default_value=FileIndexingSchema._DEFAULT_TEMPLATE_URL
)

_used = {"LOCAL_DIR", "REMOTE_URL", "TEMPLATES_URL"}
Expand Down
24 changes: 13 additions & 11 deletions src/ogd/common/schemas/configs/TestConfigSchema.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,11 @@
# import local files

class TestConfigSchema(Schema):
_DEFAULT_VERBOSE = False
_DEFAULT_ENABLED_TESTS = {}

# *** BUILT-INS & PROPERTIES ***

@staticmethod
def DEFAULT():
return TestConfigSchema(
name = "DefaultTestConfig",
verbose = False,
enabled_tests = {}
)

def __init__(self, name:str, verbose:bool, enabled_tests:Dict[str, bool], other_elements:Dict[str, Any]={}):
self._verbose : bool = verbose
self._enabled_tests : Dict[str, bool] = enabled_tests
Expand All @@ -51,6 +45,14 @@ def AsMarkdown(self) -> str:
return ret_val

# *** IMPLEMENT ABSTRACT FUNCTIONS ***

@classmethod
def Default(cls) -> "TestConfigSchema":
return TestConfigSchema(
name = "DefaultTestConfig",
verbose = cls._DEFAULT_VERBOSE,
enabled_tests = cls._DEFAULT_ENABLED_TESTS
)

# *** PUBLIC STATICS ***

Expand All @@ -69,12 +71,12 @@ def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging
_verbose = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["VERBOSE"],
parser_function=cls._parseVerbose,
default_value=cls.DEFAULT().Verbose
default_value=cls._DEFAULT_VERBOSE
)
_enabled_tests = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["ENABLED"],
parser_function=cls._parseEnabledTests,
default_value=cls.DEFAULT().EnabledTests
default_value=cls._DEFAULT_ENABLED_TESTS
)

_used = {"VERBOSE", "ENABLED"}
Expand Down Expand Up @@ -111,7 +113,7 @@ def _parseEnabledTests(enabled, logger:Optional[logging.Logger]=None) -> Dict[st
if isinstance(enabled, dict):
ret_val = { str(key) : bool(val) for key, val in enabled.items() }
else:
ret_val = TestConfigSchema.DEFAULT().EnabledTests
ret_val = TestConfigSchema.Default().EnabledTests
_msg = f"Config 'enabled tests' setting was unexpected type {type(enabled)}, defaulting to class default = {ret_val}."
if logger:
logger.warn(_msg, logging.WARN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from ogd.common.utils.Logger import Logger

class BigQuerySchema(DataSourceSchema):
_DEFAULT_PROJECT_ID = "wcer-field-day-ogd-1798"
_DEFAULT_CREDENTIAL = "./config/ogd.json"

# *** BUILT-INS & PROPERTIES ***

Expand Down Expand Up @@ -38,6 +40,15 @@ def AsMarkdown(self) -> str:
ret_val = f"{self.Name}: `{self.AsConnectionInfo}` ({self.Type})"
return ret_val

@classmethod
def Default(cls) -> "BigQuerySchema":
return BigQuerySchema(
name="DefaultBigQuerySchema",
project_id=cls._DEFAULT_PROJECT_ID,
credential=cls._DEFAULT_CREDENTIAL,
other_elements={}
)

@classmethod
def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging.Logger]) -> "BigQuerySchema":
_project_id : str
Expand All @@ -49,12 +60,12 @@ def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging
_project_id = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["PROJECT_ID", "DATASET_ID"],
parser_function=cls._parseProjectID,
default_value="UNKNOWN"
default_value=BigQuerySchema._DEFAULT_PROJECT_ID
)
_credential = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["PROJECT_KEY"],
parser_function=cls._parseCredential,
default_value=None
default_value=BigQuerySchema._DEFAULT_CREDENTIAL
)

_used = {"PROJECT_ID", "DATASET_ID", "PROJECT_KEY"}
Expand Down
17 changes: 14 additions & 3 deletions src/ogd/common/schemas/configs/data_sources/FileSourceSchema.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from ogd.common.utils.Logger import Logger

class FileSourceSchema(DataSourceSchema):
_DEFAULT_FOLDER_PATH = Path('./data')
_DEFAULT_FILE_NAME = "UNKNOWN.tsv"

# *** BUILT-INS & PROPERTIES ***

Expand Down Expand Up @@ -49,7 +51,7 @@ def AsConnectionInfo(self) -> str:
@classmethod
def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging.Logger]=None)-> "FileSourceSchema":
_folder_path : Path
_file_name : Optional[str]
_file_name : str

if not isinstance(all_elements, dict):
all_elements = {}
Expand All @@ -61,18 +63,27 @@ def FromDict(cls, name:str, all_elements:Dict[str, Any], logger:Optional[logging
_folder_path = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["PATH"],
parser_function=cls._parseFolder,
default_value=Path("./data/")
default_value=FileSourceSchema._DEFAULT_FOLDER_PATH
)
_file_name = cls.ElementFromDict(all_elements=all_elements, logger=logger,
element_names=["FILENAME"],
parser_function=cls._parseFilename,
default_value="UNKNOWN.tsv"
default_value=FileSourceSchema._DEFAULT_FILE_NAME
)

_used = {"PATH", "FILENAME"}
_leftovers = { key : val for key,val in all_elements.items() if key not in _used }
return FileSourceSchema(name=name, folder_path=_folder_path, file_name=_file_name, other_elements=_leftovers)

@classmethod
def Default(cls) -> "FileSourceSchema":
return FileSourceSchema(
name="DefaultFileSourceSchema",
folder_path=cls._DEFAULT_FOLDER_PATH,
file_name=cls._DEFAULT_FILE_NAME,
other_elements={}
)

# *** PUBLIC STATICS ***

# *** PUBLIC METHODS ***
Expand Down
Loading