aepp 0.5.1.post1__py3-none-any.whl → 0.5.2__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.
aepp/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.5.1-1"
1
+ __version__ = "0.5.2"
aepp/classmanager.py CHANGED
@@ -23,7 +23,7 @@ class ClassManager:
23
23
  schemaAPI:'Schema'=None,
24
24
  config: Union[dict,ConnectObject] = aepp.config.config_object,
25
25
  description: str = 'power by aepp',
26
- localFolder:str=None,
26
+ localFolder:str | list | None = None,
27
27
  sandbox:str=None,
28
28
  **kwargs
29
29
  )->None:
@@ -48,13 +48,16 @@ class ClassManager:
48
48
  elif config is not None and localFolder is None:
49
49
  self.schemaAPI = Schema(config=config)
50
50
  elif localFolder is not None:
51
- self.localfolder = Path(localFolder)
52
- if self.localfolder.exists() is False:
51
+ if isinstance(localFolder, str):
52
+ self.localfolder = [Path(localFolder)]
53
+ elif isinstance(localFolder, list):
54
+ self.localfolder = [Path(lf) for lf in localFolder]
55
+ if any([folder.exists() is False for folder in self.localfolder]):
53
56
  raise Exception(f"The local folder {self.localfolder} does not exist. Please create it and extract your sandbox before using it.")
54
57
  self.schemaAPI = None
55
- self.classFolder = self.localfolder / 'class'
56
- self.behavFolder = self.localfolder / 'behaviour'
57
- if self.classFolder.exists() is False:
58
+ self.classFolder = [folder / 'class' for folder in self.localfolder]
59
+ self.behavFolder = [folder / 'behaviour' for folder in self.localfolder]
60
+ if any([folder.exists() is False for folder in self.classFolder]):
58
61
  raise Exception(f"The local folder {self.classFolder} does not exist. Please create it and extract your sandbox before using it.")
59
62
  else:
60
63
  raise Exception("You need to provide a schemaAPI instance or a config object to connect to the API or a local folder to use the local storage")
@@ -71,9 +74,11 @@ class ClassManager:
71
74
  elif type(aepclass) == dict:
72
75
  self.tenantId = aepclass.get('meta:tenantNamespace'," ")
73
76
  elif self.localfolder is not None:
74
- config_json = json.load(FileIO(self.localfolder / 'config.json'))
75
- if config_json.get('tenantId',None) is not None:
76
- self.tenantId = config_json.get('tenantId')
77
+ for folder in self.localfolder:
78
+ config_json = json.load(FileIO(folder / 'config.json'))
79
+ if config_json.get('tenantId',None) is not None:
80
+ self.tenantId = config_json.get('tenantId')
81
+ break
77
82
  else:
78
83
  self.tenantId = " "
79
84
  if type(aepclass) == dict:
@@ -82,10 +87,15 @@ class ClassManager:
82
87
  self.aepclass = self.schemaAPI.getClass(aepclass['$id'],full=False,xtype='xed')
83
88
  self.EDITABLE = True
84
89
  elif self.localfolder is not None:
85
- for json_file in self.classFolder.glob('*.json'):
86
- tmp_def = json.load(FileIO(json_file))
87
- if tmp_def.get('$id') == aepclass['$id']:
88
- self.aepclass = tmp_def
90
+ found = False
91
+ for folder in self.classFolder:
92
+ for json_file in folder.glob('*.json'):
93
+ tmp_def = json.load(FileIO(json_file))
94
+ if tmp_def.get('$id') == aepclass['$id']:
95
+ self.aepclass = tmp_def
96
+ found = True
97
+ break
98
+ if found:
89
99
  break
90
100
  self.EDITABLE = False
91
101
  elif self.tenantId[1:] not in aepclass['$id']:
@@ -93,10 +103,15 @@ class ClassManager:
93
103
  self.aepclass = self.schemaAPI.getClass(aepclass['$id'],full=True,xtype='xed')
94
104
  self.EDITABLE = False
95
105
  elif self.localfolder is not None:
96
- for json_file in self.classFolder.glob('*.json'):
97
- tmp_def = json.load(FileIO(json_file))
98
- if tmp_def.get('$id') == aepclass['$id']:
99
- self.aepclass = tmp_def
106
+ found = False
107
+ for folder in self.classFolder:
108
+ for json_file in folder.glob('*.json'):
109
+ tmp_def = json.load(FileIO(json_file))
110
+ if tmp_def.get('$id') == aepclass['$id']:
111
+ self.aepclass = tmp_def
112
+ found = True
113
+ break
114
+ if found:
100
115
  break
101
116
  self.EDITABLE = False
102
117
  self.__setAttributes__(self.aepclass)
@@ -106,20 +121,30 @@ class ClassManager:
106
121
  self.aepclass = self.schemaAPI.getClass(aepclass,full=False,xtype='xed')
107
122
  self.EDITABLE = True
108
123
  elif self.localfolder is not None:
109
- for json_file in self.classFolder.glob('*.json'):
110
- tmp_def = json.load(FileIO(json_file))
111
- if tmp_def.get('$id') == aepclass or tmp_def.get('meta:altId') == aepclass:
112
- self.aepclass = tmp_def
124
+ found = False
125
+ for folder in self.classFolder:
126
+ for json_file in folder.glob('*.json'):
127
+ tmp_def = json.load(FileIO(json_file))
128
+ if tmp_def.get('$id') == aepclass or tmp_def.get('meta:altId') == aepclass:
129
+ self.aepclass = tmp_def
130
+ found = True
131
+ break
132
+ if found:
113
133
  break
114
134
  self.EDITABLE = False
115
135
  else:
116
136
  if self.schemaAPI is not None:
117
137
  self.aepclass = self.schemaAPI.getClass(aepclass,full=True,xtype='xed')
118
138
  elif self.localfolder is not None:
119
- for json_file in self.classFolder.glob('*.json'):
120
- tmp_def = json.load(FileIO(json_file))
121
- if tmp_def.get('$id') == aepclass or tmp_def.get('meta:altId') == aepclass:
122
- self.aepclass = tmp_def
139
+ found = False
140
+ for folder in self.classFolder:
141
+ for json_file in folder.glob('*.json'):
142
+ tmp_def = json.load(FileIO(json_file))
143
+ if tmp_def.get('$id') == aepclass or tmp_def.get('meta:altId') == aepclass:
144
+ self.aepclass = tmp_def
145
+ found = True
146
+ break
147
+ if found:
123
148
  break
124
149
  self.EDITABLE = False
125
150
  self.__setAttributes__(self.aepclass)
@@ -168,10 +193,15 @@ class ClassManager:
168
193
  if self.schemaAPI is not None:
169
194
  self.behaviorDefinition = self.schemaAPI.getBehavior(behavId,full=True,xtype='xed')
170
195
  elif self.localfolder is not None:
171
- for json_file in self.behavFolder.glob('*.json'):
172
- tmp_def = json.load(FileIO(json_file))
173
- if tmp_def.get('$id') == behavId:
174
- self.behaviorDefinition = tmp_def
196
+ found = False
197
+ for folder in self.behavFolder:
198
+ for json_file in folder.glob('*.json'):
199
+ tmp_def = json.load(FileIO(json_file))
200
+ if tmp_def.get('$id') == behavId:
201
+ self.behaviorDefinition = tmp_def
202
+ found = True
203
+ break
204
+ if found:
175
205
  break
176
206
  self.requiredFields = set()
177
207
 
aepp/cli/__main__.py CHANGED
@@ -47,26 +47,25 @@ class ServiceShell(cmd.Cmd):
47
47
  self.sandbox = str(dict_config.get("sandbox-name","prod"))
48
48
  else:
49
49
  self.sandbox = str(kwargs.get("sandbox","prod"))
50
- self.secret = str(dict_config.get("secret",kwargs.get("secret")))
51
- self.org_id = str(dict_config.get("org_id",kwargs.get("org_id")))
52
- self.client_id = str(dict_config.get("client_id",kwargs.get("client_id")))
53
- self.scopes = str(dict_config.get("scopes",kwargs.get("scopes")))
50
+ self.secret = dict_config.get("secret",kwargs.get("secret"))
51
+ self.org_id = dict_config.get("org_id",kwargs.get("org_id"))
52
+ self.client_id = dict_config.get("client_id",kwargs.get("client_id"))
53
+ self.scopes = dict_config.get("scopes",kwargs.get("scopes"))
54
54
  else:
55
- self.sandbox = str(kwargs.get("sandbox","prod"))
56
- self.secret = str(kwargs.get("secret"))
57
- self.org_id = str(kwargs.get("org_id"))
58
- self.client_id = str(kwargs.get("client_id"))
59
- self.scopes = str(kwargs.get("scopes"))
60
- self.connectInstance = True
55
+ self.sandbox:str|None = kwargs.get("sandbox","prod")
56
+ self.secret:str|None = kwargs.get("secret")
57
+ self.org_id:str|None = kwargs.get("org_id")
58
+ self.client_id:str|None = kwargs.get("client_id")
59
+ self.scopes:str|None = kwargs.get("scopes")
61
60
  if self.sandbox is not None and self.secret is not None and self.org_id is not None and self.client_id is not None and self.scopes is not None:
62
61
  print("Configuring connection...")
63
62
  self.config = aepp.configure(
64
- connectInstance=self.connectInstance,
65
63
  sandbox=self.sandbox,
66
64
  secret=self.secret,
67
65
  org_id=self.org_id,
68
66
  client_id=self.client_id,
69
- scopes=self.scopes
67
+ scopes=self.scopes,
68
+ connectInstance=self.connectInstance
70
69
  )
