tracdap-runtime 0.8.0b1__py3-none-any.whl → 0.8.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. tracdap/rt/_exec/actors.py +5 -4
  2. tracdap/rt/_exec/context.py +26 -10
  3. tracdap/rt/_exec/dev_mode.py +3 -2
  4. tracdap/rt/_exec/engine.py +221 -98
  5. tracdap/rt/_exec/functions.py +27 -47
  6. tracdap/rt/_exec/graph.py +1 -20
  7. tracdap/rt/_exec/graph_builder.py +31 -17
  8. tracdap/rt/_exec/runtime.py +5 -4
  9. tracdap/rt/_exec/server.py +4 -3
  10. tracdap/rt/_impl/config_parser.py +3 -2
  11. tracdap/rt/_impl/data.py +3 -3
  12. tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.py +64 -62
  13. tracdap/rt/_impl/grpc/tracdap/metadata/job_pb2.pyi +16 -2
  14. tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.py +3 -3
  15. tracdap/rt/_impl/grpc/tracdap/metadata/object_id_pb2.pyi +2 -0
  16. tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.py +4 -4
  17. tracdap/rt/_impl/grpc/tracdap/metadata/object_pb2.pyi +4 -2
  18. tracdap/rt/_impl/logging.py +195 -0
  19. tracdap/rt/_impl/models.py +3 -2
  20. tracdap/rt/_impl/repos.py +5 -3
  21. tracdap/rt/_impl/schemas.py +2 -2
  22. tracdap/rt/_impl/shim.py +3 -2
  23. tracdap/rt/_impl/storage.py +4 -3
  24. tracdap/rt/_impl/util.py +0 -110
  25. tracdap/rt/_impl/validation.py +3 -2
  26. tracdap/rt/_version.py +1 -1
  27. tracdap/rt/ext/plugins.py +2 -2
  28. tracdap/rt/metadata/__init__.py +1 -0
  29. tracdap/rt/metadata/job.py +16 -0
  30. tracdap/rt/metadata/object.py +2 -0
  31. tracdap/rt/metadata/object_id.py +2 -0
  32. {tracdap_runtime-0.8.0b1.dist-info → tracdap_runtime-0.8.0b2.dist-info}/METADATA +1 -1
  33. {tracdap_runtime-0.8.0b1.dist-info → tracdap_runtime-0.8.0b2.dist-info}/RECORD +36 -35
  34. {tracdap_runtime-0.8.0b1.dist-info → tracdap_runtime-0.8.0b2.dist-info}/WHEEL +1 -1
  35. {tracdap_runtime-0.8.0b1.dist-info → tracdap_runtime-0.8.0b2.dist-info}/LICENSE +0 -0
  36. {tracdap_runtime-0.8.0b1.dist-info → tracdap_runtime-0.8.0b2.dist-info}/top_level.txt +0 -0
@@ -61,7 +61,7 @@ SEQUENTIAL_JOB_GROUP: JobGroupType
61
61
  PARALLEL_JOB_GROUP: JobGroupType
62
62
 
63
63
  class JobDefinition(_message.Message):
64
- __slots__ = ("jobType", "runModel", "runFlow", "importModel", "importData", "exportData", "jobGroup")
64
+ __slots__ = ("jobType", "runModel", "runFlow", "importModel", "importData", "exportData", "jobGroup", "resultId")
65
65
  JOBTYPE_FIELD_NUMBER: _ClassVar[int]
66
66
  RUNMODEL_FIELD_NUMBER: _ClassVar[int]
67
67
  RUNFLOW_FIELD_NUMBER: _ClassVar[int]
@@ -69,6 +69,7 @@ class JobDefinition(_message.Message):
69
69
  IMPORTDATA_FIELD_NUMBER: _ClassVar[int]
70
70
  EXPORTDATA_FIELD_NUMBER: _ClassVar[int]
71
71
  JOBGROUP_FIELD_NUMBER: _ClassVar[int]
72
+ RESULTID_FIELD_NUMBER: _ClassVar[int]
72
73
  jobType: JobType
73
74
  runModel: RunModelJob
74
75
  runFlow: RunFlowJob
@@ -76,7 +77,20 @@ class JobDefinition(_message.Message):
76
77
  importData: ImportDataJob
77
78
  exportData: ExportDataJob
78
79
  jobGroup: JobGroup
79
- def __init__(self, jobType: _Optional[_Union[JobType, str]] = ..., runModel: _Optional[_Union[RunModelJob, _Mapping]] = ..., runFlow: _Optional[_Union[RunFlowJob, _Mapping]] = ..., importModel: _Optional[_Union[ImportModelJob, _Mapping]] = ..., importData: _Optional[_Union[ImportDataJob, _Mapping]] = ..., exportData: _Optional[_Union[ExportDataJob, _Mapping]] = ..., jobGroup: _Optional[_Union[JobGroup, _Mapping]] = ...) -> None: ...
80
+ resultId: _object_id_pb2.TagSelector
81
+ def __init__(self, jobType: _Optional[_Union[JobType, str]] = ..., runModel: _Optional[_Union[RunModelJob, _Mapping]] = ..., runFlow: _Optional[_Union[RunFlowJob, _Mapping]] = ..., importModel: _Optional[_Union[ImportModelJob, _Mapping]] = ..., importData: _Optional[_Union[ImportDataJob, _Mapping]] = ..., exportData: _Optional[_Union[ExportDataJob, _Mapping]] = ..., jobGroup: _Optional[_Union[JobGroup, _Mapping]] = ..., resultId: _Optional[_Union[_object_id_pb2.TagSelector, _Mapping]] = ...) -> None: ...
82
+
83
+ class ResultDefinition(_message.Message):
84
+ __slots__ = ("jobId", "statusCode", "statusMessage", "logFileId")
85
+ JOBID_FIELD_NUMBER: _ClassVar[int]
86
+ STATUSCODE_FIELD_NUMBER: _ClassVar[int]
87
+ STATUSMESSAGE_FIELD_NUMBER: _ClassVar[int]
88
+ LOGFILEID_FIELD_NUMBER: _ClassVar[int]
89
+ jobId: _object_id_pb2.TagSelector
90
+ statusCode: JobStatusCode
91
+ statusMessage: str
92
+ logFileId: _object_id_pb2.TagSelector
93
+ def __init__(self, jobId: _Optional[_Union[_object_id_pb2.TagSelector, _Mapping]] = ..., statusCode: _Optional[_Union[JobStatusCode, str]] = ..., statusMessage: _Optional[str] = ..., logFileId: _Optional[_Union[_object_id_pb2.TagSelector, _Mapping]] = ...) -> None: ...
80
94
 
