synapse 2.153.0__py311-none-any.whl → 2.154.0__py311-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.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/cortex.py +4 -4
- synapse/lib/ast.py +10 -5
- synapse/lib/autodoc.py +2 -2
- synapse/lib/cache.py +16 -1
- synapse/lib/layer.py +2 -1
- synapse/lib/modelrev.py +36 -3
- synapse/lib/node.py +2 -5
- synapse/lib/snap.py +10 -0
- synapse/lib/storm.py +80 -0
- synapse/lib/stormhttp.py +3 -0
- synapse/lib/stormlib/backup.py +1 -0
- synapse/lib/stormlib/basex.py +2 -0
- synapse/lib/stormlib/cell.py +7 -0
- synapse/lib/stormlib/compression.py +3 -0
- synapse/lib/stormlib/ethereum.py +1 -0
- synapse/lib/stormlib/graph.py +2 -0
- synapse/lib/stormlib/hashes.py +5 -0
- synapse/lib/stormlib/hex.py +6 -0
- synapse/lib/stormlib/infosec.py +4 -0
- synapse/lib/stormlib/ipv6.py +1 -0
- synapse/lib/stormlib/iters.py +2 -0
- synapse/lib/stormlib/json.py +5 -0
- synapse/lib/stormlib/mime.py +1 -0
- synapse/lib/stormlib/model.py +19 -3
- synapse/lib/stormlib/modelext.py +1 -0
- synapse/lib/stormlib/notifications.py +2 -0
- synapse/lib/stormlib/pack.py +2 -0
- synapse/lib/stormlib/random.py +1 -0
- synapse/lib/stormlib/smtp.py +0 -7
- synapse/lib/stormlib/stats.py +4 -0
- synapse/lib/stormlib/stix.py +8 -0
- synapse/lib/stormlib/storm.py +1 -0
- synapse/lib/stormlib/version.py +3 -0
- synapse/lib/stormlib/xml.py +3 -0
- synapse/lib/stormlib/yaml.py +2 -0
- synapse/lib/stormtypes.py +201 -29
- synapse/lib/trigger.py +180 -4
- synapse/lib/types.py +1 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +55 -6
- synapse/models/inet.py +16 -4
- synapse/models/orgs.py +47 -2
- synapse/models/risk.py +126 -2
- synapse/models/syn.py +6 -0
- synapse/tests/files/stormpkg/badapidef.yaml +13 -0
- synapse/tests/files/stormpkg/storm/modules/apimod +10 -0
- synapse/tests/files/stormpkg/testpkg.yaml +23 -0
- synapse/tests/test_cortex.py +50 -34
- synapse/tests/test_lib_ast.py +7 -0
- synapse/tests/test_lib_autodoc.py +1 -1
- synapse/tests/test_lib_modelrev.py +9 -0
- synapse/tests/test_lib_node.py +55 -0
- synapse/tests/test_lib_storm.py +13 -0
- synapse/tests/test_lib_stormlib_storm.py +8 -0
- synapse/tests/test_lib_stormsvc.py +24 -1
- synapse/tests/test_lib_stormtypes.py +105 -1
- synapse/tests/test_lib_trigger.py +315 -0
- synapse/tests/test_lib_view.py +1 -2
- synapse/tests/test_model_inet.py +22 -0
- synapse/tests/test_model_orgs.py +28 -0
- synapse/tests/test_model_risk.py +73 -0
- synapse/tests/test_tools_autodoc.py +25 -0
- synapse/tests/test_tools_genpkg.py +9 -3
- synapse/tools/autodoc.py +42 -2
- {synapse-2.153.0.dist-info → synapse-2.154.0.dist-info}/METADATA +1 -1
- {synapse-2.153.0.dist-info → synapse-2.154.0.dist-info}/RECORD +69 -67
- {synapse-2.153.0.dist-info → synapse-2.154.0.dist-info}/WHEEL +1 -1
- {synapse-2.153.0.dist-info → synapse-2.154.0.dist-info}/LICENSE +0 -0
- {synapse-2.153.0.dist-info → synapse-2.154.0.dist-info}/top_level.txt +0 -0
synapse/lib/stormlib/json.py
CHANGED
|
@@ -62,9 +62,11 @@ class JsonSchema(s_stormtypes.StormType):
|
|
|
62
62
|
'validate': self._validate,
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
65
66
|
async def _schema(self):
|
|
66
67
|
return copy.deepcopy(self.schema)
|
|
67
68
|
|
|
69
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
68
70
|
async def _validate(self, item):
|
|
69
71
|
item = await s_stormtypes.toprim(item)
|
|
70
72
|
|
|
@@ -112,6 +114,7 @@ class JsonLib(s_stormtypes.Lib):
|
|
|
112
114
|
'schema': self._jsonSchema,
|
|
113
115
|
}
|
|
114
116
|
|
|
117
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
115
118
|
async def _jsonSave(self, item):
|
|
116
119
|
try:
|
|
117
120
|
item = await s_stormtypes.toprim(item)
|
|
@@ -120,6 +123,7 @@ class JsonLib(s_stormtypes.Lib):
|
|
|
120
123
|
mesg = f'Argument is not JSON compatible: {item}'
|
|
121
124
|
raise s_exc.MustBeJsonSafe(mesg=mesg)
|
|
122
125
|
|
|
126
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
123
127
|
async def _jsonLoad(self, text):
|
|
124
128
|
text = await s_stormtypes.tostr(text)
|
|
125
129
|
try:
|
|
@@ -128,6 +132,7 @@ class JsonLib(s_stormtypes.Lib):
|
|
|
128
132
|
mesg = f'Text is not valid JSON: {text}'
|
|
129
133
|
raise s_exc.BadJsonText(mesg=mesg)
|
|
130
134
|
|
|
135
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
131
136
|
async def _jsonSchema(self, schema, use_default=True):
|
|
132
137
|
schema = await s_stormtypes.toprim(schema)
|
|
133
138
|
use_default = await s_stormtypes.tobool(use_default)
|
synapse/lib/stormlib/mime.py
CHANGED
synapse/lib/stormlib/model.py
CHANGED
|
@@ -251,10 +251,12 @@ class LibModelTags(s_stormtypes.Lib):
|
|
|
251
251
|
self.runt.confirm(('model', 'tag', 'set'))
|
|
252
252
|
return await self.runt.snap.core.delTagModel(tagname)
|
|
253
253
|
|
|
254
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
254
255
|
async def _getTagModel(self, tagname):
|
|
255
256
|
tagname = await s_stormtypes.tostr(tagname)
|
|
256
257
|
return await self.runt.snap.core.getTagModel(tagname)
|
|
257
258
|
|
|
259
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
258
260
|
async def _listTagModel(self):
|
|
259
261
|
return await self.runt.snap.core.listTagModel()
|
|
260
262
|
|
|
@@ -325,24 +327,28 @@ class LibModel(s_stormtypes.Lib):
|
|
|
325
327
|
}
|
|
326
328
|
|
|
327
329
|
@s_cache.memoizemethod(size=100)
|
|
330
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
328
331
|
async def _methType(self, name):
|
|
329
332
|
type_ = self.model.type(name)
|
|
330
333
|
if type_ is not None:
|
|
331
334
|
return ModelType(type_)
|
|
332
335
|
|
|
333
336
|
@s_cache.memoizemethod(size=100)
|
|
337
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
334
338
|
async def _methProp(self, name):
|
|
335
339
|
prop = self.model.prop(name)
|
|
336
340
|
if prop is not None:
|
|
337
341
|
return ModelProp(prop)
|
|
338
342
|
|
|
339
343
|
@s_cache.memoizemethod(size=100)
|
|
344
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
340
345
|
async def _methForm(self, name):
|
|
341
346
|
form = self.model.form(name)
|
|
342
347
|
if form is not None:
|
|
343
348
|
return ModelForm(form)
|
|
344
349
|
|
|
345
350
|
@s_cache.memoize(size=100)
|
|
351
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
346
352
|
async def _methTagProp(self, name):
|
|
347
353
|
tagprop = self.model.getTagProp(name)
|
|
348
354
|
if tagprop is not None:
|
|
@@ -387,6 +393,7 @@ class ModelForm(s_stormtypes.Prim):
|
|
|
387
393
|
def _ctorFormType(self, path=None):
|
|
388
394
|
return ModelType(self.valu.type, path=path)
|
|
389
395
|
|
|
396
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
390
397
|
def _getFormProp(self, name):
|
|
391
398
|
prop = self.valu.prop(name)
|
|
392
399
|
if prop is not None:
|
|
@@ -490,15 +497,21 @@ class ModelType(s_stormtypes.Prim):
|
|
|
490
497
|
s_stormtypes.Prim.__init__(self, valu, path=path)
|
|
491
498
|
self.locls.update(self.getObjLocals())
|
|
492
499
|
self.locls.update({'name': valu.name,
|
|
493
|
-
'norm': self._methNorm,
|
|
494
|
-
'repr': self._methRepr,
|
|
495
500
|
'stortype': valu.stortype,
|
|
496
501
|
})
|
|
497
502
|
|
|
503
|
+
def getObjLocals(self):
|
|
504
|
+
return {
|
|
505
|
+
'norm': self._methNorm,
|
|
506
|
+
'repr': self._methRepr,
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
498
510
|
async def _methRepr(self, valu):
|
|
499
511
|
nval = self.valu.norm(valu)
|
|
500
512
|
return self.valu.repr(nval[0])
|
|
501
513
|
|
|
514
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
502
515
|
async def _methNorm(self, valu):
|
|
503
516
|
return self.valu.norm(valu)
|
|
504
517
|
|
|
@@ -544,7 +557,7 @@ class LibModelEdge(s_stormtypes.Lib):
|
|
|
544
557
|
# Note: The use of extprops in hive paths in this class is an artifact of the
|
|
545
558
|
# original implementation which used extended property language which had a
|
|
546
559
|
# very bad cognitive overload with the cortex extended properties, but we
|
|
547
|
-
#
|
|
560
|
+
# don't want to change underlying data. epiphyte 20200703
|
|
548
561
|
|
|
549
562
|
# restrict list of keys which we allow to be set/del through this API.
|
|
550
563
|
validedgekeys = (
|
|
@@ -578,9 +591,11 @@ class LibModelEdge(s_stormtypes.Lib):
|
|
|
578
591
|
raise s_exc.NoSuchProp(mesg=f'The requested key is not valid for light edge metadata.',
|
|
579
592
|
name=key)
|
|
580
593
|
|
|
594
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
581
595
|
def _methValidKeys(self):
|
|
582
596
|
return self.validedgekeys
|
|
583
597
|
|
|
598
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
584
599
|
async def _methEdgeGet(self, verb):
|
|
585
600
|
verb = await s_stormtypes.tostr(verb)
|
|
586
601
|
await self._chkEdgeVerbInView(verb)
|
|
@@ -620,6 +635,7 @@ class LibModelEdge(s_stormtypes.Lib):
|
|
|
620
635
|
|
|
621
636
|
await self.runt.snap.core.setHiveKey(path, kvdict)
|
|
622
637
|
|
|
638
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
623
639
|
async def _methEdgeList(self):
|
|
624
640
|
retn = []
|
|
625
641
|
async for verb in self.runt.snap.view.getEdgeVerbs():
|
synapse/lib/stormlib/modelext.py
CHANGED
|
@@ -156,6 +156,7 @@ class LibModelExt(s_stormtypes.Lib):
|
|
|
156
156
|
s_stormtypes.confirm(('model', 'tagprop', 'del'))
|
|
157
157
|
await self.runt.snap.core.delTagProp(propname)
|
|
158
158
|
|
|
159
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
159
160
|
async def getExtModel(self):
|
|
160
161
|
return await self.runt.snap.core.getExtModel()
|
|
161
162
|
|
|
@@ -65,6 +65,7 @@ class NotifyLib(s_stormtypes.Lib):
|
|
|
65
65
|
# 'bytype':
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
68
69
|
async def get(self, indx):
|
|
69
70
|
indx = await s_stormtypes.toint(indx)
|
|
70
71
|
mesg = await self.runt.snap.core.getUserNotif(indx)
|
|
@@ -81,6 +82,7 @@ class NotifyLib(s_stormtypes.Lib):
|
|
|
81
82
|
raise s_exc.AuthDeny(mesg=mesg, user=self.runt.user.iden, username=self.runt.user.name)
|
|
82
83
|
await self.runt.snap.core.delUserNotif(indx)
|
|
83
84
|
|
|
85
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
84
86
|
async def list(self, size=None):
|
|
85
87
|
size = await s_stormtypes.toint(size, noneok=True)
|
|
86
88
|
async for mesg in self.runt.snap.core.iterUserNotifs(self.runt.user.iden, size=size):
|
synapse/lib/stormlib/pack.py
CHANGED
|
@@ -34,6 +34,7 @@ class LibPack(s_stormtypes.Lib):
|
|
|
34
34
|
'un': self.un,
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
37
38
|
async def en(self, fmt, items):
|
|
38
39
|
fmt = await s_stormtypes.tostr(fmt)
|
|
39
40
|
items = await s_stormtypes.toprim(items)
|
|
@@ -47,6 +48,7 @@ class LibPack(s_stormtypes.Lib):
|
|
|
47
48
|
except struct.error as e:
|
|
48
49
|
raise s_exc.BadArg(mesg=str(e))
|
|
49
50
|
|
|
51
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
50
52
|
async def un(self, fmt, byts, offs=0):
|
|
51
53
|
|
|
52
54
|
fmt = await s_stormtypes.tostr(fmt)
|
synapse/lib/stormlib/random.py
CHANGED
synapse/lib/stormlib/smtp.py
CHANGED
|
@@ -130,19 +130,15 @@ class SmtpMessage(s_stormtypes.StormType):
|
|
|
130
130
|
'sender': self._setSenderEmail,
|
|
131
131
|
})
|
|
132
132
|
|
|
133
|
-
@s_stormtypes.stormfunc(readonly=True)
|
|
134
133
|
async def _setSenderEmail(self, valu):
|
|
135
|
-
# TODO handle inet:email and ps:contact Nodes
|
|
136
134
|
self.sender = await s_stormtypes.tostr(valu)
|
|
137
135
|
|
|
138
136
|
async def _getSenderEmail(self):
|
|
139
137
|
return self.sender
|
|
140
138
|
|
|
141
|
-
@s_stormtypes.stormfunc(readonly=True)
|
|
142
139
|
async def _setEmailText(self, text):
|
|
143
140
|
self.bodytext = await s_stormtypes.tostr(text)
|
|
144
141
|
|
|
145
|
-
@s_stormtypes.stormfunc(readonly=True)
|
|
146
142
|
async def _setEmailHtml(self, html):
|
|
147
143
|
self.bodyhtml = await s_stormtypes.tostr(html)
|
|
148
144
|
|
|
@@ -152,9 +148,6 @@ class SmtpMessage(s_stormtypes.StormType):
|
|
|
152
148
|
async def _getEmailHtml(self):
|
|
153
149
|
return self.bodyhtml
|
|
154
150
|
|
|
155
|
-
# TODO
|
|
156
|
-
# async def attach(self, sha256, name, mime):
|
|
157
|
-
|
|
158
151
|
async def send(self, host, port=25, user=None, passwd=None, usetls=False, starttls=False, timeout=60):
|
|
159
152
|
|
|
160
153
|
self.runt.confirm(('storm', 'inet', 'smtp', 'send'))
|
synapse/lib/stormlib/stats.py
CHANGED
|
@@ -131,6 +131,7 @@ class LibStats(s_stormtypes.Lib):
|
|
|
131
131
|
'tally': self.tally,
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
134
135
|
async def tally(self):
|
|
135
136
|
return StatTally(path=self.path)
|
|
136
137
|
|
|
@@ -198,10 +199,12 @@ class StatTally(s_stormtypes.Prim):
|
|
|
198
199
|
def __len__(self):
|
|
199
200
|
return len(self.counters)
|
|
200
201
|
|
|
202
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
201
203
|
async def inc(self, name, valu=1):
|
|
202
204
|
valu = await s_stormtypes.toint(valu)
|
|
203
205
|
self.counters[name] += valu
|
|
204
206
|
|
|
207
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
205
208
|
async def get(self, name):
|
|
206
209
|
return self.counters.get(name, 0)
|
|
207
210
|
|
|
@@ -212,6 +215,7 @@ class StatTally(s_stormtypes.Prim):
|
|
|
212
215
|
for item in tuple(self.counters.items()):
|
|
213
216
|
yield item
|
|
214
217
|
|
|
218
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
215
219
|
async def sorted(self, byname=False, reverse=False):
|
|
216
220
|
if byname:
|
|
217
221
|
return list(sorted(self.counters.items(), reverse=reverse))
|
synapse/lib/stormlib/stix.py
CHANGED
|
@@ -653,10 +653,12 @@ class LibStix(s_stormtypes.Lib):
|
|
|
653
653
|
'validate': self.validateBundle,
|
|
654
654
|
}
|
|
655
655
|
|
|
656
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
656
657
|
async def validateBundle(self, bundle):
|
|
657
658
|
bundle = await s_stormtypes.toprim(bundle)
|
|
658
659
|
return await s_coro.semafork(validateStix, bundle)
|
|
659
660
|
|
|
661
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
660
662
|
async def liftBundle(self, bundle):
|
|
661
663
|
bundle = await s_stormtypes.toprim(bundle)
|
|
662
664
|
|
|
@@ -861,6 +863,7 @@ class LibStixImport(s_stormtypes.Lib):
|
|
|
861
863
|
'ingest': self.ingest,
|
|
862
864
|
}
|
|
863
865
|
|
|
866
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
864
867
|
async def config(self):
|
|
865
868
|
return s_msgpack.deepcopy(stixingest, use_list=True)
|
|
866
869
|
|
|
@@ -1129,10 +1132,12 @@ class LibStixExport(s_stormtypes.Lib):
|
|
|
1129
1132
|
'timestamp': self.timestamp,
|
|
1130
1133
|
}
|
|
1131
1134
|
|
|
1135
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
1132
1136
|
async def config(self):
|
|
1133
1137
|
# make a new mutable config
|
|
1134
1138
|
return json.loads(json.dumps(_DefaultConfig))
|
|
1135
1139
|
|
|
1140
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
1136
1141
|
async def bundle(self, config=None):
|
|
1137
1142
|
|
|
1138
1143
|
if config is None:
|
|
@@ -1265,6 +1270,7 @@ class StixBundle(s_stormtypes.Prim):
|
|
|
1265
1270
|
# async def addPropMap(self, formname, stixtype, propname, stormtext):
|
|
1266
1271
|
# async def addRelsMap(self, formname, stixtype, relname, targtype, stormtext):
|
|
1267
1272
|
|
|
1273
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
1268
1274
|
async def add(self, node, stixtype=None):
|
|
1269
1275
|
|
|
1270
1276
|
if len(self.objs) >= self.maxsize:
|
|
@@ -1380,6 +1386,7 @@ class StixBundle(s_stormtypes.Prim):
|
|
|
1380
1386
|
}
|
|
1381
1387
|
return ret
|
|
1382
1388
|
|
|
1389
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
1383
1390
|
def pack(self):
|
|
1384
1391
|
objects = list(self.objs.values())
|
|
1385
1392
|
if self.synextension:
|
|
@@ -1391,6 +1398,7 @@ class StixBundle(s_stormtypes.Prim):
|
|
|
1391
1398
|
}
|
|
1392
1399
|
return bundle
|
|
1393
1400
|
|
|
1401
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
1394
1402
|
def size(self):
|
|
1395
1403
|
return len(self.objs)
|
|
1396
1404
|
|
synapse/lib/stormlib/storm.py
CHANGED
synapse/lib/stormlib/version.py
CHANGED
|
@@ -45,12 +45,15 @@ class VersionLib(s_stormtypes.Lib):
|
|
|
45
45
|
'synapse': self._getSynVersion,
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
48
49
|
async def _getSynVersion(self):
|
|
49
50
|
return s_version.version
|
|
50
51
|
|
|
52
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
51
53
|
async def _getSynCommit(self):
|
|
52
54
|
return s_version.commit
|
|
53
55
|
|
|
56
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
54
57
|
async def matches(self, vertup, reqstr):
|
|
55
58
|
reqstr = await s_stormtypes.tostr(reqstr)
|
|
56
59
|
vertup = tuple(await s_stormtypes.toprim(vertup))
|
synapse/lib/stormlib/xml.py
CHANGED
|
@@ -49,6 +49,7 @@ class XmlElement(s_stormtypes.Prim):
|
|
|
49
49
|
for elem in self.elem:
|
|
50
50
|
yield XmlElement(self.runt, elem)
|
|
51
51
|
|
|
52
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
52
53
|
async def find(self, name, nested=True):
|
|
53
54
|
name = await s_stormtypes.tostr(name)
|
|
54
55
|
nested = await s_stormtypes.tobool(nested)
|
|
@@ -60,6 +61,7 @@ class XmlElement(s_stormtypes.Prim):
|
|
|
60
61
|
for elem in self.elem.findall(name):
|
|
61
62
|
yield XmlElement(self.runt, elem)
|
|
62
63
|
|
|
64
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
63
65
|
async def get(self, name):
|
|
64
66
|
name = await s_stormtypes.tostr(name)
|
|
65
67
|
elem = self.elem.find(name)
|
|
@@ -87,6 +89,7 @@ class LibXml(s_stormtypes.Lib):
|
|
|
87
89
|
'parse': self.parse,
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
90
93
|
async def parse(self, valu):
|
|
91
94
|
valu = await s_stormtypes.tostr(valu)
|
|
92
95
|
try:
|
synapse/lib/stormlib/yaml.py
CHANGED
|
@@ -34,11 +34,13 @@ class LibYaml(s_stormtypes.Lib):
|
|
|
34
34
|
'load': self.load,
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
37
38
|
async def save(self, valu, sort_keys=True):
|
|
38
39
|
valu = await s_stormtypes.toprim(valu)
|
|
39
40
|
sort_keys = await s_stormtypes.tobool(sort_keys)
|
|
40
41
|
return yaml.dump(valu, sort_keys=sort_keys, Dumper=s_common.Dumper)
|
|
41
42
|
|
|
43
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
42
44
|
async def load(self, valu):
|
|
43
45
|
valu = await s_stormtypes.tostr(valu)
|
|
44
46
|
try:
|