71
70
  self.prompt = f"{self.config.sandbox}> "
72
71
  console.print(Panel(f"Connected to [bold green]{self.sandbox}[/bold green]", style="blue"))
@@ -82,7 +81,6 @@ class ServiceShell(cmd.Cmd):
82
81
  console.print(f"Configuration file created at {Path.cwd() / Path(filename_json)}", style="green")
83
82
  return
84
83
 
85
-
86
84
  # # --- Commands ---
87
85
  def do_config(self, arg:Any) -> None:
88
86
  """connect to an AEP instance"""
@@ -94,14 +92,14 @@ class ServiceShell(cmd.Cmd):
94
92
  parser.add_argument("-cid", "--client_id", help="Auto-login client ID")
95
93
  parser.add_argument("-cf", "--config_file", help="Path to config file", default=None)
96
94
  args = parser.parse_args(shlex.split(arg))
97
- if args.config_file:
95
+ if args.config_file is not None:
98
96
  mypath = Path.cwd()
99
97
  dict_config = json.load(FileIO(mypath / Path(args.config_file)))
100
- self.sandbox = str(args.sandbox) if args.sandbox else str(dict_config.get("sandbox-name",args.sandbox))
101
- self.secret = str(dict_config.get("secret",args.secret))
102
- self.org_id = str(dict_config.get("org_id",args.org_id))
103
- self.client_id = str(dict_config.get("client_id",args.client_id))
104
- self.scopes = str(dict_config.get("scopes",args.scopes))
98
+ self.sandbox:str|None = args.sandbox if args.sandbox else dict_config.get("sandbox-name",args.sandbox)
99
+ self.secret:str|None = dict_config.get("secret",args.secret)
100
+ self.org_id:str|None = dict_config.get("org_id",args.org_id)
101
+ self.client_id:str|None = dict_config.get("client_id",args.client_id)
102
+ self.scopes:str|None = dict_config.get("scopes",args.scopes)
105
103
  self.connectInstance = True
106
104
  else:
107
105
  if args.sandbox: self.sandbox = str(args.sandbox)
@@ -1203,18 +1201,14 @@ class ServiceShell(cmd.Cmd):
1203
1201
  console.print("Syncing artifact...", style="blue")
1204
1202
  parser = argparse.ArgumentParser(prog='extractArtifact', description='Extract artifacts from AEP')
1205
1203
  parser.add_argument('artifact', help='artifact to extract (name or id): "schema","fieldgroup","datatype","descriptor","dataset","identity","mergepolicy","audience"')
1206
- parser.add_argument('-at','--artifactType', help='artifact type ')
1207
- parser.add_argument('-t','--targets', help='target sandboxes')
1208
- parser.add_argument('-lf','--localfolder', help='Local folder to extract artifacts to',default='extractions')
1204
+ parser.add_argument('-at','--artifactType', help='artifact type ',type=str)
1205
+ parser.add_argument('-t','--targets', help='target sandboxes',nargs='+',type=str)
1206
+ parser.add_argument('-lf','--localfolder', help='Local folder to extract artifacts to',default='extractions',nargs='+',type=str)
1209
1207
  parser.add_argument('-b','--baseSandbox', help='Base sandbox for synchronization')
1210
1208
  parser.add_argument('-rg','--region', help='Region to extract artifacts from: "ndl2" (default), "va7", "aus5", "can2", "ind2"',default='ndl2')
1211
1209
  parser.add_argument('-v','--verbose', help='Enable verbose output',default=True)
1212
1210
  try:
1213
1211
  args = parser.parse_args(shlex.split(args))
1214
- if ',' in args.targets:
1215
- args.targets = args.targets.split(',')
1216
- else:
1217
- args.targets = [args.targets]
1218
1212
  console.print("Initializing Synchronizor...", style="blue")
1219
1213
  if args.baseSandbox:
1220
1214
  synchronizor = synchronizer.Synchronizer(
aepp/datatypemanager.py CHANGED
@@ -36,7 +36,7 @@ class DataTypeManager:
36
36
  schemaAPI:'Schema'=None,
37
37
  config: Union[dict,ConnectObject] = aepp.config.config_object,
38
38
  description:str="",
39
- localFolder:str=None,
39
+ localFolder:str|list|None=None,
40
40
  sandbox:str=None,
41
41
  **kwargs
42
42
  )->None:
@@ -65,10 +65,13 @@ class DataTypeManager:
65
65
  elif config is not None and localFolder is None:
66
66
  self.schemaAPI = Schema(config=config)
67
67
  elif localFolder is not None:
68
- self.localfolder = Path(localFolder)
69
- self.datatypeFolder = self.localfolder / 'datatype'
70
- self.datatypeGlobalFolder = self.datatypeFolder / 'global'
71
- if self.localfolder.exists() is False:
68
+ if isinstance(localFolder, str):
69
+ self.localfolder = [Path(localFolder)]
70
+ elif isinstance(localFolder, list):
71
+ self.localfolder = [Path(folder) for folder in localFolder]
72
+ self.datatypeFolder = [folder / 'datatype' for folder in self.localfolder]
73
+ self.datatypeGlobalFolder = [folder / 'global' for folder in self.datatypeFolder]
74
+ if any([folder.exists() is False for folder in self.localfolder]):
72
75
  raise Exception(f"The local folder {self.localfolder} does not exist. Please create it and extract your sandbox before using it.")
73
76
  self.schemaAPI = None
74
77
  if self.schemaAPI is not None:
@@ -99,20 +102,32 @@ class DataTypeManager:
99
102
  self.dataType = self.schemaAPI.getDataType(dataType['$id'],full=False)
100
103
  self.EDITABLE = True
101
104
  elif self.localfolder is not None:
102
- for dataTypeFile in self.datatypeFolder.glob(f"*.json"):
103
- tmp_def = json.load(FileIO(dataTypeFile))
104
- if tmp_def.get('$id') == dataType.get('$id') or tmp_def.get('meta:altId') == dataType.get('meta:altId'):
105
- self.dataType = tmp_def
105
+ found = False
106
+ for folder in self.datatypeFolder:
107
+ for dataTypeFile in folder.glob(f"*.json"):
108
+ tmp_def = json.load(FileIO(dataTypeFile))
109
+ if tmp_def.get('$id') == dataType.get('$id') or tmp_def.get('meta:altId') == dataType.get('meta:altId'):
110
+ self.dataType = tmp_def
111
+ found = True
112
+ break
113
+ if found:
114
+ break
106
115
  self.EDITABLE = False
107
116
  else:
108
117
  if self.schemaAPI is not None:
109
118
  self.dataType = self.schemaAPI.getDataType(dataType['$id'],full=True)
110
119
  self.EDITABLE = True
111
120
  elif self.localfolder is not None:
112
- for dataTypeFile in self.datatypeGlobalFolder.glob("*.json"):
113
- tmp_def = json.load(FileIO(dataTypeFile))
114
- if tmp_def.get('$id') == dataType.get('$id') or tmp_def.get('meta:altId') == dataType.get('meta:altId') or tmp_def.get('title') == dataType.get('title'):
115
- self.dataType = tmp_def
121
+ found = False
122
+ for folder in self.datatypeGlobalFolder:
123
+ for dataTypeFile in folder.glob("*.json"):
124
+ tmp_def = json.load(FileIO(dataTypeFile))
125
+ if tmp_def.get('$id') == dataType.get('$id') or tmp_def.get('meta:altId') == dataType.get('meta:altId') or tmp_def.get('title') == dataType.get('title'):
126
+ self.dataType = tmp_def
127
+ found = True
128
+ break
129
+ if found:
130
+ break
116
131
  self.EDITABLE = False
117
132
  elif type(dataType) == str:
118
133
  if self.tenantId[1:] in dataType:
@@ -122,10 +137,16 @@ class DataTypeManager:
122
137
  raise ValueError(f"Cannot find the data type with id {dataType} in the schema API.")
123
138
  self.EDITABLE = True
124
139
  elif self.localfolder is not None:
125
- for dataTypeFile in self.datatypeFolder.glob("*.json"):
126
- tmp_def = json.load(FileIO(dataTypeFile))
127
- if tmp_def.get('$id') == dataType or tmp_def.get('meta:altId') == dataType or tmp_def.get('title') == dataType:
128
- self.dataType = tmp_def
140
+ found = False
141
+ for folder in self.datatypeFolder:
142
+ for dataTypeFile in folder.glob("*.json"):
143
+ tmp_def = json.load(FileIO(dataTypeFile))
144
+ if tmp_def.get('$id') == dataType or tmp_def.get('meta:altId') == dataType or tmp_def.get('title') == dataType:
145
+ self.dataType = tmp_def
146
+ found = True
147
+ break
148
+ if found:
149
+ break
129
150
  self.EDITABLE = False
130
151
  else:
131
152
  raise Exception("You try to retrieve the datatype definition from the id, but no API or localFolder has been passed as a parameter.")
@@ -136,10 +157,16 @@ class DataTypeManager:
136
157
  raise ValueError(f"Cannot find the data type with id {dataType} in the schema API.")
137
158
  self.EDITABLE = True
138
159
  elif self.localfolder is not None:
139
- for dataTypeFile in self.datatypeGlobalFolder.glob("*.json"):
140
- tmp_def = json.load(FileIO(dataTypeFile))
141
- if tmp_def.get('$id') == dataType or tmp_def.get('meta:altId') == dataType or tmp_def.get('title') == dataType:
142
- self.dataType = tmp_def
160
+ found = False
161
+ for folder in self.datatypeGlobalFolder:
162
+ for dataTypeFile in folder.glob("*.json"):
163
+ tmp_def = json.load(FileIO(dataTypeFile))
164
+ if tmp_def.get('$id') == dataType or tmp_def.get('meta:altId') == dataType or tmp_def.get('title') == dataType:
165
+ self.dataType = tmp_def
166
+ found = True
167
+ break
168
+ if found:
169
+ break
143
170
  self.EDITABLE = False
144
171
  else:
145
172
  raise Exception("You try to retrieve the datatype definition from the id, but no API or localFolder has been passed as a parameter.")
@@ -181,12 +208,18 @@ class DataTypeManager:
181
208
  self.dataTypeManagers[dt_manager.title] = dt_manager
182
209
  elif self.localfolder is not None:
183
210
  for dt in dataTypes: ## today only searching custom data types in local folder
184
- for dataTypeFile in self.datatypeFolder.glob("*.json"):
185
- tmp_def = json.load(FileIO(dataTypeFile))
186
- if tmp_def.get('$id') == dt or tmp_def.get('meta:altId') == dt or tmp_def.get('title') == dt:
187
- dt_manager = DataTypeManager(dataType=tmp_def,localFolder=self.localfolder,tenantId=self.tenantId,sandbox=self.sandbox)
188
- self.dataTypes[dt_manager.id] = dt_manager.title
189
- self.dataTypeManagers[dt_manager.title] = dt_manager
211
+ found = False
212
+ for folder in self.datatypeFolder:
213
+ for dataTypeFile in folder.glob("*.json"):
214
+ tmp_def = json.load(FileIO(dataTypeFile))
215
+ if tmp_def.get('$id') == dt or tmp_def.get('meta:altId') == dt or tmp_def.get('title') == dt:
216
+ dt_manager = DataTypeManager(dataType=tmp_def,localFolder=self.localfolder,tenantId=self.tenantId,sandbox=self.sandbox)
217
+ self.dataTypes[dt_manager.id] = dt_manager.title
218
+ self.dataTypeManagers[dt_manager.title] = dt_manager
219
+ found = True
220
+ break
221
+ if found:
222
+ break
190
223
  if title is not None:
191
224
  self.dataType['title'] = title
192
225
  self.title = title
aepp/fieldgroupmanager.py CHANGED
@@ -39,7 +39,7 @@ class FieldGroupManager:
39
39
  config: Union[dict,ConnectObject] = aepp.config.config_object,
40
40
  description:str="powered by aepp",
41
41
  full:bool=None,
42
- localFolder:str=None,
42
+ localFolder:str | list | None=None,
43
43
  sandbox:str=None,
44
44
  **kwargs
45
45
  )->None:
@@ -71,13 +71,16 @@ class FieldGroupManager:
71
71
  elif config is not None and localFolder is None:
72
72
  self.schemaAPI = Schema(config=config)
73
73
  elif localFolder is not None:
74
- self.localfolder = Path(localFolder)
75
- self.datatypeFolder = self.localfolder / 'datatype'
76
- self.datatypeGlobalFolder = self.datatypeFolder / 'global'
77
- self.fieldgroupFolder = self.localfolder / 'fieldgroup'
78
- self.fieldgroupGlobalFolder = self.fieldgroupFolder / 'global'
79
- self.descriptorFolder = self.localfolder / 'descriptor'
80
- if self.localfolder.exists() is False:
74
+ if isinstance(localFolder, str):
75
+ self.localfolder = [Path(localFolder)]
76
+ elif isinstance(localFolder, list):
77
+ self.localfolder = [Path(folder) for folder in localFolder]
78
+ self.datatypeFolder = [folder / 'datatype' for folder in self.localfolder]
79
+ self.datatypeGlobalFolder = [folder / 'global' for folder in self.datatypeFolder]
80
+ self.fieldgroupFolder = [folder / 'fieldgroup' for folder in self.localfolder]
81
+ self.fieldgroupGlobalFolder = [folder / 'global' for folder in self.fieldgroupFolder]
82
+ self.descriptorFolder = [folder / 'descriptor' for folder in self.localfolder]
83
+ if any([folder.exists() is False for folder in self.localfolder]):
81
84
  raise Exception(f"The local folder {self.localfolder} does not exist. Please create it and extract your sandbox before using it.")
82
85
  self.schemaAPI = None
83
86
  if self.schemaAPI is not None:
@@ -95,9 +98,11 @@ class FieldGroupManager:
95
98
  if fieldGroup.get('meta:tenantNamespace') is not None:
96
99
  self.tenantId = fieldGroup.get('meta:tenantNamespace')
97
100
  elif self.localfolder is not None:
98
- config_json = json.load(FileIO(self.localfolder / 'config.json'))
99
- if config_json.get('tenantId',None) is not None:
100
- self.tenantId = config_json.get('tenantId')
101
+ for folder in self.localfolder:
102
+ config_json = json.load(FileIO(folder / 'config.json'))
103
+ if config_json.get('tenantId',None) is not None:
104
+ self.tenantId = config_json.get('tenantId')
105
+ break
101
106
  else:### Should not be a problem as the element without a tenantId are not supposed to change
102
107
  self.tenantId = " "
103
108
  if fieldGroup is not None:
@@ -126,28 +131,40 @@ class FieldGroupManager:
126
131
  self.fieldGroup = tmp_def
127
132
  self.EDITABLE = False
128
133
  elif self.localfolder is not None:
129
- for json_file in self.fieldgroupFolder.glob('*.json'):
130
- tmp_def = json.load(FileIO(json_file))
131
- if tmp_def.get('$id') == fieldGroup['$id'] or tmp_def.get('meta:altId') == fieldGroup.get('meta:altId') or tmp_def.get('title') == fieldGroup.get('title'):
132
- self.fieldGroup = tmp_def
133
- if self.tenantId[1:] in self.fieldGroup.get('$id'): ## custom field group
134
- if '/datatypes/' in str(self.fieldGroup):
135
- dataTypeSearch = f"(https://ns.adobe.com/{self.tenantId[1:]}/datatypes/[0-9a-z]+?)'"
136
- dataTypes = re.findall(dataTypeSearch,str(self.fieldGroup))
137
- for dt in dataTypes:
138
- dt_manager = DataTypeManager(dt,localFolder=self.localfolder,sandbox=self.sandbox,tenantId=self.tenantId)
139
- self.dataTypes[dt_manager.id] = dt_manager.title
140
- self.dataTypeManagers[dt_manager.title] = dt_manager
141
- else: ## OOTB field group
142
- if 'properties' in self.fieldGroup.keys():
143
- self.fieldGroup['definitions'] = self.fieldGroup['properties']
144
- if self.fieldGroup == {}:
145
- for json_file in self.fieldgroupGlobalFolder.glob('*.json'):
134
+ found = False
135
+ for folder in self.fieldgroupFolder:
136
+ for json_file in folder.glob('*.json'):
146
137
  tmp_def = json.load(FileIO(json_file))
147
138
  if tmp_def.get('$id') == fieldGroup['$id'] or tmp_def.get('meta:altId') == fieldGroup.get('meta:altId') or tmp_def.get('title') == fieldGroup.get('title'):
148
139
  self.fieldGroup = tmp_def
149
- if 'properties' in self.fieldGroup.keys():
150
- self.fieldGroup['definitions'] = self.fieldGroup['properties']
140
+ if self.tenantId[1:] in self.fieldGroup.get('$id'): ## custom field group
141
+ if '/datatypes/' in str(self.fieldGroup):
142
+ dataTypeSearch = f"(https://ns.adobe.com/{self.tenantId[1:]}/datatypes/[0-9a-z]+?)'"
143
+ dataTypes = re.findall(dataTypeSearch,str(self.fieldGroup))
144
+ for dt in dataTypes:
145
+ dt_manager = DataTypeManager(dt,localFolder=self.localfolder,sandbox=self.sandbox,tenantId=self.tenantId)
146
+ self.dataTypes[dt_manager.id] = dt_manager.title
147
+ self.dataTypeManagers[dt_manager.title] = dt_manager
148
+ else: ## OOTB field group
149
+ if 'properties' in self.fieldGroup.keys():
150
+ self.fieldGroup['definitions'] = self.fieldGroup['properties']
151
+ found = True
152
+ break
153
+ if found:
154
+ break
155
+ if self.fieldGroup == {}:
156
+ found = False
157
+ for folder in self.fieldgroupGlobalFolder:
158
+ for json_file in folder.glob('*.json'):
159
+ tmp_def = json.load(FileIO(json_file))
160
+ if tmp_def.get('$id') == fieldGroup['$id'] or tmp_def.get('meta:altId') == fieldGroup.get('meta:altId') or tmp_def.get('title') == fieldGroup.get('title'):
161
+ self.fieldGroup = tmp_def
162
+ if 'properties' in self.fieldGroup.keys():
163
+ self.fieldGroup['definitions'] = self.fieldGroup['properties']
164
+ found = True
165
+ break
166
+ if found:
167
+ break
151
168
  self.EDITABLE = False
152
169
  else: ## if definitions key not present
153
170
  if 'properties' in self.fieldGroup.keys():
@@ -166,19 +183,24 @@ class FieldGroupManager:
166
183
  self.fieldGroup = self.schemaAPI.getFieldGroup(self.fieldGroup['$id'],full=True)
167
184
  self.EDITABLE = True
168
185
  elif self.localfolder is not None: ## looking into local folder