81
95
  class RunModelJob(_message.Message):
82
96
  __slots__ = ("model", "parameters", "inputs", "outputs", "priorOutputs", "outputAttrs")
@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
15
15
  from tracdap.rt._impl.grpc.tracdap.metadata import type_pb2 as tracdap_dot_rt_dot___impl_dot_grpc_dot_tracdap_dot_metadata_dot_type__pb2
16
16
 
17
17
 
18
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n6tracdap/rt/_impl/grpc/tracdap/metadata/object_id.proto\x12\x10tracdap.metadata\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/type.proto\"\x98\x02\n\tTagHeader\x12\x30\n\nobjectType\x18\x01 \x01(\x0e\x32\x1c.tracdap.metadata.ObjectType\x12\x10\n\x08objectId\x18\x02 \x01(\t\x12\x15\n\robjectVersion\x18\x03 \x01(\x05\x12\x38\n\x0fobjectTimestamp\x18\x04 \x01(\x0b\x32\x1f.tracdap.metadata.DatetimeValue\x12\x12\n\ntagVersion\x18\x05 \x01(\x05\x12\x35\n\x0ctagTimestamp\x18\x06 \x01(\x0b\x32\x1f.tracdap.metadata.DatetimeValue\x12\x16\n\x0eisLatestObject\x18\x07 \x01(\x08\x12\x13\n\x0bisLatestTag\x18\x08 \x01(\x08\"\xb9\x02\n\x0bTagSelector\x12\x30\n\nobjectType\x18\x01 \x01(\x0e\x32\x1c.tracdap.metadata.ObjectType\x12\x10\n\x08objectId\x18\x02 \x01(\t\x12\x16\n\x0clatestObject\x18\x03 \x01(\x08H\x00\x12\x17\n\robjectVersion\x18\x04 \x01(\x05H\x00\x12\x35\n\nobjectAsOf\x18\x05 \x01(\x0b\x32\x1f.tracdap.metadata.DatetimeValueH\x00\x12\x13\n\tlatestTag\x18\x06 \x01(\x08H\x01\x12\x14\n\ntagVersion\x18\x07 \x01(\x05H\x01\x12\x32\n\x07tagAsOf\x18\x08 \x01(\x0b\x32\x1f.tracdap.metadata.DatetimeValueH\x01\x42\x10\n\x0eobjectCriteriaB\r\n\x0btagCriteria*|\n\nObjectType\x12\x17\n\x13OBJECT_TYPE_NOT_SET\x10\x00\x12\x08\n\x04\x44\x41TA\x10\x01\x12\t\n\x05MODEL\x10\x02\x12\x08\n\x04\x46LOW\x10\x03\x12\x07\n\x03JOB\x10\x04\x12\x08\n\x04\x46ILE\x10\x05\x12\n\n\x06\x43USTOM\x10\x06\x12\x0b\n\x07STORAGE\x10\x07\x12\n\n\x06SCHEMA\x10\x08\x42\x1e\n\x1aorg.finos.tracdap.metadataP\x01\x62\x06proto3')
18
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n6tracdap/rt/_impl/grpc/tracdap/metadata/object_id.proto\x12\x10tracdap.metadata\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/type.proto\"\x98\x02\n\tTagHeader\x12\x30\n\nobjectType\x18\x01 \x01(\x0e\x32\x1c.tracdap.metadata.ObjectType\x12\x10\n\x08objectId\x18\x02 \x01(\t\x12\x15\n\robjectVersion\x18\x03 \x01(\x05\x12\x38\n\x0fobjectTimestamp\x18\x04 \x01(\x0b\x32\x1f.tracdap.metadata.DatetimeValue\x12\x12\n\ntagVersion\x18\x05 \x01(\x05\x12\x35\n\x0ctagTimestamp\x18\x06 \x01(\x0b\x32\x1f.tracdap.metadata.DatetimeValue\x12\x16\n\x0eisLatestObject\x18\x07 \x01(\x08\x12\x13\n\x0bisLatestTag\x18\x08 \x01(\x08\"\xb9\x02\n\x0bTagSelector\x12\x30\n\nobjectType\x18\x01 \x01(\x0e\x32\x1c.tracdap.metadata.ObjectType\x12\x10\n\x08objectId\x18\x02 \x01(\t\x12\x16\n\x0clatestObject\x18\x03 \x01(\x08H\x00\x12\x17\n\robjectVersion\x18\x04 \x01(\x05H\x00\x12\x35\n\nobjectAsOf\x18\x05 \x01(\x0b\x32\x1f.tracdap.metadata.DatetimeValueH\x00\x12\x13\n\tlatestTag\x18\x06 \x01(\x08H\x01\x12\x14\n\ntagVersion\x18\x07 \x01(\x05H\x01\x12\x32\n\x07tagAsOf\x18\x08 \x01(\x0b\x32\x1f.tracdap.metadata.DatetimeValueH\x01\x42\x10\n\x0eobjectCriteriaB\r\n\x0btagCriteria*\x88\x01\n\nObjectType\x12\x17\n\x13OBJECT_TYPE_NOT_SET\x10\x00\x12\x08\n\x04\x44\x41TA\x10\x01\x12\t\n\x05MODEL\x10\x02\x12\x08\n\x04\x46LOW\x10\x03\x12\x07\n\x03JOB\x10\x04\x12\x08\n\x04\x46ILE\x10\x05\x12\n\n\x06\x43USTOM\x10\x06\x12\x0b\n\x07STORAGE\x10\x07\x12\n\n\x06SCHEMA\x10\x08\x12\n\n\x06RESULT\x10\tB\x1e\n\x1aorg.finos.tracdap.metadataP\x01\x62\x06proto3')
19
19
 
