pumpwood_communication.type
Module for custom types at pumpwood systems.
1"""Module for custom types at pumpwood systems.""" 2from .action import ( 3 ActionReturnFile, ActionInfomation, ActionParameterType, 4 ActionReturnType) 5from .abc import PumpwoodSentinel, PumpwoodDataclassMixin 6from .sentinel import ( 7 PumpwoodMissingType, PumpwoodAutoincrementType, PumpwoodAutoNowType, 8 PumpwoodAutoTodayType, PumpwoodPKType, PumpwoodLoggedUserType, 9 PumpwoodAutoFillType, MISSING, AUTOINCREMENT, NOW, TODAY, PUMPWOOD_PK, 10 LOGGED_USER, AUTO_FILL) 11from .info import ( 12 ForeignKeyColumnExtraInfo, RelatedColumnExtraInfo, 13 FileColumnExtraInfo, OptionsColumnExtraInfo, 14 ColumnInfo, ColumnExtraInfo, PrimaryKeyExtraInfo) 15from .views import ( 16 BulkSaveMicroserviceAutoFillField, BulkSaveLocalAutoFillField, 17 BulkSaveDefaultField, MixinBulkSaveField) 18 19 20__all__ = [ 21 PumpwoodSentinel, PumpwoodMissingType, PumpwoodAutoincrementType, 22 PumpwoodAutoNowType, PumpwoodAutoTodayType, MISSING, AUTOINCREMENT, NOW, 23 TODAY, PumpwoodDataclassMixin, PumpwoodPKType, PUMPWOOD_PK, 24 ActionReturnFile, ForeignKeyColumnExtraInfo, RelatedColumnExtraInfo, 25 FileColumnExtraInfo, OptionsColumnExtraInfo, 26 ColumnInfo, ColumnExtraInfo, PrimaryKeyExtraInfo, 27 PumpwoodLoggedUserType, LOGGED_USER, PumpwoodAutoFillType, AUTO_FILL, 28 BulkSaveMicroserviceAutoFillField, BulkSaveLocalAutoFillField, 29 BulkSaveDefaultField, MixinBulkSaveField, ActionInfomation, 30 ActionParameterType, ActionReturnType]
8class PumpwoodSentinel(ABC): 9 """Pumpwood Sentinel class for missing values.""" 10 11 _RETURN_VALUE: str = "" 12 """Value that will be returned on dataclass to dict.""" 13 14 _HELP_TEXT: str = "" 15 """Value that will be returned on dataclass to dict.""" 16 17 @classmethod 18 def value(cls): 19 """Return defult value.""" 20 return cls._RETURN_VALUE 21 22 @classmethod 23 def help_text(cls): 24 """Return defult value.""" 25 return cls._HELP_TEXT
Pumpwood Sentinel class for missing values.
7class PumpwoodMissingType(PumpwoodSentinel): 8 """Pumpwood Sentinel class for missing values.""" 9 10 _RETURN_VALUE: str = "**missing**" 11 _HELP_TEXT: str = "Missing value"
Pumpwood Sentinel class for missing values.
14class PumpwoodAutoincrementType(PumpwoodSentinel): 15 """Pumpwood Sentinel class for missing values.""" 16 17 _RETURN_VALUE: str = "**autoincrement**" 18 _HELP_TEXT: str = "Auto-increment value, usually an integer"
Pumpwood Sentinel class for missing values.
21class PumpwoodAutoNowType(PumpwoodSentinel): 22 """Pumpwood Sentinel class for auto now default.""" 23 24 _RETURN_VALUE: str = "**now**" 25 _HELP_TEXT: str = "Return the now time at the server"
Pumpwood Sentinel class for auto now default.
28class PumpwoodAutoTodayType(PumpwoodSentinel): 29 """Pumpwood Sentinel class for auto now default.""" 30 31 _RETURN_VALUE: str = "**today**" 32 _HELP_TEXT: str = "Return the todat date at the server"
Pumpwood Sentinel class for auto now default.
28class PumpwoodDataclassMixin(ABC): 29 """Pumpwood Dataclasses with some pre-implemented methods. 30 31 Is implemented so it can be used as an object, but data can also be 32 retrived as dictionary using obj['key'] notation. 33 """ 34 35 _RENAME_FIELDS: ClassVar[dict[str, str]] = {} 36 """Rename field on the dataclass and the response, this migth be 37 particullary usefull when dealling with fields like 'in', which is 38 not avaiable.""" 39 40 def to_dict(self): 41 """Converts the dataclass instance into a dictionary recursively.""" 42 clean_data = {} 43 # Iterate over the fields of the current dataclass 44 for field in dataclasses.fields(self): 45 key = field.name 46 value = getattr(self, key) 47 48 # Rename the keys 49 new_key = self._RENAME_FIELDS.get(key, key) 50 clean_data[new_key] = self._process_value(value) 51 return clean_data 52 53 def _process_value(self, value): 54 """Helper to handle recursion and sentinel replacement.""" 55 # Handle Sentinels 56 if isinstance(value, PumpwoodSentinel): 57 return value.value() 58 59 # Handle Nested Pumpwood Dataclasses (Recursion) 60 if isinstance(value, PumpwoodDataclassMixin): 61 return value.to_dict() 62 63 # Handle Lists (check each element) 64 if isinstance(value, list): 65 return [ 66 self._process_value(item) 67 for item in value] 68 69 # Handle Dicts (check each value) 70 if isinstance(value, dict): 71 return { 72 k: self._process_value(v) 73 for k, v in value.items()} 74 return value 75 76 def __iter__(self): 77 """This allows: for key, val in my_dataclass.""" 78 for key, value in self.to_dict().items(): 79 yield key, value 80 81 def __getitem__(self, key): 82 """Allows obj["name"].""" 83 return getattr(self, key) 84 85 def keys(self): 86 """Allows dict(obj) and spreading **obj.""" 87 return [f.name for f in dataclasses.fields(self)]
Pumpwood Dataclasses with some pre-implemented methods.
Is implemented so it can be used as an object, but data can also be retrived as dictionary using obj['key'] notation.
40 def to_dict(self): 41 """Converts the dataclass instance into a dictionary recursively.""" 42 clean_data = {} 43 # Iterate over the fields of the current dataclass 44 for field in dataclasses.fields(self): 45 key = field.name 46 value = getattr(self, key) 47 48 # Rename the keys 49 new_key = self._RENAME_FIELDS.get(key, key) 50 clean_data[new_key] = self._process_value(value) 51 return clean_data
Converts the dataclass instance into a dictionary recursively.
35class PumpwoodPKType(PumpwoodSentinel): 36 """Pumpwood Sentinel class for auto now default.""" 37 38 _RETURN_VALUE: str = "**pumpwood_pk**" 39 _HELP_TEXT: str = ( 40 "Primary key associated with model. It is an integer if not composite " 41 "and a base64 dictionary if it is composite (more than one field)")
Pumpwood Sentinel class for auto now default.
8@dataclass 9class ActionReturnFile(PumpwoodDataclassMixin): 10 """Type for returning files at Pumpwood Actions.""" 11 12 content: bytes 13 """Content of the file that will be returned at the action.""" 14 filename: str 15 """Name off the file that will be returned at the action.""" 16 content_type: str = 'application/octet-stream' 17 """Type content the the file that will be returned at the action."""
Type for returning files at Pumpwood Actions.
23@dataclass 24class ForeignKeyColumnExtraInfo(ColumnExtraInfo): 25 """Foreign Key Extra Info for fill column information.""" 26 model_class: str 27 """Model class associated with the Foreign Key.""" 28 display_field: str 29 """Field that will be used to display the object, it will be serialized 30 as `__display_field__`.""" 31 object_field: str 32 """Field that will receive information from the object.""" 33 source_keys: list[str] 34 """Fields that will used at current object to fetch data at 35 the foreign key object.""" 36 many: bool = False 37 """Foreign keys are always many=False.""" 38 fields: list[str] | None = None 39 """Fields that will be returned at object call."""
Foreign Key Extra Info for fill column information.
Field that will be used to display the object, it will be serialized
as __display_field__.
42@dataclass 43class RelatedColumnExtraInfo(ColumnExtraInfo): 44 """Related Key Extra Info for fill column information.""" 45 model_class: str 46 """Model class associated with Foreign Key.""" 47 pk_field: str 48 """Field of the origin model class that will be used to filter 49 related models at foreign_key.""" 50 foreign_key: str 51 """Field of the origin model class that will be used to filter 52 related models at foreign_key.""" 53 complementary_foreign_key: dict[str, str] 54 """Complementary primary key fields that will be used on query 55 to reduce query time.""" 56 fields: list[str] 57 """Set the fileds that will be returned at the foreign key 58 object.""" 59 many: bool = True 60 """Related will always return many=True."""
Related Key Extra Info for fill column information.
Field of the origin model class that will be used to filter related models at foreign_key.
Field of the origin model class that will be used to filter related models at foreign_key.
72@dataclass 73class FileColumnExtraInfo(ColumnExtraInfo): 74 """File field extra info for column information.""" 75 76 permited_file_types: list[str] 77 """Files allowed to be uploaded."""
File field extra info for column information.
80@dataclass 81class OptionsColumnExtraInfo(ColumnExtraInfo): 82 """Options field extra info for column information.""" 83 _RENAME_FIELDS: ClassVar[dict[str, str]] = { 84 'in_': 'in' 85 } 86 """Rename keys at the result dictionary.""" 87 88 in_: list[dict] | PumpwoodSentinel = MISSING 89 """Options avaiable for the field."""
Options field extra info for column information.
92@dataclass 93class ColumnInfo(PumpwoodDataclassMixin): 94 """Type for returning files at Pumpwood Actions.""" 95 _RENAME_FIELDS: ClassVar[dict[str, str]] = { 96 'in_': 'in', 97 'type_': 'type'} 98 """Rename keys at the result dictionary.""" 99 100 primary_key: bool 101 """If column should be considered a primary_key.""" 102 column: str 103 """Name of the column.""" 104 column__verbose: str 105 """User friendly name for the column.""" 106 help_text: str 107 """Help text associated with the column.""" 108 help_text__verbose: str 109 """User friendly help text associated with the column.""" 110 type_: str 111 """Type of the column.""" 112 nullable: bool 113 """If column can be nullable.""" 114 read_only: bool 115 """If column column is considered read only.""" 116 unique: bool 117 """Is column is to be considered unique.""" 118 indexed: bool 119 """If column is indexed.""" 120 extra_info: ColumnExtraInfo 121 """Extra info associated with custom field types like Foreign Key and 122 related.""" 123 in_: list[dict] | PumpwoodSentinel = MISSING 124 """Return a list with options associated with field possible values.""" 125 default: Any | PumpwoodSentinel = MISSING 126 """If column column is considered read only.""" 127 128 def to_dict(self): 129 """Remove in from dict return when it is missing.""" 130 data = super().to_dict() 131 132 # Remove the in data if it is missing 133 if data.get("in") == "**missing**": 134 data.pop("in") 135 return data
Type for returning files at Pumpwood Actions.
Extra info associated with custom field types like Foreign Key and related.
9@dataclass 10class ColumnExtraInfo(PumpwoodDataclassMixin): 11 """Foreign Key Extra Info for fill column information."""
Foreign Key Extra Info for fill column information.
63@dataclass 64class PrimaryKeyExtraInfo(ColumnExtraInfo): 65 """Extra-info associated with primary key information.""" 66 columns: list[str] 67 """Columns that together form the primary key.""" 68 partition: list[str] 69 """Partition logic of the table."""
Extra-info associated with primary key information.
44class PumpwoodLoggedUserType(PumpwoodSentinel): 45 """Pumpwood Sentinel class for logged user default.""" 46 47 _RETURN_VALUE: str = "**logged_user**" 48 _HELP_TEXT: str = ( 49 "Use autentication header to fill field with id of the logged " 50 "user.")
Pumpwood Sentinel class for logged user default.
53class PumpwoodAutoFillType(PumpwoodSentinel): 54 """Pumpwood Sentinel class auto fill fields on serializer.""" 55 56 _RETURN_VALUE: str = "**autofill**" 57 _HELP_TEXT: str = ( 58 "Use autentication header to fill field with id of the logged " 59 "user.")
Pumpwood Sentinel class auto fill fields on serializer.
15@dataclass 16class BulkSaveMicroserviceAutoFillField(MixinBulkSaveField): 17 """Define a field to be auto filled by microservice at bulk save.""" 18 19 field: str 20 """Name of the field that will be filled on bulk save.""" 21 fill_model_class: str 22 """String associated with model class to fetch information from.""" 23 fill_col: str 24 """Column of the foreign object that will be used to fill the data.""" 25 object_fk_column: str | None 26 """Column that contains the field with pk for the object used to fill 27 the data.""" 28 use_cache: bool = True 29 """If it is allowed to use local cache to fill column value."""
Define a field to be auto filled by microservice at bulk save.
32@dataclass 33class BulkSaveLocalAutoFillField(MixinBulkSaveField): 34 """Define a field to be auto filled by local at bulk save.""" 35 36 field: str 37 """Name of the field that will be filled on bulk save.""" 38 fill_model_class: str 39 """String or SQLAlchemy class associated with model class to fetch 40 information from.""" 41 fill_col: str 42 """Column of the foreign object that will be used to fill the data.""" 43 object_fk_column: str | None 44 """Column that contains the field with pk for the object used to fill 45 the data.""" 46 use_cache: bool = True 47 """If it is allowed to use local cache to fill column value.""" 48 49 @cached_property 50 def cls_fill_model_class(self): 51 """Class used to fetch local data information.""" 52 if isinstance(self.fill_model_class, str): 53 return import_function_by_string(self.fill_model_class) 54 return self.fill_model_class
Define a field to be auto filled by local at bulk save.
String or SQLAlchemy class associated with model class to fetch information from.
Column that contains the field with pk for the object used to fill the data.
49 @cached_property 50 def cls_fill_model_class(self): 51 """Class used to fetch local data information.""" 52 if isinstance(self.fill_model_class, str): 53 return import_function_by_string(self.fill_model_class) 54 return self.fill_model_class
Class used to fetch local data information.
57@dataclass 58class BulkSaveDefaultField(MixinBulkSaveField): 59 """Define a field to be auto filled by default at bulk save.""" 60 61 field: str 62 """Name of the field that will be filled on bulk save by default.""" 63 default: Any 64 """Default value to be used if the field is not filled."""
Define a field to be auto filled by default at bulk save.
10@dataclass 11class MixinBulkSaveField(PumpwoodDataclassMixin): 12 """Mixin to define a field to be used on bulk save."""
Mixin to define a field to be used on bulk save.
20@dataclass 21class ActionInfomation(PumpwoodDataclassMixin): 22 """Type to standardize action information exchange.""" 23 24 action_name: str 25 """Name of the action.""" 26 is_static_function: bool 27 """If action should be considered a static function and should run without 28 an associated object (pk should not be passed on function call).""" 29 info: str 30 """Description of the action.""" 31 return_: dict 32 """Information about the variable that be returned by the action.""" 33 parameters: dict 34 """Description of the parameters used by the action.""" 35 doc_string: str 36 """Doc string avaiable at action definition.""" 37 required_role: str = 'default' 38 """Required role to run the action, if default is set the permission will 39 be managed by end-point permission at pumpwood auth.""" 40 41 _RENAME_FIELDS = {"return_": "return"} 42 """Rename 'return_' to 'return' since it is a retricted expression on 43 python."""
Type to standardize action information exchange.
46@dataclass 47class ActionParameterType(PumpwoodDataclassMixin): 48 """Type to standardize action parameter type exchange.""" 49 50 many: bool 51 """Define if the parameter is a list of the type.""" 52 type_: str 53 """Type of the parameter.""" 54 required: bool 55 """Define if the parameter is required or not.""" 56 default_value: Any 57 """Default value associated with the parameter.""" 58 in_: list[str] | None = None 59 """If the parameter if an options, it will return the possible options 60 associated with the parameter.""" 61 62 _RENAME_FIELDS = {"type_": "type", "in_": "in"} 63 """Rename 'return_' to 'return' since it is a retricted expression on 64 python."""
Type to standardize action parameter type exchange.
67@dataclass 68class ActionReturnType(PumpwoodDataclassMixin): 69 """Type to standardize action return type exchange.""" 70 71 many: bool 72 """Define if the parameter is a list of the type.""" 73 type_: str 74 """Type of the parameter.""" 75 in_: list[str] | None = None 76 """If the parameter if an options, it will return the possible options 77 associated with the parameter.""" 78 79 _RENAME_FIELDS = {"type_": "type", "in_": "in"} 80 """Rename 'return_' to 'return' since it is a retricted expression on 81 python."""
Type to standardize action return type exchange.