169
- for json_file in self.fieldgroupFolder.glob('*.json'): ## only custom Field groups: TO DO check for OOTB FG without definition
170
- tmp_def = json.load(FileIO(json_file))
171
- if tmp_def.get('$id') == fieldGroup['$id'] or tmp_def.get('meta:altId') == fieldGroup.get('meta:altId') or tmp_def.get('title') == fieldGroup.get('title'):
172
- self.fieldGroup = tmp_def
173
- if self.tenantId[1:] in self.fieldGroup.get('$id'): ## custom field group
174
- if '/datatypes/' in str(self.fieldGroup):
175
- dataTypeSearch = f"(https://ns.adobe.com/{self.tenantId[1:]}/datatypes/[0-9a-z]+?)'"
176
- dataTypes = re.findall(dataTypeSearch,str(self.fieldGroup))
177
- for dt in dataTypes:
178
- dt_manager = DataTypeManager(dt,localFolder=self.localfolder,sandbox=self.sandbox,tenantId=self.tenantId)
179
- self.dataTypes[dt_manager.id] = dt_manager.title
180
- self.dataTypeManagers[dt_manager.title] = dt_manager
181
-
186
+ found = False
187
+ for folder in self.fieldgroupFolder:
188
+ for json_file in folder.glob('*.json'): ## only custom Field groups: TO DO check for OOTB FG without definition
189
+ tmp_def = json.load(FileIO(json_file))
190
+ if tmp_def.get('$id') == fieldGroup['$id'] or tmp_def.get('meta:altId') == fieldGroup.get('meta:altId') or tmp_def.get('title') == fieldGroup.get('title'):
191
+ self.fieldGroup = tmp_def
192
+ if self.tenantId[1:] in self.fieldGroup.get('$id'): ## custom field group
193
+ if '/datatypes/' in str(self.fieldGroup):
194
+ dataTypeSearch = f"(https://ns.adobe.com/{self.tenantId[1:]}/datatypes/[0-9a-z]+?)'"
195
+ dataTypes = re.findall(dataTypeSearch,str(self.fieldGroup))
196
+ for dt in dataTypes:
197
+ dt_manager = DataTypeManager(dt,localFolder=self.localfolder,sandbox=self.sandbox,tenantId=self.tenantId)
198
+ self.dataTypes[dt_manager.id] = dt_manager.title
199
+ self.dataTypeManagers[dt_manager.title] = dt_manager
200
+ found = True
201
+ break
202
+ if found:
203
+ break
182
204
  else:
183
205
  raise ValueError("The field group definition provided does not contains the 'definitions' key. Please check the field group.")
184
206
  else:
@@ -208,26 +230,38 @@ class FieldGroupManager:
208
230
  self.fieldGroup = tmp_def
209
231
  self.EDITABLE = False
210
232
  elif self.localfolder is not None:
211
- for json_file in self.fieldgroupFolder.glob('*.json'):
212
- tmp_def = json.load(FileIO(json_file))
213
- if tmp_def.get('$id') == fieldGroup or tmp_def.get('meta:altId') == fieldGroup or tmp_def.get('title') == fieldGroup:
214
- self.fieldGroup = tmp_def
215
- if tmp_def.get('meta:tenantNamespace',None) is not None:
216
- self.tenantId = tmp_def.get('meta:tenantNamespace')
217
- if '/datatypes/' in str(self.fieldGroup):
218
- dataTypeSearch = f"(https://ns.adobe.com/{self.tenantId[1:]}/datatypes/[0-9a-z]+?)'"
219
- dataTypes = re.findall(dataTypeSearch,str(self.fieldGroup.get('definitions')))
220
- for file in self.datatypeFolder.glob('*.json'):
221
- tmp_def = json.load(FileIO(file))
222
- if tmp_def.get('$id') in dataTypes or tmp_def.get('meta:altId') in dataTypes:
223
- dt_manager = DataTypeManager(tmp_def,localFolder=self.localfolder,sandbox=self.sandbox,tenantId=self.tenantId)
224
- self.dataTypes[dt_manager.id] = dt_manager.title
225
- self.dataTypeManagers[dt_manager.title] = dt_manager
226
- if self.fieldGroup == {}: ## looking into the global folder
227
- for json_file in self.fieldgroupGlobalFolder.glob('*.json'):
233
+ found = False
234
+ for folder in self.fieldgroupFolder:
235
+ for json_file in folder.glob('*.json'):
228
236
  tmp_def = json.load(FileIO(json_file))
229
237
  if tmp_def.get('$id') == fieldGroup or tmp_def.get('meta:altId') == fieldGroup or tmp_def.get('title') == fieldGroup:
230
- self.fieldGroup = tmp_def
238
+ self.fieldGroup = tmp_def
239
+ if tmp_def.get('meta:tenantNamespace',None) is not None:
240
+ self.tenantId = tmp_def.get('meta:tenantNamespace')
241
+ if '/datatypes/' in str(self.fieldGroup):
242
+ dataTypeSearch = f"(https://ns.adobe.com/{self.tenantId[1:]}/datatypes/[0-9a-z]+?)'"
243
+ dataTypes = re.findall(dataTypeSearch,str(self.fieldGroup.get('definitions')))
244
+ for file in self.datatypeFolder.glob('*.json'):
245
+ tmp_def = json.load(FileIO(file))
246
+ if tmp_def.get('$id') in dataTypes or tmp_def.get('meta:altId') in dataTypes:
247
+ dt_manager = DataTypeManager(tmp_def,localFolder=self.localfolder,sandbox=self.sandbox,tenantId=self.tenantId)
248
+ self.dataTypes[dt_manager.id] = dt_manager.title
249
+ self.dataTypeManagers[dt_manager.title] = dt_manager
250
+ found = True
251
+ break
252
+ if found:
253
+ break
254
+ if self.fieldGroup == {}: ## looking into the global folder
255
+ found = False
256
+ for folder in self.fieldgroupGlobalFolder:
257
+ for json_file in folder.glob('*.json'):
258
+ tmp_def = json.load(FileIO(json_file))
259
+ if tmp_def.get('$id') == fieldGroup or tmp_def.get('meta:altId') == fieldGroup or tmp_def.get('title') == fieldGroup:
260
+ self.fieldGroup = tmp_def
261
+ found = True
262
+ break
263
+ if found:
264
+ break
231
265
  else:
232
266
  raise ValueError("the element pass is not a field group definition")
233
267
  else:
@@ -1689,10 +1723,11 @@ class FieldGroupManager:
1689
1723
  res = self.schemaAPI.getDescriptors(prop=f"xdm:sourceSchema=={self.id}")
1690
1724
  elif self.localfolder is not None:
1691
1725
  res = []
1692
- for json_file in self.descriptorFolder.glob('*.json'):
1693
- tmp_def = json.load(FileIO(json_file))
1694
- if tmp_def.get('xdm:sourceSchema') == self.id:
1695
- res.append(tmp_def)
1726
+ for folder in self.descriptorFolder:
1727
+ for json_file in folder.glob('*.json'):
1728
+ tmp_def = json.load(FileIO(json_file))
1729
+ if tmp_def.get('xdm:sourceSchema') == self.id:
1730
+ res.append(tmp_def)
1696
1731
  else:
1697
1732
  raise Exception("Require a schema API connection or local folder. Pass the instance of a Schema class or import a configuration file.")
1698
1733
  return res
aepp/schemamanager.py CHANGED
@@ -39,7 +39,7 @@ class SchemaManager:
39
39
  schemaClass:str="https://ns.adobe.com/xdm/context/profile",
40
40
  config: Union[dict,ConnectObject] = aepp.config.config_object,
41
41
  description : str = "powered by aepp",
42
- localFolder:str=None,
42
+ localFolder:str|list|None=None,
43
43
  sandbox:str=None,
44
44
  **kwargs
45
45
  )->None:
@@ -57,7 +57,7 @@ class SchemaManager:
57
57
  Possible default value: "https://ns.adobe.com/xdm/context/experienceevent", "https://ns.adobe.com/xdm/context/segmentdefinition"
58
58
  config : OPTIONAL : The config object in case you want to override the configuration.
59
59
  description : OPTIONAL : To provide a description to your schema
60
- localFolder : OPTIONAL : If you want to use local storage to create all the connections between schema and field groups, classes and datatypes
60
+ localFolder : OPTIONAL : If you want to use local storage to create all the connections between schema and field groups, classes and datatypes. Can be a set of folders.
61
61
  sandbox : OPTIONAL : If you use localFolder, you can specific the sandbox.