20
20
  _globals = globals()
21
21
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -23,8 +23,8 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tracdap.rt._impl.grpc.tracd
23
23
  if _descriptor._USE_C_DESCRIPTORS == False:
24
24
  _globals['DESCRIPTOR']._options = None
25
25
  _globals['DESCRIPTOR']._serialized_options = b'\n\032org.finos.tracdap.metadataP\001'
26
- _globals['_OBJECTTYPE']._serialized_start=726
27
- _globals['_OBJECTTYPE']._serialized_end=850
26
+ _globals['_OBJECTTYPE']._serialized_start=727
27
+ _globals['_OBJECTTYPE']._serialized_end=863
28
28
  _globals['_TAGHEADER']._serialized_start=128
29
29
  _globals['_TAGHEADER']._serialized_end=408
30
30
  _globals['_TAGSELECTOR']._serialized_start=411
@@ -17,6 +17,7 @@ class ObjectType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
17
17
  CUSTOM: _ClassVar[ObjectType]
18
18
  STORAGE: _ClassVar[ObjectType]
19
19
  SCHEMA: _ClassVar[ObjectType]
20
+ RESULT: _ClassVar[ObjectType]
20
21
  OBJECT_TYPE_NOT_SET: ObjectType
21
22
  DATA: ObjectType
22
23
  MODEL: ObjectType
@@ -26,6 +27,7 @@ FILE: ObjectType
26
27
  CUSTOM: ObjectType
27
28
  STORAGE: ObjectType
28
29
  SCHEMA: ObjectType
30
+ RESULT: ObjectType
29
31
 
30
32
  class TagHeader(_message.Message):
31
33
  __slots__ = ("objectType", "objectId", "objectVersion", "objectTimestamp", "tagVersion", "tagTimestamp", "isLatestObject", "isLatestTag")
@@ -23,7 +23,7 @@ from tracdap.rt._impl.grpc.tracdap.metadata import custom_pb2 as tracdap_dot_rt_
23
23
  from tracdap.rt._impl.grpc.tracdap.metadata import stoarge_pb2 as tracdap_dot_rt_dot___impl_dot_grpc_dot_tracdap_dot_metadata_dot_stoarge__pb2
24
24
 
25
25
 
26
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n3tracdap/rt/_impl/grpc/tracdap/metadata/object.proto\x12\x10tracdap.metadata\x1a\x36tracdap/rt/_impl/grpc/tracdap/metadata/object_id.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/type.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/data.proto\x1a\x32tracdap/rt/_impl/grpc/tracdap/metadata/model.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/flow.proto\x1a\x30tracdap/rt/_impl/grpc/tracdap/metadata/job.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/file.proto\x1a\x33tracdap/rt/_impl/grpc/tracdap/metadata/custom.proto\x1a\x34tracdap/rt/_impl/grpc/tracdap/metadata/stoarge.proto\"\x87\x05\n\x10ObjectDefinition\x12\x30\n\nobjectType\x18\x01 \x01(\x0e\x32\x1c.tracdap.metadata.ObjectType\x12\x30\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .tracdap.metadata.DataDefinitionH\x00\x12\x32\n\x05model\x18\x03 \x01(\x0b\x32!.tracdap.metadata.ModelDefinitionH\x00\x12\x30\n\x04\x66low\x18\x04 \x01(\x0b\x32 .tracdap.metadata.FlowDefinitionH\x00\x12.\n\x03job\x18\x05 \x01(\x0b\x32\x1f.tracdap.metadata.JobDefinitionH\x00\x12\x30\n\x04\x66ile\x18\x06 \x01(\x0b\x32 .tracdap.metadata.FileDefinitionH\x00\x12\x34\n\x06\x63ustom\x18\x07 \x01(\x0b\x32\".tracdap.metadata.CustomDefinitionH\x00\x12\x36\n\x07storage\x18\x08 \x01(\x0b\x32#.tracdap.metadata.StorageDefinitionH\x00\x12\x34\n\x06schema\x18\t \x01(\x0b\x32\".tracdap.metadata.SchemaDefinitionH\x00\x12H\n\x0bobjectProps\x18\x64 \x03(\x0b\x32\x33.tracdap.metadata.ObjectDefinition.ObjectPropsEntry\x1aK\n\x10ObjectPropsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.tracdap.metadata.Value:\x02\x38\x01\x42\x0c\n\ndefinitionB2\n\x1aorg.finos.tracdap.metadataB\x12ObjectProtoWrapperP\x01\x62\x06proto3')
26
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n3tracdap/rt/_impl/grpc/tracdap/metadata/object.proto\x12\x10tracdap.metadata\x1a\x36tracdap/rt/_impl/grpc/tracdap/metadata/object_id.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/type.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/data.proto\x1a\x32tracdap/rt/_impl/grpc/tracdap/metadata/model.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/flow.proto\x1a\x30tracdap/rt/_impl/grpc/tracdap/metadata/job.proto\x1a\x31tracdap/rt/_impl/grpc/tracdap/metadata/file.proto\x1a\x33tracdap/rt/_impl/grpc/tracdap/metadata/custom.proto\x1a\x34tracdap/rt/_impl/grpc/tracdap/metadata/stoarge.proto\"\xbd\x05\n\x10ObjectDefinition\x12\x30\n\nobjectType\x18\x01 \x01(\x0e\x32\x1c.tracdap.metadata.ObjectType\x12\x30\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .tracdap.metadata.DataDefinitionH\x00\x12\x32\n\x05model\x18\x03 \x01(\x0b\x32!.tracdap.metadata.ModelDefinitionH\x00\x12\x30\n\x04\x66low\x18\x04 \x01(\x0b\x32 .tracdap.metadata.FlowDefinitionH\x00\x12.\n\x03job\x18\x05 \x01(\x0b\x32\x1f.tracdap.metadata.JobDefinitionH\x00\x12\x30\n\x04\x66ile\x18\x06 \x01(\x0b\x32 .tracdap.metadata.FileDefinitionH\x00\x12\x34\n\x06\x63ustom\x18\x07 \x01(\x0b\x32\".tracdap.metadata.CustomDefinitionH\x00\x12\x36\n\x07storage\x18\x08 \x01(\x0b\x32#.tracdap.metadata.StorageDefinitionH\x00\x12\x34\n\x06schema\x18\t \x01(\x0b\x32\".tracdap.metadata.SchemaDefinitionH\x00\x12\x34\n\x06result\x18\n \x01(\x0b\x32\".tracdap.metadata.ResultDefinitionH\x00\x12H\n\x0bobjectProps\x18\x64 \x03(\x0b\x32\x33.tracdap.metadata.ObjectDefinition.ObjectPropsEntry\x1aK\n\x10ObjectPropsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.tracdap.metadata.Value:\x02\x38\x01\x42\x0c\n\ndefinitionB2\n\x1aorg.finos.tracdap.metadataB\x12ObjectProtoWrapperP\x01\x62\x06proto3')
27
27
 
28
28
  _globals = globals()
29
29
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -34,7 +34,7 @@ if _descriptor._USE_C_DESCRIPTORS == False:
34
34
  _globals['_OBJECTDEFINITION_OBJECTPROPSENTRY']._options = None
35
35
  _globals['_OBJECTDEFINITION_OBJECTPROPSENTRY']._serialized_options = b'8\001'
36
36
  _globals['_OBJECTDEFINITION']._serialized_start=543
37
- _globals['_OBJECTDEFINITION']._serialized_end=1190
38
- _globals['_OBJECTDEFINITION_OBJECTPROPSENTRY']._serialized_start=1101
39
- _globals['_OBJECTDEFINITION_OBJECTPROPSENTRY']._serialized_end=1176
37
+ _globals['_OBJECTDEFINITION']._serialized_end=1244
38
+ _globals['_OBJECTDEFINITION_OBJECTPROPSENTRY']._serialized_start=1155
39
+ _globals['_OBJECTDEFINITION_OBJECTPROPSENTRY']._serialized_end=1230
40
40
  # @@protoc_insertion_point(module_scope)
@@ -15,7 +15,7 @@ from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Opti
15
15
  DESCRIPTOR: _descriptor.FileDescriptor
16
16
 
17
17
  class ObjectDefinition(_message.Message):
18
- __slots__ = ("objectType", "data", "model", "flow", "job", "file", "custom", "storage", "schema", "objectProps")
18
+ __slots__ = ("objectType", "data", "model", "flow", "job", "file", "custom", "storage", "schema", "result", "objectProps")
19
19
  class ObjectPropsEntry(_message.Message):
20
20
  __slots__ = ("key", "value")
21
21
  KEY_FIELD_NUMBER: _ClassVar[int]
@@ -32,6 +32,7 @@ class ObjectDefinition(_message.Message):
32
32
  CUSTOM_FIELD_NUMBER: _ClassVar[int]
33
33
  STORAGE_FIELD_NUMBER: _ClassVar[int]
34
34
  SCHEMA_FIELD_NUMBER: _ClassVar[int]
35
+ RESULT_FIELD_NUMBER: _ClassVar[int]
35
36
  OBJECTPROPS_FIELD_NUMBER: _ClassVar[int]
36
37
  objectType: _object_id_pb2.ObjectType
37
38
  data: _data_pb2.DataDefinition
@@ -42,5 +43,6 @@ class ObjectDefinition(_message.Message):
42
43
  custom: _custom_pb2.CustomDefinition
43
44
  storage: _stoarge_pb2.StorageDefinition
44
45
  schema: _data_pb2.SchemaDefinition
46
+ result: _job_pb2.ResultDefinition
45
47
  objectProps: _containers.MessageMap[str, _type_pb2.Value]