62
62
  """
63
63
  self.fieldGroupIds=[]
@@ -72,17 +72,20 @@ class SchemaManager:
72
72
  elif config is not None and localFolder is None:
73
73
  self.schemaAPI = Schema(config=config)
74
74
  elif localFolder is not None:
75
- self.localfolder = Path(localFolder)
76
- if self.localfolder.exists() is False:
77
- raise Exception(f"The local folder {self.localfolder} does not exist. Please create it and extract your sandbox before using it.")
75
+ if isinstance(localFolder, str):
76
+ self.localfolder = [Path(localFolder)]
77
+ else:
78
+ self.localfolder = [Path(folder) for folder in localFolder]
79
+ if any([folder.exists() is False for folder in self.localfolder]):
80
+ raise Exception(f"One of the local folders {self.localfolder} does not exist. Please create it and extract your sandbox before using it.")
78
81
  self.schemaAPI = None
79
- self.schemaFolder = self.localfolder / 'schema'
80
- self.fieldgroupFolder = self.localfolder / 'fieldgroup'
81
- self.fieldgroupGlobalFolder = self.fieldgroupFolder / 'global'
82
- self.classFolder = self.localfolder / 'class'
83
- self.descriptorFolder = self.localfolder / 'descriptor'
84
- if self.schemaFolder.exists() is False or self.fieldgroupFolder.exists() is False or self.classFolder.exists() is False:
85
- raise Exception(f"{self.schemaFolder} or {self.fieldgroupFolder} or {self.classFolder} does not exist. Please create it and extract your sandbox before using it.")
82
+ self.schemaFolder = [folder / 'schema' for folder in self.localfolder]
83
+ self.fieldgroupFolder = [folder / 'fieldgroup' for folder in self.localfolder]
84
+ self.fieldgroupGlobalFolder = [folder / 'global' for folder in self.fieldgroupFolder]
85
+ self.classFolder = [folder / 'class' for folder in self.localfolder]
86
+ self.descriptorFolder = [folder / 'descriptor' for folder in self.localfolder]
87
+ if any([folder.exists() is False for folder in self.schemaFolder]) or any([folder.exists() is False for folder in self.fieldgroupFolder]) or any([folder.exists() is False for folder in self.classFolder]):
88
+ raise Exception(f"One of the folders {self.schemaFolder} or {self.fieldgroupFolder} or {self.classFolder} does not exist. Please create it and extract your sandbox before using it.")
86
89
  else:
87
90
  raise Exception("You need to provide a schemaAPI instance or a config object to connect to the API or a local folder to use the local storage")
88
91
  if self.schemaAPI is not None:
@@ -99,9 +102,11 @@ class SchemaManager:
99
102
  elif kwargs.get('tenantId') is not None:
100
103
  self.tenantId = f"{kwargs.get('tenantId')}"
101
104
  elif self.localfolder is not None:
102
- config_json = json.load(FileIO(self.localfolder / 'config.json'))
103
- if config_json.get('tenantId',None) is not None:
104
- self.tenantId = config_json.get('tenantId')
105
+ for folder in self.localfolder:
106
+ config_json = json.load(FileIO(folder / 'config.json'))
107
+ if config_json.get('tenantId',None) is not None:
108
+ self.tenantId = config_json.get('tenantId')
109
+ break
105
110
  else: ### Should not be a problem as the element without a tenantId are not supposed to change
106
111
  self.tenantId = " "
107
112
  if type(schema) == dict:
@@ -113,32 +118,47 @@ class SchemaManager:
113
118
  if self.schemaAPI is not None:
114
119
  self.schema = self.schemaAPI.getSchema(self.schema['$id'],full=False,schema_type='xed')
115
120
  elif self.localfolder is not None:
116
- for json_file in self.schemaFolder.glob('*.json'):
117
- tmp_def = json.load(FileIO(json_file))
118
- if tmp_def.get('$id') == self.schema['$id'] or tmp_def.get('meta:altId') == self.schema.get('meta:altId') or tmp_def.get('title') == self.schema.get('title'):
119
- self.schema = tmp_def
120
- if self.schema.get('meta:tenantNamespace') is not None:
121
- self.tenantId = f"_{self.schema.get('meta:tenantNamespace')}"
121
+ found = False
122
+ for folder in self.schemaFolder:
123
+ for json_file in folder.glob('*.json'):
124
+ tmp_def = json.load(FileIO(json_file))
125
+ if tmp_def.get('$id') == self.schema['$id'] or tmp_def.get('meta:altId') == self.schema.get('meta:altId') or tmp_def.get('title') == self.schema.get('title'):
126
+ self.schema = tmp_def
127
+ if self.schema.get('meta:tenantNamespace') is not None:
128
+ self.tenantId = f"_{self.schema.get('meta:tenantNamespace')}"
129
+ found = True
130
+ break
131
+ if found:
122
132
  break
123
133
  self.fieldGroupIds = [obj['$ref'] for obj in allOf if ('/mixins/' in obj['$ref'] or '/experience/' in obj['$ref'] or '/context/' in obj['$ref']) and obj['$ref'] != self.classId]
124
134
  self.classIds = [self.classId]
125
135
  for ref in self.fieldGroupIds:
126
136
  if '/mixins/' in ref and self.tenantId[1:] in ref:
127
137
  if self.localfolder is not None:
128
- for json_file in self.fieldgroupFolder.glob('*.json'):
129
- tmp_def = json.load(FileIO(json_file))
130
- if tmp_def.get('$id') == ref:
131
- definition = tmp_def
138
+ found = False
139
+ for folder in self.fieldgroupFolder:
140
+ for json_file in folder.glob('*.json'):
141
+ tmp_def = json.load(FileIO(json_file))
142
+ if tmp_def.get('$id') == ref:
143
+ definition = tmp_def
144
+ found = True
145
+ break
146
+ if found:
132
147
  break
133
148
  elif self.schemaAPI is not None:
134
149
  definition = self.schemaAPI.getFieldGroup(ref,full=False)
135
150
  fgM = FieldGroupManager(fieldGroup=definition,schemaAPI=self.schemaAPI,localFolder=localFolder,tenantId=self.tenantId,sandbox=self.sandbox)
136
151
  else:
137
152
  if self.localfolder is not None:
138
- for json_file in self.fieldgroupGlobalFolder.glob('*.json'):
139
- tmp_def = json.load(FileIO(json_file))
140
- if tmp_def.get('$id') == ref:
141
- definition = tmp_def
153
+ found = False
154
+ for folder in self.fieldgroupFolder:
155
+ for json_file in folder.glob('*.json'):
156
+ tmp_def = json.load(FileIO(json_file))
157
+ if tmp_def.get('$id') == ref:
158
+ definition = tmp_def
159
+ found = True
160
+ break
161
+ if found:
142
162
  break
143
163
  elif self.schemaAPI is not None:
144
164
  definition = self.schemaAPI.getFieldGroup(ref,full=False)
@@ -158,17 +178,22 @@ class SchemaManager:
158
178
  self.fieldGroupIds = [obj.get('$ref','') for obj in allOf if ('/mixins/' in obj.get('$ref','') or '/experience/' in obj.get('$ref','') or '/context/' in obj.get('$ref','')) and obj.get('$ref','') != self.classId]
159
179
  self.classIds = [self.classId]
160
180
  elif localFolder is not None:
161
- for json_file in self.schemaFolder.glob('*.json'):
162
- tmp_def = json.load(FileIO(json_file))
163
- if tmp_def.get('$id') == schema or tmp_def.get('meta:altId') == schema or schema == tmp_def.get('title'):
164
- self.schema = tmp_def
165
- self.requiredFields = set([el.replace('@','_').replace('xdm:','') for el in self.schema.get('required',[])])
166
- self.__setAttributes__(self.schema)
167
- allOf = self.schema.get("allOf",[])
168
- self.fieldGroupIds = [obj.get('$ref','') for obj in allOf if ('/mixins/' in obj.get('$ref','') or '/experience/' in obj.get('$ref','') or '/context/' in obj.get('$ref','')) and obj.get('$ref','') != self.classId]
169
- self.classIds = [self.classId]
170
- if self.schema.get('meta:tenantNamespace') is not None:
171
- self.tenantId = self.schema.get('meta:tenantNamespace')
181
+ found = False
182
+ for folder in self.schemaFolder:
183
+ for json_file in folder.glob('*.json'):
184
+ tmp_def = json.load(FileIO(json_file))
185
+ if tmp_def.get('$id') == schema or tmp_def.get('meta:altId') == schema or schema == tmp_def.get('title'):
186
+ self.schema = tmp_def
187
+ self.requiredFields = set([el.replace('@','_').replace('xdm:','') for el in self.schema.get('required',[])])
188
+ self.__setAttributes__(self.schema)
189
+ allOf = self.schema.get("allOf",[])
190
+ self.fieldGroupIds = [obj.get('$ref','') for obj in allOf if ('/mixins/' in obj.get('$ref','') or '/experience/' in obj.get('$ref','') or '/context/' in obj.get('$ref','')) and obj.get('$ref','') != self.classId]
191
+ self.classIds = [self.classId]
192
+ if self.schema.get('meta:tenantNamespace') is not None:
193
+ self.tenantId = self.schema.get('meta:tenantNamespace')
194
+ found = True
195
+ break
196
+ if found:
172
197
  break
173
198
  else:
174
199
  raise Exception("You need to provide a schemaAPI instance or a localFolder to use the local storage")
@@ -178,31 +203,51 @@ class SchemaManager:
178
203
  if self.schemaAPI is not None:
179
204
  definition = self.schemaAPI.getFieldGroup(ref,full=False)
180
205
  elif self.localfolder is not None:
181
- for json_file in self.fieldgroupFolder.glob('*.json'):
182
- tmp_def = json.load(FileIO(json_file))
183
- if tmp_def.get('$id') == ref:
184
- definition = tmp_def
185
- break
186
- if definition is None:
187
- for json_file in self.fieldgroupGlobalFolder.glob('*.json'):
206
+ found = False
207
+ for folder in self.fieldgroupFolder:
208
+ for json_file in folder.glob('*.json'):
188
209
  tmp_def = json.load(FileIO(json_file))
189
210
  if tmp_def.get('$id') == ref:
190
211
  definition = tmp_def
212
+ found = True
213
+ break
214
+ if found:
215
+ break
216
+ found = False
217
+ if definition is None:
218
+ for folder in self.fieldgroupGlobalFolder:
219
+ for json_file in folder.glob('*.json'):
220
+ tmp_def = json.load(FileIO(json_file))
221
+ if tmp_def.get('$id') == ref:
222
+ definition = tmp_def
223
+ found = True
224
+ break
225
+ if found:
191
226
  break
192
227
  else:
193
228
  if self.schemaAPI is not None:
194
229
  definition = self.schemaAPI.getFieldGroup(ref,full=False)
195
230
  elif self.localfolder is not None:
196
- for json_file in self.fieldgroupFolder.glob('*.json'):
197
- tmp_def = json.load(FileIO(json_file))
198
- if tmp_def.get('$id') == ref:
199
- definition = tmp_def
200
- break
201
- if definition is None:
202
- for json_file in self.fieldgroupGlobalFolder.glob('*.json'):
231
+ found = False
232
+ for folder in self.fieldgroupFolder:
233
+ for json_file in folder.glob('*.json'):
203
234
  tmp_def = json.load(FileIO(json_file))
204
235
  if tmp_def.get('$id') == ref:
205
236
  definition = tmp_def
237
+ found = True
238
+ break
239
+ if found:
240
+ break
241
+ found = False
242
+ if definition is None:
243
+ for folder in self.fieldgroupGlobalFolder:
244
+ for json_file in folder.glob('*.json'):
245
+ tmp_def = json.load(FileIO(json_file))
246
+ if tmp_def.get('$id') == ref:
247
+ definition = tmp_def
248
+ found = True
249
+ break
250
+ if found:
206
251
  break
207
252
  if 'properties' in definition.keys():
208
253
  definition['definitions'] = definition['properties']
@@ -210,12 +255,17 @@ class SchemaManager:
210
255
  self.fieldGroupsManagers[fgM.title] = fgM
211
256
  for clas in self.classIds:
212
257
  if self.localfolder is not None:
213
- for json_file in self.classFolder.glob('*.json'):
214
- tmp_def = json.load(FileIO(json_file))
215
- if tmp_def.get('$id') == clas:
216
- self.classId = tmp_def['$id']
217
- self.schemaClass = tmp_def['$id']
218
- clsM = ClassManager(tmp_def,schemaAPI=self.schemaAPI,localFolder=localFolder,tenantId=self.tenantId,sandbox=self.sandbox)
258
+ found = False
259
+ for folder in self.classFolder:
260
+ for json_file in folder.glob('*.json'):
261
+ tmp_def = json.load(FileIO(json_file))
262
+ if tmp_def.get('$id') == clas:
263
+ self.classId = tmp_def['$id']
264
+ self.schemaClass = tmp_def['$id']
265
+ clsM = ClassManager(tmp_def,schemaAPI=self.schemaAPI,localFolder=localFolder,tenantId=self.tenantId,sandbox=self.sandbox)
266
+ found = True
267
+ break
268
+ if found:
219
269
  break
220
270
  elif self.schemaAPI is not None:
221
271
  clsM = ClassManager(clas,schemaAPI=self.schemaAPI,localFolder=localFolder,tenantId=self.tenantId,sandbox=self.sandbox)
@@ -243,20 +293,31 @@ class SchemaManager:
243
293
  definition = self.schemaAPI.getFieldGroup(fgId,full=False)
244
294
  elif self.localfolder is not None:
245
295
  definition = None
246
- fieldGroupPath = self.localfolder / 'fieldgroup'
247
- if fieldGroupPath.exists() is False:
248
- raise Exception(f"The local folder {fieldGroupPath} does not exist. Please create it and extract your sandbox before using it.")
249
- for json_file in fieldGroupPath.glob('*.json'):
250
- tmp_def = json.load(FileIO(json_file))
251
- if tmp_def.get('$id') == fgId:
252
- definition = tmp_def
253
- break
254
- if definition is None:
255
- for json_file in self.fieldgroupGlobalFolder.glob('*.json'):
296
+ found = False
297
+ for fieldGroupPath in self.fieldgroupFolder:
298
+ if fieldGroupPath.exists() is False:
299
+ raise Exception(f"The local folder {fieldGroupPath} does not exist. Please create it and extract your sandbox before using it.")
300
+ for json_file in fieldGroupPath.glob('*.json'):
256
301
  tmp_def = json.load(FileIO(json_file))
257
- if tmp_def.get('$id') == ref:
302
+ if tmp_def.get('$id') == fgId:
258
303
  definition = tmp_def
259
- break
304
+ found = True
305
+ break
306
+ if found:
307
+ break
308
+ if definition is None:
309
+ found = False
310
+ for fieldGroupPath in self.fieldgroupGlobalFolder:
311
+ if fieldGroupPath.exists() is False:
312
+ raise Exception(f"The local folder {fieldGroupPath} does not exist. Please create it and extract your sandbox before using it.")
313
+ for json_file in fieldGroupPath.glob('*.json'):
314
+ tmp_def = json.load(FileIO(json_file))
315
+ if tmp_def.get('$id') == fgId:
316
+ definition = tmp_def
317
+ found = True
318
+ break
319
+ if found:
320
+ break
260
321
  fgM = FieldGroupManager(definition,schemaAPI=self.schemaAPI, localFolder=localFolder,tenantId=self.tenantId,sandbox=self.sandbox)
261
322
  self.fieldGroupsManagers[fgM.title] = fgM
262
323
  elif fieldGroups[0] == dict:
@@ -805,12 +866,13 @@ class SchemaManager:
805
866
  elif self.localfolder is not None:
806
867
  res = []
807
868
  fieldGroupsIds = [fg.id for fg in list(self.fieldGroupsManagers.values())]
808
- for json_file in self.descriptorFolder.glob('*.json'):
809
- tmp_def = json.load(FileIO(json_file))
810
- if tmp_def.get('xdm:sourceSchema') == self.id:
811
- res.append(tmp_def)
812
- elif tmp_def.get('xdm:sourceSchema') in fieldGroupsIds:
813
- res.append(tmp_def)
869
+ for folder in self.descriptorFolder:
870
+ for json_file in folder.glob('*.json'):
871
+ tmp_def = json.load(FileIO(json_file))
872
+ if tmp_def.get('xdm:sourceSchema') == self.id:
873
+ res.append(tmp_def)
874
+ elif tmp_def.get('xdm:sourceSchema') in fieldGroupsIds:
875
+ res.append(tmp_def)
814
876
  else:
815
877
  raise Exception("No API connection set and no local folder provided. No descriptors can be retrieved.")
816
878
  return res
aepp/synchronizer.py CHANGED
@@ -20,7 +20,7 @@ from .configs import ConnectObject
20
20
 
21
21
  class Synchronizer:
22
22
  ## TO DO -> Add support for local environment
23
- def __init__(self,targets:list=None,config:'ConnectObject'=None,baseSandbox:str=None,region:str='nld2',localFolder:str=None):
23
+ def __init__(self,targets:list=None,config:'ConnectObject'=None,baseSandbox:str=None,region:str='nld2',localFolder:str|list|None=None):
24
24
  """
25
25
  Setup the synchronizor object with the base sandbox and target sandbox.
26
26
  Arguments:
@@ -56,24 +56,30 @@ class Synchronizer:
56
56
  self.baseSandbox = baseSandbox
57
57
  elif localFolder is not None:
58
58
  self.baseConfig = None
59
- self.localfolder = Path(localFolder)
60
- self.classFolder = self.localfolder / 'class'
61
- self.schemaFolder = self.localfolder / 'schema'
62
- self.fieldgroupFolder = self.localfolder / 'fieldgroup'
63
- self.fieldgroupGlobalFolder = self.fieldgroupFolder / 'global'
64
- self.datatypeFolder = self.localfolder / 'datatype'
65
- self.datatypeGlobalFolder = self.datatypeFolder / 'global'
66
- self.identityFolder = self.localfolder / 'identity'
67
- self.datasetFolder = self.localfolder / 'dataset'
68
- self.descriptorFolder = self.localfolder / 'descriptor'
69
- self.mergePolicyFolder = self.localfolder / 'mergepolicy'
70
- self.audienceFolder = self.localfolder / 'audience'
59
+ if isinstance(localFolder, str):
60
+ self.localfolder = [Path(localFolder)]
61
+ else:
62
+ self.localfolder = [Path(folder) for folder in localFolder]
63
+ self.classFolder = [folder / 'class' for folder in self.localfolder]
64
+ self.schemaFolder = [folder / 'schema' for folder in self.localfolder]
65
+ self.fieldgroupFolder = [folder / 'fieldgroup' for folder in self.localfolder]
66
+ self.fieldgroupGlobalFolder = [folder / 'global' for folder in self.fieldgroupFolder]
67
+ self.datatypeFolder = [folder / 'datatype' for folder in self.localfolder]
68
+ self.datatypeGlobalFolder = [folder / 'global' for folder in self.datatypeFolder]
69
+ self.identityFolder = [folder / 'identity' for folder in self.localfolder]
70
+ self.datasetFolder = [folder / 'dataset' for folder in self.localfolder]
71
+ self.descriptorFolder = [folder / 'descriptor' for folder in self.localfolder]
72
+ self.mergePolicyFolder = [folder / 'mergepolicy' for folder in self.localfolder]
73
+ self.audienceFolder = [folder / 'audience' for folder in self.localfolder]
71
74
  if baseSandbox is not None:
72
75
  self.baseSandbox = baseSandbox
73
76
  else:
74
- with open(self.localfolder / 'config.json','r') as f:
75
- local_config = json.load(f)
76
- self.baseSandbox = local_config.get('sandbox',None)
77
+ for folder in self.localfolder:
78
+ with open(folder / 'config.json','r') as f:
79
+ local_config = json.load(f)
80
+ if 'baseSandbox' in local_config.keys():
81
+ self.baseSandbox = local_config['baseSandbox']
82
+ break
77
83
  self.dict_targetsConfig = {target: aepp.configure(org_id=config_object['org_id'],client_id=config_object['client_id'],scopes=config_object['scopes'],secret=config_object['secret'],sandbox=target,connectInstance=True) for target in targets}
78
84
  self.region = region
79
85
  self.dict_baseComponents = {'schema':{},'class':{},'fieldgroup':{},'datatype':{},'datasets':{},'identities':{},"schemaDescriptors":{},'mergePolicy':{},'audience':{}}
@@ -163,11 +169,12 @@ class Synchronizer:
163
169
  if component in base_schema.data.schemas_altId.keys():## replacing name with altId
164
170
  component = base_schema.data.schemas_altId[component]
165
171
  if self.localfolder is not None:
166
- for file in self.schemaFolder.glob('*.json'):
167
- sc_file = json.load(FileIO(file))
168
- if sc_file['title'] == component or sc_file['$id'] == component or sc_file['meta:altId'] == component:
169
- component = sc_file
170
- break
172
+ for folder in self.schemaFolder:
173
+ for file in folder.glob('*.json'):
174
+ sc_file = json.load(FileIO(file))
175
+ if sc_file['title'] == component or sc_file['$id'] == component or sc_file['meta:altId'] == component:
176
+ component = sc_file
177
+ break
171
178
  component = schemamanager.SchemaManager(component,config=self.baseConfig,localFolder=self.localfolder,sandbox=self.baseSandbox)
172
179
  elif componentType == 'fieldgroup':
173
180
  if base_schema is not None:
@@ -175,11 +182,12 @@ class Synchronizer:
175
182
  if component in base_schema.data.fieldGroups_altId.keys():## replacing name with altId
176
183
  component = base_schema.data.fieldGroups_altId[component]
177
184
  if self.localfolder is not None:
178
- for file in self.fieldgroupFolder.glob('*.json'):
179
- fg_file = json.load(FileIO(file))
180
- if fg_file['title'] == component or fg_file['$id'] == component or fg_file['meta:altId'] == component:
181
- component = fg_file
182
- break
185
+ for folder in self.fieldgroupFolder:
186
+ for file in folder.glob('*.json'):
187
+ fg_file = json.load(FileIO(file))
188
+ if fg_file['title'] == component or fg_file['$id'] == component or fg_file['meta:altId'] == component:
189
+ component = fg_file
190
+ break
183
191
  component = fieldgroupmanager.FieldGroupManager(component,config=self.baseConfig,localFolder=self.localfolder,sandbox=self.baseSandbox)
184
192
  elif componentType == 'datatypes':
185
193
  datatypes = base_schema.getDataTypes()
@@ -187,11 +195,12 @@ class Synchronizer:
187
195
  if component in base_schema.data.dataTypes_altId.keys():## replacing name with altId
188
196
  component = base_schema.data.dataTypes_altId[component]
189
197
  if self.localfolder is not None:
190
- for file in self.datatypeFolder.glob('*.json'):
191
- dt_file = json.load(FileIO(file))
192
- if dt_file['title'] == component or dt_file['$id'] == component or dt_file['meta:altId'] == component:
193
- component = dt_file
194
- break
198
+ for folder in self.datatypeFolder:
199
+ for file in folder.glob('*.json'):
200
+ dt_file = json.load(FileIO(file))
201
+ if dt_file['title'] == component or dt_file['$id'] == component or dt_file['meta:altId'] == component:
202
+ component = dt_file
203
+ break
195
204
  component = datatypemanager.DataTypeManager(component,config=self.baseConfig,localFolder=self.localfolder,sandbox=self.baseSandbox)
196
205
  elif componentType == 'class':
197
206
  classes = base_schema.getClasses()
@@ -204,9 +213,10 @@ class Synchronizer:
204
213
  identities:list = id_base.getIdentities()
205
214
  elif self.localfolder is not None:
206
215
  identities = []
207
- for file in self.identityFolder.glob('*.json'):
208
- id_file = json.load(FileIO(file))
209
- identities.append(id_file)
216
+ for folder in self.identityFolder:
217
+ for file in folder.glob('*.json'):
218
+ id_file = json.load(FileIO(file))
219
+ identities.append(id_file)
210
220
  if component in [el['code'] for el in identities]:
211
221
  component = [el for el in identities if el['code'] == component][0]
212
222
  elif component in [el['name'] for el in identities]:
@@ -221,11 +231,12 @@ class Synchronizer:
221
231
  component = cat_base.data.ids[component]
222
232
  component = cat_base.getDataSet(component)
223
233
  elif self.localfolder is not None:
224
- for file in self.datasetFolder.glob('*.json'):
225
- ds_file = json.load(FileIO(file))
226
- if ds_file['id'] == component or ds_file['name'] == component:
227
- component = ds_file
228
- break
234
+ for folder in self.datasetFolder:
235
+ for file in folder.glob('*.json'):
236
+ ds_file = json.load(FileIO(file))
237
+ if ds_file['id'] == component or ds_file['name'] == component:
238
+ component = ds_file
239
+ break
229
240
  if len(component) == 1: ## if the component is the catalog API response {'key': {dataset definition}}
230
241
  component = component[list(component.keys())[0]] ## accessing the real dataset definition
231
242
  elif componentType == "mergepolicy":
@@ -235,11 +246,12 @@ class Synchronizer:
235
246
  if component in [el.get('id','') for el in base_mergePolicies] or component in [el.get('name','') for el in base_mergePolicies]:
236
247
  component = [el for el in base_mergePolicies if el.get('id','') == component or el.get('name','') == component][0]
237
248
  elif self.localfolder is not None:
238
- for file in self.mergePolicyFolder.glob('*.json'):
239
- mp_file = json.load(FileIO(file))
240
- if mp_file.get('id','') == component or mp_file.get('name','') == component:
241
- component = mp_file
242
- break
249
+ for folder in self.mergePolicyFolder:
250
+ for file in folder.glob('*.json'):
251
+ mp_file = json.load(FileIO(file))
252
+ if mp_file.get('id','') == component or mp_file.get('name','') == component:
253
+ component = mp_file
254
+ break
243
255
  elif componentType == 'audience':
244
256
  if self.baseConfig is not None:
245
257
  seg_base = segmentation.Segmentation(config=self.baseConfig)
@@ -247,11 +259,12 @@ class Synchronizer:
247
259
  if component in [el.get('id','') for el in base_audiences] or component in [el.get('name','') for el in base_audiences]:
248
260
  component = [el for el in base_audiences if el.get('id','') == component or el.get('name','') == component][0]
249
261
  elif self.localfolder is not None:
250
- for file in self.audienceFolder.glob('*.json'):
251
- au_file = json.load(FileIO(file))
252
- if au_file.get('id','') == component or au_file.get('name','') == component:
253
- component = au_file
254
- break
262
+ for folder in self.audienceFolder:
263
+ for file in folder.glob('*.json'):
264
+ au_file = json.load(FileIO(file))
265
+ if au_file.get('id','') == component or au_file.get('name','') == component:
266
+ component = au_file
267
+ break
255
268
  elif type(component) == dict:
256
269
  if 'meta:resourceType' in component.keys():
257
270
  componentType = component['meta:resourceType']
@@ -708,8 +721,9 @@ class Synchronizer:
708
721
  myschemas = baseSchemaAPI.getSchemas() ## to populate the data object
709
722
  elif self.localfolder is not None:
710
723
  myschemas = []
711
- for json_file in self.schemaFolder.glob('*.json'):
712
- myschemas.append(json.load(FileIO(json_file)))
724
+ for folder in self.schemaFolder:
725
+ for json_file in folder.glob('*.json'):
726
+ myschemas.append(json.load(FileIO(json_file)))
713
727
  target_descriptors = targetSchemaManager.getDescriptors()
714
728
  list_descriptors = []
715
729
  for baseDescriptor in base_descriptors:
@@ -761,10 +775,15 @@ class Synchronizer:
761
775
  if self.baseConfig is not None and self.localfolder is None:
762
776
  base_targetSchemaManager = schemamanager.SchemaManager(base_targetSchemaId,config=self.baseConfig)
763
777
  elif self.localfolder is not None:
764
- for file in self.schemaFolder.glob('*.json'):
765
- base_targetSchema = json.load(FileIO(file))
766
- if base_targetSchema['$id'] == base_targetSchemaId:
767
- base_targetSchemaManager = schemamanager.SchemaManager(base_targetSchema,config=self.baseConfig,localFolder=self.localfolder,sandbox=self.baseSandbox)
778
+ found = False
779
+ for folder in self.schemaFolder:
780
+ for file in folder.glob('*.json'):
781
+ base_targetSchema = json.load(FileIO(file))
782
+ if base_targetSchema['$id'] == base_targetSchemaId:
783
+ base_targetSchemaManager = schemamanager.SchemaManager(base_targetSchema,config=self.baseConfig,localFolder=self.localfolder,sandbox=self.baseSandbox)
784
+ found = True
785
+ break
786
+ if found:
768
787
  break
769
788
  self.__syncSchema__(base_targetSchemaManager,verbose=verbose)
770
789
  target_targetSchemaId = self.dict_targetComponents[targetSchemaManager.sandbox]['schema'][base_targetSchemaName].id
@@ -903,8 +922,9 @@ class Synchronizer:
903
922
  base_dataset_related_schemaName = [schemaName for schemaName,schemaId in baseSchemaAPI.data.schemas_id.items() if schemaId == base_dataset_related_schemaId][0]
904
923
  elif self.localfolder is not None:
905
924
  base_schemas = []
906
- for json_file in self.schemaFolder.glob('*.json'):
907
- base_schemas.append(json.load(FileIO(json_file)))
925
+ for folder in self.schemaFolder:
926
+ for json_file in folder.glob('*.json'):
927
+ base_schemas.append(json.load(FileIO(json_file)))
908
928
  base_dataset_related_schemaName = [sc['title'] for sc in base_schemas if sc['$id'] == base_dataset_related_schemaId][0]
909
929
  for target in self.dict_targetsConfig.keys():
910
930
  targetCatalog = catalog.Catalog(config=self.dict_targetsConfig[target])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aepp
3
- Version: 0.5.1.post1
3
+ Version: 0.5.2
4
4
  Summary: Package to manage AEP API endpoint and some helper functions
5
5
  Author-email: Julien Piccini <piccini.julien@gmail.com>
6
6
  License: Apache-2.0
@@ -22,6 +22,7 @@ Requires-Dist: tenacity
22
22
  Requires-Dist: deprecation
23
23
  Requires-Dist: datamodel-code-generator
24
24
  Requires-Dist: rich
25
+ Requires-Dist: matplotlib
25
26
  Dynamic: license-file
26
27
 
27
28
  # Adobe Experience Platform API made for humans
@@ -1,8 +1,8 @@
1
1
  aepp/__init__.py,sha256=rsU4OMu3pJIgy8emJAD6lhAfqH0-raZ6GyIMJanNBdM,27912
2
- aepp/__version__.py,sha256=e01d08qSqR9ezx14ZZOY_pkCgFXO6JmU6f0iOigM5Wk,23
2
+ aepp/__version__.py,sha256=wlmBF5A1gVspskZOpqNe0Xi1AY5ZRYF38SMV3fRd_LA,21
3
3
  aepp/accesscontrol.py,sha256=PB3FcrO4bvDjdNxjHx7p_20hp4ahBXewoOSxuTGMXC8,17423
4
4
  aepp/catalog.py,sha256=hK9m3SAP0fhgkYqu14Tcfq14qBhw54tLCOF0mH31b1M,68237
5
- aepp/classmanager.py,sha256=CTYGkg5ygB8HtRia6DfT9WLBqXJOVg7pSM9jBB25Bqw,64707
5
+ aepp/classmanager.py,sha256=16hx_hptg3PYwmezZCr9dLjvOkNSunih1PK3Q-iPoZY,66099
6
6
  aepp/config.py,sha256=232fcO8JaYJnS4glf8Ebnx9rCdHshZBVaVUbhoOAXkc,2543
7
7
  aepp/configs.py,sha256=5rRWJoUQDDaj3AAXWdKCZBZA_Xb7q1Hd58OkWhzwK34,16151
8
8
  aepp/connector.py,sha256=-EskFJm8Ki8A7_gpuNrydBBhz1-jZZz8QMB6gHQTZeA,27262
@@ -10,13 +10,13 @@ aepp/customerprofile.py,sha256=1yz7piGsSbxM2GaHqkCV-117Es6D1SthrNgnsVxH3Y8,49344
10
10
  aepp/dataaccess.py,sha256=oOERLSxMh2nYBFngPS1dFI_AG3W-DJXmMoUVUiKXJrw,16338
11
11
  aepp/dataprep.py,sha256=vMT4OYO8y6wsGRSjbJNQmgM048BiP3t1-RvKKglSiN4,27586
12
12
  aepp/datasets.py,sha256=hTioR0WyImB91mleCwDQ2FfunvqYi_RrxX_v-iW6N70,8778
13
- aepp/datatypemanager.py,sha256=Iz68Ttp3ogxAMoY3Od_KQybc-6m873Bhf3Z9V1WSHcE,82025
13
+ aepp/datatypemanager.py,sha256=5nP9EbJHd-q58aLFWKT2YyjRjpzI9QjTAo7G3lbMEWY,83540
14
14
  aepp/deletion.py,sha256=hzSWNPky7iVRUFEOrpKX72iKJO149Mxp2e3Q_JqN-Mk,11416
15
15
  aepp/destination.py,sha256=_-Hrzb_LUNaRrqR4Y3EZZuTisIs0nF3KH_GZpFjryrs,24348
16
16
  aepp/destinationinstanceservice.py,sha256=zEZbKi519cOOdxWMZ3mv9ccP6yjNAlNwqrQMlzW_gO4,5378
17
17
  aepp/edge.py,sha256=F2QZApmITObXB8hRWXftHBZ82KNqVZ7iSNuovT8qnk4,16041
18
18
  aepp/exportDatasetToDataLandingZone.py,sha256=C6jg3XttFC-0mswa3ypZb6qx3MCQ8_A_3kyKspurXJA,18629
19
- aepp/fieldgroupmanager.py,sha256=OQkSuGiSxU5ToSPqKmB_3Pmfg6aZjQMGL6LFnODqEiY,101560
19
+ aepp/fieldgroupmanager.py,sha256=4A7u3tx63HzcDiMqyZs5TRy-LN0Xsf7VGLdt1_exw2Q,103591
20
20
  aepp/flowservice.py,sha256=WizgwY6TYn1kiLxQt6Y3d7XgoLAb9imXrFXtt94hhog,107612
21
21
  aepp/hygiene.py,sha256=VEspnyu9eUlcK3wLeJYclaFaOWl5G5I5MRwmVA-RnUg,15385
22
22
  aepp/identity.py,sha256=E9MCIgntScMssduqKZqehT6FqSfTjWHcq7E7wESj3Zc,20833
@@ -27,18 +27,18 @@ aepp/privacyservice.py,sha256=V6BkJeZG1LDBCyEQm9Gx0i68iRHG6uxSJiVnXzkHapI,8790
27
27
  aepp/queryservice.py,sha256=wB9GiaMwJszNjqkYjkfEDUhdT2IoI22jA3Kt_6ki4Hk,62373
28
28
  aepp/sandboxes.py,sha256=UwlSFkO2OOmH--6ISz8rxwDu2LcLH1MPqoH7yOEAZHc,29363
29
29
  aepp/schema.py,sha256=aLYDM5lCANNddk-NZPNxCxazg9HpELalKlFxQz55dRs,123111
30
- aepp/schemamanager.py,sha256=hwItd4vXsPFeV25gX1Fbeiu07-BCg4z_VRQREMgJZ58,50738
30
+ aepp/schemamanager.py,sha256=G3JhVikWkaT14F8vORDfGJGivarvU2AgKO1RB-1pzdM,54117
31
31
  aepp/segmentation.py,sha256=oSgR2yx4nawYN5XAeHV_wefvmXEf0nb-bCguaDmp8F8,43555
32
32
  aepp/sensei.py,sha256=oYNy5BSWAEqsDkEexcQso6NfA6ntGGMnCOyHri0pJs8,7761
33
33
  aepp/som.py,sha256=XNm_Lu2wt2kpSSpldLptuER2eludFXeO9fI6i3iNCzo,34175
34
- aepp/synchronizer.py,sha256=s5azHDeNuFc_FroUsNjLw0n9J1namccsyJkFtZdsWIY,78016
34
+ aepp/synchronizer.py,sha256=3scwuimQJIBVdEqJ9fVsT1UgmFc9EkH3mpYxUwSoAOE,79363
35
35
  aepp/tags.py,sha256=t2qBallTcWR4IOXcDBmrPpqjbSay1z3E2bcRijzVm1s,17641
36
36
  aepp/utils.py,sha256=tG-YVXylm38-bynqfp5N_Mzyo7mhlZj-dLo7wLoO4tM,1200
37
37
  aepp/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- aepp/cli/__main__.py,sha256=L6yxbt32SkMmKGhw8qt350kDoan_pFjUAaWlQveL0mA,68092
39
- aepp-0.5.1.post1.dist-info/licenses/LICENSE,sha256=HjYTlfne3BbS5gNHzNqJ5COCiTQLUdf87QkzRyFbE4Y,10337
40
- aepp-0.5.1.post1.dist-info/METADATA,sha256=9cYtuO_5gPaKcxCVt543tCUAkq30EQ1xEJABFHkZ3TA,5317
41
- aepp-0.5.1.post1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
42
- aepp-0.5.1.post1.dist-info/entry_points.txt,sha256=e7HAumUTymoUiCuVRzFlcchennUBLcjxvuiimySF98Y,48
43
- aepp-0.5.1.post1.dist-info/top_level.txt,sha256=dtZJI8SzhWVgZRl68PHKZX_fD6amvDiFR-lqD9FSJvE,5
44
- aepp-0.5.1.post1.dist-info/RECORD,,
38
+ aepp/cli/__main__.py,sha256=9Hswyux5umZozY0NP6i1J7WWV81PrNj--pfOQ9REeL8,67968
39
+ aepp-0.5.2.dist-info/licenses/LICENSE,sha256=HjYTlfne3BbS5gNHzNqJ5COCiTQLUdf87QkzRyFbE4Y,10337
40
+ aepp-0.5.2.dist-info/METADATA,sha256=wfGA0AzXQdAwcYWD6RB9umN6LWXz_RP07HaEAorpG5k,5338
41
+ aepp-0.5.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
42
+ aepp-0.5.2.dist-info/entry_points.txt,sha256=e7HAumUTymoUiCuVRzFlcchennUBLcjxvuiimySF98Y,48
43
+ aepp-0.5.2.dist-info/top_level.txt,sha256=dtZJI8SzhWVgZRl68PHKZX_fD6amvDiFR-lqD9FSJvE,5
44
+ aepp-0.5.2.dist-info/RECORD,,