46
- def __init__(self, objectType: _Optional[_Union[_object_id_pb2.ObjectType, str]] = ..., data: _Optional[_Union[_data_pb2.DataDefinition, _Mapping]] = ..., model: _Optional[_Union[_model_pb2.ModelDefinition, _Mapping]] = ..., flow: _Optional[_Union[_flow_pb2.FlowDefinition, _Mapping]] = ..., job: _Optional[_Union[_job_pb2.JobDefinition, _Mapping]] = ..., file: _Optional[_Union[_file_pb2.FileDefinition, _Mapping]] = ..., custom: _Optional[_Union[_custom_pb2.CustomDefinition, _Mapping]] = ..., storage: _Optional[_Union[_stoarge_pb2.StorageDefinition, _Mapping]] = ..., schema: _Optional[_Union[_data_pb2.SchemaDefinition, _Mapping]] = ..., objectProps: _Optional[_Mapping[str, _type_pb2.Value]] = ...) -> None: ...
48
+ def __init__(self, objectType: _Optional[_Union[_object_id_pb2.ObjectType, str]] = ..., data: _Optional[_Union[_data_pb2.DataDefinition, _Mapping]] = ..., model: _Optional[_Union[_model_pb2.ModelDefinition, _Mapping]] = ..., flow: _Optional[_Union[_flow_pb2.FlowDefinition, _Mapping]] = ..., job: _Optional[_Union[_job_pb2.JobDefinition, _Mapping]] = ..., file: _Optional[_Union[_file_pb2.FileDefinition, _Mapping]] = ..., custom: _Optional[_Union[_custom_pb2.CustomDefinition, _Mapping]] = ..., storage: _Optional[_Union[_stoarge_pb2.StorageDefinition, _Mapping]] = ..., schema: _Optional[_Union[_data_pb2.SchemaDefinition, _Mapping]] = ..., result: _Optional[_Union[_job_pb2.ResultDefinition, _Mapping]] = ..., objectProps: _Optional[_Mapping[str, _type_pb2.Value]] = ...) -> None: ...
@@ -0,0 +1,195 @@
1
+ # Licensed to the Fintech Open Source Foundation (FINOS) under one or
2
+ # more contributor license agreements. See the NOTICE file distributed
3
+ # with this work for additional information regarding copyright ownership.
4
+ # FINOS licenses this file to you under the Apache License, Version 2.0
5
+ # (the "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import io as _io
17
+ import sys as _sys
18
+ import typing as _tp
19
+
20
+ from logging import *
21
+
22
+
23
+ class PlainFormatter(Formatter):
24
+
25
+ FORMAT = f"%(asctime)s [%(threadName)s] %(levelname)s %(name)s" + \
26
+ f" - %(message)s"
27
+
28
+ def __init__(self):
29
+ super().__init__(self.FORMAT)
30
+
31
+
32
+ class ColorFormatter(Formatter):
33
+
34
+ _BLACK, _RED, _GREEN, _YELLOW, _BLUE, _MAGENTA, _CYAN, _WHITE, _DEFAULT_WHITE = range(9)
35
+ _DARK_BASE = 30
36
+ _LIGHT_BASE = 90
37
+
38
+ # DARK_BASE + WHITE = light grey
39
+ # DARK_BASE + DEFAULT_WHITE = regular console white
40
+ # LIGHT_BASE + WHITE = bright white (0xffffff), very bright!
41
+
42
+ def __init__(self, is_bright: bool):
43
+
44
+ super().__init__(self._base_fmt(is_bright))
45
+ self._level_colors = self._make_level_colors(is_bright)
46
+ self._default_color = self._make_default_color(is_bright)
47
+
48
+ def format(self, record):
49
+
50
+ level_name = record.levelname
51
+ level_color = self._level_colors.get(level_name)
52
+
53
+ if level_color:
54
+ record.levelname = level_color
55
+ else:
56
+ record.levelname = self._default_color + level_name
57
+
58
+ return Formatter.format(self, record)
59
+
60
+ def _base_fmt(self, is_bright: bool):
61
+
62
+ if is_bright:
63
+ base_color = self._make_ansi_code(self._DARK_BASE, self._DEFAULT_WHITE, is_bold=False)
64
+ message_color = self._make_ansi_code(self._LIGHT_BASE, self._CYAN, is_bold=False)
65
+ else:
66
+ base_color = self._make_ansi_code(self._DARK_BASE, self._WHITE, is_bold=False)
67
+ message_color = self._make_ansi_code(self._DARK_BASE, self._CYAN, is_bold=False)
68
+
69
+ return f"{base_color}%(asctime)s [%(threadName)s] %(levelname)s{base_color} %(name)s" + \
70
+ f" - {message_color}%(message)s"
71
+
72
+ def _make_level_colors(self, is_bright: bool):
73
+
74
+ base_code = self._LIGHT_BASE if is_bright else self._DARK_BASE
75
+
76
+ green = self._make_ansi_code(base_code, self._GREEN, is_bold=is_bright)
77
+ yellow = self._make_ansi_code(base_code, self._YELLOW, is_bold=is_bright)
78
+ red = self._make_ansi_code(base_code, self._RED, is_bold=is_bright)
79
+
80
+ level_colors = {
81
+ 'CRITICAL': f"{red}CRITICAL",
82
+ 'ERROR': f"{red}ERROR",
83
+ 'WARNING': f"{yellow}WARNING",
84
+ 'INFO': f"{green}INFO"
85
+ }
86
+
87
+ return level_colors
88
+
89
+ def _make_default_color(self, is_bright: bool):
90
+
91
+ base_code = self._LIGHT_BASE if is_bright else self._DARK_BASE
92
+ blue = self._make_ansi_code(base_code, self._BLUE, is_bold=is_bright)
93
+
94
+ return blue
95
+
96
+ @classmethod
97
+ def _make_ansi_code(cls, base_code: int, color_offset: int, is_bold: bool):
98
+ return f"\033[{1 if is_bold else 0};{base_code + color_offset}m"
99
+
100
+
101
+ def configure_logging(enable_debug=False):
102
+
103
+ root_logger = getLogger()
104
+ log_level = DEBUG if enable_debug else INFO
105
+
106
+ if not root_logger.hasHandlers():
107
+
108
+ console_formatter = ColorFormatter(is_bright=True)
109
+ console_handler = StreamHandler(_sys.stdout)
110
+ console_handler.setFormatter(console_formatter)
111
+ console_handler.setLevel(INFO)
112
+ root_logger.addHandler(console_handler)
113
+ root_logger.setLevel(log_level)
114
+
115
+ # Use is_bright=False for logs from the TRAC runtime, so model logs stand out
116
+
117
+ trac_logger = getLogger("tracdap.rt")
118
+
119
+ console_formatter = ColorFormatter(is_bright=False)
120
+ console_handler = StreamHandler(_sys.stdout)
121
+ console_handler.setFormatter(console_formatter)
122
+ console_handler.setLevel(log_level)
123
+ trac_logger.addHandler(console_handler)
124
+ trac_logger.propagate = False
125
+
126
+
127
+ def logger_for_object(obj: object) -> Logger:
128
+ return logger_for_class(obj.__class__)
129
+
130
+
131
+ def logger_for_class(clazz: type) -> Logger:
132
+ qualified_class_name = f"{clazz.__module__}.{clazz.__name__}"
133
+ return getLogger(qualified_class_name)
134
+
135
+
136
+ def logger_for_namespace(namespace: str) -> Logger:
137
+ return getLogger(namespace)
138
+
139
+
140
+ class JobLogger(Logger):
141
+
142
+ def __init__(self, sys_log: Logger, *handlers: Handler):
143
+
144
+ super().__init__(sys_log.name, sys_log.level)
145
+ self._sys_log = sys_log._log
146
+ self._job_log = super()._log
147
+
148
+ for handler in handlers:
149
+ self.addHandler(handler)
150
+
151
+ def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1):
152
+
153
+ self._sys_log(level, msg, args, exc_info, extra, stack_info, stacklevel)
154
+ self._job_log(level, msg, args, exc_info, extra, stack_info, stacklevel)
155
+
156
+
157
+ class LogProvider:
158
+
159
+ def logger_for_object(self, obj: object) -> Logger:
160
+ return logger_for_object(obj)
161
+
162
+ def logger_for_class(self, clazz: type) -> Logger:
163
+ return logger_for_class(clazz)
164
+
165
+ def logger_for_namespace(self, namespace: str) -> Logger:
166
+ return logger_for_namespace(namespace)
167
+
168
+
169
+ class JobLogProvider(LogProvider):
170
+
171
+ def __init__(self, *handlers: Handler):
172
+ self.__handlers = handlers
173
+
174
+ def logger_for_object(self, obj: object) -> Logger:
175
+ base_logger = logger_for_object(obj)
176
+ return JobLogger(base_logger, *self.__handlers)
177
+
178
+ def logger_for_class(self, clazz: type) -> Logger:
179
+ base_logger = logger_for_class(clazz)
180
+ return JobLogger(base_logger, *self.__handlers)
181
+
182
+ def logger_for_namespace(self, namespace: str) -> Logger:
183
+ base_logger = logger_for_namespace(namespace)
184
+ return JobLogger(base_logger, *self.__handlers)
185
+
186
+
187
+ def job_log_provider(target: _tp.BinaryIO) -> JobLogProvider:
188
+
189
+ stream = _io.TextIOWrapper(target, newline="\r\n")
190
+ formatter = PlainFormatter()
191
+
192
+ handler = StreamHandler(stream)
193
+ handler.setFormatter(formatter)
194
+
195
+ return JobLogProvider(handler)
@@ -25,9 +25,10 @@ import tracdap.rt.metadata as _meta
25
25
  import tracdap.rt.config as _cfg
26
26
  import tracdap.rt.exceptions as _ex
27
27
 
28
- import tracdap.rt._impl.type_system as _types
28
+ import tracdap.rt._impl.logging as _logging
29
29
  import tracdap.rt._impl.repos as _repos
30
30
  import tracdap.rt._impl.shim as _shim
31
+ import tracdap.rt._impl.type_system as _types
31
32
  import tracdap.rt._impl.util as _util
32
33
  import tracdap.rt._impl.validation as _val
33
34
 
@@ -43,7 +44,7 @@ class ModelLoader:
43
44
 
44
45
  def __init__(self, sys_config: _cfg.RuntimeConfig, scratch_dir: pathlib.Path):
45
46
 
46
- self.__log = _util.logger_for_object(self)
47
+ self.__log = _logging.logger_for_object(self)
47
48
 
48
49
  self.__scratch_dir = scratch_dir.joinpath("models")
49
50
  self.__repos = _repos.RepositoryManager(sys_config)
tracdap/rt/_impl/repos.py CHANGED
@@ -13,10 +13,12 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ import typing as _tp
17
+
16
18
  import tracdap.rt.ext.plugins as plugins
17
19
  import tracdap.rt.config as cfg
18
20
  import tracdap.rt.exceptions as ex
19
- import tracdap.rt._impl.util as util
21
+ import tracdap.rt._impl.logging as _logging
20
22
 
21
23
  # Import repo interfaces
22
24
  from tracdap.rt.ext.repos import *
@@ -26,8 +28,8 @@ class RepositoryManager:
26
28
 
27
29
  def __init__(self, sys_config: cfg.RuntimeConfig):
28
30
 
29
- self._log = util.logger_for_object(self)
30
- self._repos: tp.Dict[str, IModelRepository] = dict()
31
+ self._log = _logging.logger_for_object(self)
32
+ self._repos: _tp.Dict[str, IModelRepository] = dict()
31
33
 
32
34
  # Initialize all repos in the system config
33
35
  # Any errors for missing repo types (plugins) will be raised during startup
@@ -22,9 +22,9 @@ import pyarrow as pa
22
22
  import tracdap.rt.metadata as _meta
23
23
  import tracdap.rt.exceptions as _ex
24
24
  import tracdap.rt._impl.data as _data
25
+ import tracdap.rt._impl.logging as _log
25
26
  import tracdap.rt._impl.storage as _storage
26
27
  import tracdap.rt._impl.shim as _shim
27
- import tracdap.rt._impl.util as _util
28
28
 
29
29
 
30
30
  class SchemaLoader:
@@ -169,4 +169,4 @@ class SchemaLoader:
169
169
  raise _ex.EDataConformance(err)
170
170
 
171
171
 
172
- SchemaLoader._log = _util.logger_for_class(SchemaLoader)
172
+ SchemaLoader._log = _log.logger_for_class(SchemaLoader)
tracdap/rt/_impl/shim.py CHANGED
@@ -31,6 +31,7 @@ import importlib.resources as _ilr
31
31
 
32
32
  import tracdap.rt.exceptions as _ex
33
33
  import tracdap.rt._impl.guard_rails as _guard
34
+ import tracdap.rt._impl.logging as _log
34
35
  import tracdap.rt._impl.util as _util
35
36
 
36
37
 
@@ -138,7 +139,7 @@ class _NamespaceShimFinder(_ila.MetaPathFinder):
138
139
  def __init__(self, shim_map: tp.Dict[str, _Shim], active_shim: _ActiveShim):
139
140
  self.__shim_map = shim_map
140
141
  self.__active_shim = active_shim
141
- self._log = _util.logger_for_class(ShimLoader)
142
+ self._log = _log.logger_for_class(ShimLoader)
142
143
 
143
144
  def find_spec(
144
145
  self, fullname: str,
@@ -561,5 +562,5 @@ class ShimLoader:
561
562
  raise _ex.ERuntimeValidation(err)
562
563
 
563
564
 
564
- ShimLoader._log = _util.logger_for_class(ShimLoader)
565
+ ShimLoader._log = _log.logger_for_class(ShimLoader)
565
566
  ShimLoader._init() # noqa
@@ -30,6 +30,7 @@ import tracdap.rt.config as _cfg
30
30
  import tracdap.rt.exceptions as _ex
31
31
  import tracdap.rt.ext.plugins as plugins
32
32
  import tracdap.rt._impl.data as _data
33
+ import tracdap.rt._impl.logging as _logging
33
34
  import tracdap.rt._impl.util as _util
34
35
  import tracdap.rt._impl.validation as _val
35
36
 
@@ -76,7 +77,7 @@ class StorageManager:
76
77
 
77
78
  def __init__(self, sys_config: _cfg.RuntimeConfig):
78
79
 
79
- self.__log = _util.logger_for_object(self)
80
+ self.__log = _logging.logger_for_object(self)
80
81
  self.__file_storage: tp.Dict[str, IFileStorage] = dict()
81
82
  self.__data_storage: tp.Dict[str, IDataStorage] = dict()
82
83
  self.__external: tp.List[str] = list()
@@ -224,7 +225,7 @@ class CommonFileStorage(IFileStorage):
224
225
 
225
226
  def __init__(self, storage_key: str, storage_config: _cfg.PluginConfig, fs: pa_fs.SubTreeFileSystem):
226
227
 
227
- self._log = _util.logger_for_object(self)
228
+ self._log = _logging.logger_for_object(self)
228
229
  self._key = storage_key
229
230
  self._config = storage_config
230
231
  self._fs = fs
@@ -731,7 +732,7 @@ class CommonDataStorage(IDataStorage):
731
732
  self, config: _cfg.PluginConfig, file_storage: IFileStorage,
732
733
  pushdown_pandas: bool = False, pushdown_spark: bool = False):
733
734
 
734
- self.__log = _util.logger_for_object(self)
735
+ self.__log = _logging.logger_for_object(self)
735
736
 
736
737
  self.__config = config
737
738
  self.__file_storage = file_storage
tracdap/rt/_impl/util.py CHANGED
@@ -14,11 +14,9 @@
14
14
  # limitations under the License.
15
15
 
16
16
  import datetime as dt
17
- import logging
18
17
  import pathlib
19
18
  import platform
20
19
 
21
- import sys
22
20
  import typing as tp
23
21
  import uuid
24
22
 
@@ -38,114 +36,6 @@ def is_windows():
38
36
  return __IS_WINDOWS
39
37
 
40
38
 
41
- class ColorFormatter(logging.Formatter):
42
-
43
- _BLACK, _RED, _GREEN, _YELLOW, _BLUE, _MAGENTA, _CYAN, _WHITE, _DEFAULT_WHITE = range(9)
44
- _DARK_BASE = 30
45
- _LIGHT_BASE = 90
46
-
47
- # DARK_BASE + WHITE = light grey
48
- # DARK_BASE + DEFAULT_WHITE = regular console white
49
- # LIGHT_BASE + WHITE = bright white (0xffffff), very bright!
50
-
51
- def __init__(self, is_bright: bool):
52
-
53
- super().__init__(self._base_fmt(is_bright))
54
- self._level_colors = self._make_level_colors(is_bright)
55
- self._default_color = self._make_default_color(is_bright)
56
-
57
- def format(self, record):
58
-
59
- level_name = record.levelname
60
- level_color = self._level_colors.get(level_name)
61
-
62
- if level_color:
63
- record.levelname = level_color
64
- else:
65
- record.levelname = self._default_color + level_name
66
-
67
- return logging.Formatter.format(self, record)
68
-
69
- def _base_fmt(self, is_bright: bool):
70
-
71
- if is_bright:
72
- base_color = self._make_ansi_code(self._DARK_BASE, self._DEFAULT_WHITE, is_bold=False)
73
- message_color = self._make_ansi_code(self._LIGHT_BASE, self._CYAN, is_bold=False)
74
- else:
75
- base_color = self._make_ansi_code(self._DARK_BASE, self._WHITE, is_bold=False)
76
- message_color = self._make_ansi_code(self._DARK_BASE, self._CYAN, is_bold=False)
77
-
78
- return f"{base_color}%(asctime)s [%(threadName)s] %(levelname)s{base_color} %(name)s" + \
79
- f" - {message_color}%(message)s"
80
-
81
- def _make_level_colors(self, is_bright: bool):
82
-
83
- base_code = self._LIGHT_BASE if is_bright else self._DARK_BASE
84
-
85
- green = self._make_ansi_code(base_code, self._GREEN, is_bold=is_bright)
86
- yellow = self._make_ansi_code(base_code, self._YELLOW, is_bold=is_bright)
87
- red = self._make_ansi_code(base_code, self._RED, is_bold=is_bright)
88
-
89
- level_colors = {
90
- 'CRITICAL': f"{red}CRITICAL",
91
- 'ERROR': f"{red}ERROR",
92
- 'WARNING': f"{yellow}WARNING",
93
- 'INFO': f"{green}INFO"
94
- }
95
-
96
- return level_colors
97
-
98
- def _make_default_color(self, is_bright: bool):
99
-
100
- base_code = self._LIGHT_BASE if is_bright else self._DARK_BASE
101
- blue = self._make_ansi_code(base_code, self._BLUE, is_bold=is_bright)
102
-
103
- return blue
104
-
105
- @classmethod
106
- def _make_ansi_code(cls, base_code: int, color_offset: int, is_bold: bool):
107
- return f"\033[{1 if is_bold else 0};{base_code + color_offset}m"
108
-
109
-
110
- def configure_logging(enable_debug=False):
111
-
112
- root_logger = logging.getLogger()
113
- log_level = logging.DEBUG if enable_debug else logging.INFO
114
-
115
- if not root_logger.hasHandlers():
116
-
117
- console_formatter = ColorFormatter(is_bright=True)
118
- console_handler = logging.StreamHandler(sys.stdout)
119
- console_handler.setFormatter(console_formatter)
120
- console_handler.setLevel(logging.INFO)
121
- root_logger.addHandler(console_handler)
122
- root_logger.setLevel(log_level)
123
-
124
- # Use is_bright=False for logs from the TRAC runtime, so model logs stand out
125
-
126
- trac_logger = logging.getLogger("tracdap.rt")
127
-
128
- console_formatter = ColorFormatter(is_bright=False)
129
- console_handler = logging.StreamHandler(sys.stdout)
130
- console_handler.setFormatter(console_formatter)
131
- console_handler.setLevel(log_level)
132
- trac_logger.addHandler(console_handler)
133
- trac_logger.propagate = False
134
-
135
-
136
- def logger_for_object(obj: object) -> logging.Logger:
137
- return logger_for_class(obj.__class__)
138
-
139
-
140
- def logger_for_class(clazz: type) -> logging.Logger:
141
- qualified_class_name = f"{clazz.__module__}.{clazz.__name__}"
142
- return logging.getLogger(qualified_class_name)
143
-
144
-
145
- def logger_for_namespace(namespace: str) -> logging.Logger:
146
- return logging.getLogger(namespace)
147
-
148
-
149
39
  def format_file_size(size: int) -> str:
150
40
 
151
41
  if size < 1024:
@@ -22,6 +22,7 @@ import pathlib
22
22
 
23
23
  import tracdap.rt.metadata as meta
24
24
  import tracdap.rt.exceptions as ex
25
+ import tracdap.rt._impl.logging as log
25
26
  import tracdap.rt._impl.util as util
26
27
 
27
28
  # _Named placeholder type from API hook is needed for API type checking
@@ -74,7 +75,7 @@ class _TypeValidator:
74
75
  # Inspecting a function signature can take ~ half a second in Python 3.7
75
76
  __method_cache: tp.Dict[str, tp.Tuple[inspect.Signature, tp.Any]] = dict()
76
77
 
77
- _log: logging.Logger = util.logger_for_namespace(__name__)
78
+ _log: logging.Logger = log.logger_for_namespace(__name__)
78
79
 
79
80
  @classmethod
80
81
  def validate_signature(cls, method: tp.Callable, *args, **kwargs):
@@ -324,7 +325,7 @@ class StaticValidator:
324
325
  meta.BasicType.INTEGER,
325
326
  meta.BasicType.DATE]
326
327
 
327
- _log: logging.Logger = util.logger_for_namespace(__name__)
328
+ _log: logging.Logger = log.logger_for_namespace(__name__)
328
329
 
329
330
  @classmethod
330
331
  def is_primitive_type(cls, basic_type: meta.BasicType) -> bool:
tracdap/rt/_version.py CHANGED
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- __version__ = "0.8.0b1"
16
+ __version__ = "0.8.0b2"
tracdap/rt/ext/plugins.py CHANGED
@@ -14,13 +14,13 @@
14
14
  # limitations under the License.
15
15
 
16
16
  import typing as _tp
17
- import logging as _log
18
17
  import pkgutil as _pkg
19
18
  import importlib as _il
20
19
 
21
20
  import tracdap.rt.config as _cfg
22
21
  import tracdap.rt.exceptions as _ex
23
22
  import tracdap.rt._impl.guard_rails as _guard # noqa
23
+ import tracdap.rt._impl.logging as _logging # noqa
24
24
  from tracdap.rt.exceptions import EStartup
25
25
 
26
26
 
@@ -28,7 +28,7 @@ class PluginManager:
28
28
 
29
29
  T_SERVICE = _tp.TypeVar("T_SERVICE")
30
30
 
31
- __log = _log.getLogger(f"{__name__}.PluginManager")
31
+ __log = _logging.getLogger(f"{__name__}.PluginManager")
32
32
 
33
33
  __core_registered = False
34
34
  __3rd_party_registered = list()
@@ -50,6 +50,7 @@ from .job import JobType
50
50
  from .job import JobStatusCode
51
51
  from .job import JobGroupType
52
52
  from .job import JobDefinition
53
+ from .job import ResultDefinition
53
54
  from .job import RunModelJob
54
55
  from .job import RunFlowJob
55
56
  from .job import ImportModelJob
@@ -117,6 +117,22 @@ class JobDefinition:
117
117
 
118
118
  jobGroup: "_tp.Optional[JobGroup]" = None
119
119
 
120
+ resultId: "TagSelector" = _dc.field(default_factory=lambda: TagSelector())
121
+
122
+
123
+ @_dc.dataclass
124
+ class ResultDefinition:
125
+
126
+ """Define the result of a job after it has completed"""
127
+
128
+ jobId: "TagSelector" = _dc.field(default_factory=lambda: TagSelector())
129
+
130
+ statusCode: "JobStatusCode" = JobStatusCode.JOB_STATUS_CODE_NOT_SET
131
+
132
+ statusMessage: "str" = ""
133
+
134
+ logFileId: "TagSelector" = _dc.field(default_factory=lambda: TagSelector())
135
+
120
136
 
121
137
  @_dc.dataclass
122
138
  class RunModelJob: