mspec 0.0.2a0__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.
mspec/__init__.py ADDED
@@ -0,0 +1,46 @@
1
+ from pathlib import Path
2
+ import yaml
3
+
4
+ __all__ = ['spec', 'sample_spec_dir', 'dist_dir']
5
+
6
+ sample_spec_dir = Path(__file__).parent / 'data'
7
+ dist_dir = Path(__file__).parent.parent.parent / 'dist'
8
+
9
+ def generate_names(lower_case:str) -> dict:
10
+ name_split = lower_case.split(' ')
11
+ pascal_case = ''.join([name.capitalize() for name in name_split])
12
+ return {
13
+ 'snake_case': '_'.join(name_split),
14
+ 'pascal_case': pascal_case,
15
+ 'kebab_case': '-'.join(name_split),
16
+ 'camel_case': pascal_case[0].lower() + pascal_case[1:]
17
+ }
18
+
19
+ def load_spec(spec_file:str) -> dict:
20
+ """
21
+ open and parse spec file into dict,
22
+ first try to load from the path as provided,
23
+ if not found, try searching for path in built in sample_spec_dir
24
+ """
25
+ try:
26
+ print(f'attempting to load spec file: {spec_file}')
27
+ with open(spec_file) as f:
28
+ spec = yaml.load(f, Loader=yaml.FullLoader)
29
+ print(f'\tloaded.')
30
+
31
+ except FileNotFoundError:
32
+ _path = sample_spec_dir / spec_file
33
+ print(f'attempting to load spec file: {_path}')
34
+ with open(_path) as f:
35
+ spec = yaml.load(f, Loader=yaml.FullLoader)
36
+ print(f'\tloaded.')
37
+
38
+ project = spec['project']
39
+ project['name'].update(generate_names(project['name']['lower_case']))
40
+
41
+ for module in spec['modules'].values():
42
+ module['name'].update(generate_names(module['name']['lower_case']))
43
+ for model in module['models'].values():
44
+ model['name'].update(generate_names(model['name']['lower_case']))
45
+
46
+ return spec
mspec/__main__.py ADDED
@@ -0,0 +1,16 @@
1
+ import argparse
2
+ from mspec import load_spec
3
+ from pprint import pprint
4
+
5
+ parser = argparse.ArgumentParser(description='MSpec command line interface')
6
+ parser.add_argument('command', choices=['spec'], help='command to run')
7
+ parser.add_argument('--spec', type=str, default='test-gen.yaml', help='spec file pattern')
8
+
9
+ args = parser.parse_args()
10
+ match args.command:
11
+ case 'spec':
12
+ pprint(load_spec(args.spec))
13
+
14
+ case _:
15
+ print('Unknown command')
16
+ raise SystemExit(1)
@@ -0,0 +1,89 @@
1
+ project:
2
+ name:
3
+ snake_case: 'cms'
4
+ pascal_case: 'CMS'
5
+ camel_case: 'cms'
6
+ kebab_case: 'cms'
7
+ lower_case: 'cms'
8
+
9
+ description: 'A CMS module for mspec-alpha python app generator'
10
+
11
+ author:
12
+ name: 'B rad C'
13
+ email: 'sample@email.com'
14
+
15
+ server:
16
+ port: 6006
17
+
18
+ modules:
19
+
20
+ cms:
21
+ name:
22
+ lower_case: 'cms'
23
+
24
+ models:
25
+
26
+ file:
27
+ type: object
28
+ fields:
29
+
30
+ name:
31
+ type: str
32
+
33
+ size:
34
+ type: int
35
+
36
+ hash:
37
+ type: str
38
+
39
+ file_cid:
40
+ type: cid
41
+ help: the file cid
42
+
43
+ content_type:
44
+ type: str
45
+
46
+ created:
47
+ type: datetime
48
+
49
+ backup_policy:
50
+ type: cid
51
+ help: backup policy for this media object
52
+
53
+ width:
54
+ type: int
55
+
56
+ height:
57
+ type: int
58
+
59
+ duration:
60
+ type: int
61
+
62
+ audio_bitrate:
63
+ type: int
64
+
65
+ audio_channels:
66
+ type: int
67
+
68
+ audio_sample_rate:
69
+ type: int
70
+
71
+ image_channels:
72
+ type: int
73
+
74
+ video_channels:
75
+ type: int
76
+
77
+ video_bitrate:
78
+ type: int
79
+
80
+ backup_policy:
81
+ type: object
82
+ use_cid: true
83
+ fields:
84
+ name:
85
+ type: str
86
+ repos:
87
+ type: list
88
+ element_type: str
89
+ help: list of cid repos to backup to (http/ftp/file/s3/etc)
@@ -0,0 +1,166 @@
1
+ types:
2
+ cid:
3
+ type: str
4
+
5
+ tags:
6
+ type: list
7
+ element_type: string
8
+
9
+ hierarchy:
10
+ type: list
11
+ element_type: string
12
+
13
+ meta:
14
+ type: object
15
+ fields:
16
+ data:
17
+ type: object
18
+ tags:
19
+ type: tags
20
+ loc:
21
+ type: hierarchy
22
+
23
+ context:
24
+ type: object
25
+ fields:
26
+ id:
27
+ type: str
28
+ source:
29
+ type: str
30
+ meta:
31
+ type: meta
32
+
33
+ entity:
34
+ type: object
35
+ fields:
36
+ id:
37
+ type: cid
38
+ type:
39
+ type: str
40
+ enum:
41
+ - user
42
+ - profile
43
+ - group_profile
44
+
45
+ permissions:
46
+ type: object
47
+ fields:
48
+ read:
49
+ type: str
50
+ help: "public, private, inherit, or cid of acl"
51
+ write:
52
+ type: str
53
+ help: "public, private, inherit, or cid of acl"
54
+ delete:
55
+ type: str
56
+ help: "public, private, inherit, or cid of acl"
57
+
58
+ models:
59
+ user:
60
+ fields:
61
+ name:
62
+ type: str
63
+ email:
64
+ type: str
65
+ profile:
66
+ type: cid
67
+
68
+ user_session:
69
+ fields:
70
+ user:
71
+ type: cid
72
+ token:
73
+ type: str
74
+ expires:
75
+ type: datetime
76
+
77
+ user_password_hash:
78
+ fields:
79
+ user:
80
+ type: cid
81
+ hash:
82
+ type: str
83
+ salt:
84
+ type: str
85
+
86
+ profile:
87
+ fields:
88
+ name:
89
+ type: str
90
+ bio:
91
+ type: str
92
+ meta:
93
+ type: meta
94
+
95
+ acl:
96
+ fields:
97
+ name:
98
+ type: str
99
+ admin:
100
+ type: entity
101
+
102
+ acl_entry:
103
+ fields:
104
+ acl:
105
+ type: cid
106
+ entity:
107
+ type: entity
108
+
109
+ attachment:
110
+ fields:
111
+ item:
112
+ type: cid
113
+ help: "reference cid to the item being attached"
114
+ to:
115
+ type: cid
116
+ help: "reference cid that `item` is being attached to"
117
+
118
+ reference:
119
+ fields:
120
+ cid:
121
+ type: cid
122
+ name:
123
+ type: str
124
+ meta:
125
+ type: meta
126
+ perms:
127
+ type: permissions
128
+
129
+ ops:
130
+ current:
131
+ help: db query for version.ref == self.cid, sort by time and take most recent
132
+ versions:
133
+ help: db query returning version where version.ref == self.cid
134
+
135
+ version:
136
+ fields:
137
+ name:
138
+ type: str
139
+ meta:
140
+ type: meta
141
+ perms:
142
+ type: permissions
143
+
144
+ type:
145
+ type: str
146
+ help: "file, image, video, audio, text, etc"
147
+
148
+ ref:
149
+ type: cid
150
+ help: reference to the item this version is for
151
+ hash:
152
+ type: str
153
+ size:
154
+ type: int
155
+ datetime:
156
+ type: datetime
157
+
158
+ cid:
159
+ help: generated from hash/size/etc on this object
160
+
161
+ ops:
162
+ previous:
163
+ type: str
164
+ help: previous version cid for reference, if empty string this is first version in series
165
+ next:
166
+ help: db query to return version where previous == self.cid
@@ -0,0 +1,48 @@
1
+ models:
2
+ sample_item:
3
+ fields:
4
+ name:
5
+ type: str
6
+ examples:
7
+ - "a large thing"
8
+ - "a random thing"
9
+ - "another thing"
10
+
11
+ verified:
12
+ type: bool
13
+ examples:
14
+ - true
15
+ - false
16
+
17
+ color:
18
+ type: str
19
+ enum:
20
+ - red
21
+ - green
22
+ - blue
23
+ examples:
24
+ - red
25
+ - green
26
+ - blue
27
+
28
+ age:
29
+ type: int
30
+ examples:
31
+ - 36
32
+ - 27
33
+ - 42
34
+
35
+ score:
36
+ type: float
37
+ examples:
38
+ - 4.7
39
+ - 8.1
40
+ - 9.9
41
+
42
+ tags:
43
+ type: list
44
+ element_type: string
45
+ examples:
46
+ - ["tag1", "tag2"]
47
+ - ["tag3", "tag4"]
48
+ - ["tag5", "tag6"]
@@ -0,0 +1,158 @@
1
+ {
2
+ "params": {},
3
+ "state": {
4
+ "test_bool_true": {
5
+ "type": "bool",
6
+ "calc": {"call": "bool", "args": {"object": 1}}
7
+ },
8
+ "test_bool_false": {
9
+ "type": "bool",
10
+ "calc": {"call": "bool", "args": {"object": 0}}
11
+ },
12
+ "test_not_true": {
13
+ "type": "bool",
14
+ "calc": {"call": "not", "args": {"object": true}}
15
+ },
16
+ "test_not_false": {
17
+ "type": "bool",
18
+ "calc": {"call": "not", "args": {"object": false}}
19
+ },
20
+ "test_neg": {
21
+ "type": "int",
22
+ "calc": {"call": "neg", "args": {"object": 5}}
23
+ },
24
+ "test_and_true": {
25
+ "type": "bool",
26
+ "calc": {"call": "and", "args": {"a": true, "b": true}}
27
+ },
28
+ "test_and_false": {
29
+ "type": "bool",
30
+ "calc": {"call": "and", "args": {"a": true, "b": false}}
31
+ },
32
+ "test_or_true": {
33
+ "type": "bool",
34
+ "calc": {"call": "or", "args": {"a": false, "b": true}}
35
+ },
36
+ "test_or_false": {
37
+ "type": "bool",
38
+ "calc": {"call": "or", "args": {"a": false, "b": false}}
39
+ },
40
+ "test_add": {
41
+ "type": "int",
42
+ "calc": {"call": "add", "args": {"a": 10, "b": 5}}
43
+ },
44
+ "test_sub": {
45
+ "type": "int",
46
+ "calc": {"call": "sub", "args": {"a": 10, "b": 3}}
47
+ },
48
+ "test_mul": {
49
+ "type": "int",
50
+ "calc": {"call": "mul", "args": {"a": 4, "b": 7}}
51
+ },
52
+ "test_div": {
53
+ "type": "float",
54
+ "calc": {"call": "div", "args": {"a": 15, "b": 3}}
55
+ },
56
+ "test_pow": {
57
+ "type": "int",
58
+ "calc": {"call": "pow", "args": {"a": 2, "b": 3}}
59
+ },
60
+ "test_eq_true": {
61
+ "type": "bool",
62
+ "calc": {"call": "eq", "args": {"a": 5, "b": 5}}
63
+ },
64
+ "test_eq_false": {
65
+ "type": "bool",
66
+ "calc": {"call": "eq", "args": {"a": 5, "b": 3}}
67
+ },
68
+ "test_ne_true": {
69
+ "type": "bool",
70
+ "calc": {"call": "ne", "args": {"a": 5, "b": 3}}
71
+ },
72
+ "test_ne_false": {
73
+ "type": "bool",
74
+ "calc": {"call": "ne", "args": {"a": 5, "b": 5}}
75
+ },
76
+ "test_lt_true": {
77
+ "type": "bool",
78
+ "calc": {"call": "lt", "args": {"a": 3, "b": 5}}
79
+ },
80
+ "test_lt_false": {
81
+ "type": "bool",
82
+ "calc": {"call": "lt", "args": {"a": 5, "b": 3}}
83
+ },
84
+ "test_le_true": {
85
+ "type": "bool",
86
+ "calc": {"call": "le", "args": {"a": 5, "b": 5}}
87
+ },
88
+ "test_le_false": {
89
+ "type": "bool",
90
+ "calc": {"call": "le", "args": {"a": 7, "b": 5}}
91
+ },
92
+ "test_gt_true": {
93
+ "type": "bool",
94
+ "calc": {"call": "gt", "args": {"a": 7, "b": 5}}
95
+ },
96
+ "test_gt_false": {
97
+ "type": "bool",
98
+ "calc": {"call": "gt", "args": {"a": 3, "b": 5}}
99
+ },
100
+ "test_ge_true": {
101
+ "type": "bool",
102
+ "calc": {"call": "ge", "args": {"a": 5, "b": 5}}
103
+ },
104
+ "test_ge_false": {
105
+ "type": "bool",
106
+ "calc": {"call": "ge", "args": {"a": 3, "b": 5}}
107
+ }
108
+ },
109
+ "ops": {},
110
+ "output": [
111
+ {"heading": {"text": "Function Tests"}, "level": 1},
112
+ {"block": [
113
+ {"text": "Boolean Functions:"},
114
+ {"break": 1},
115
+ {"text": "bool(1) = "}, {"lingo": {"state": {"test_bool_true": {}}}}, {"break": 1},
116
+ {"text": "bool(0) = "}, {"lingo": {"state": {"test_bool_false": {}}}}, {"break": 1},
117
+ {"text": "not(true) = "}, {"lingo": {"state": {"test_not_true": {}}}}, {"break": 1},
118
+ {"text": "not(false) = "}, {"lingo": {"state": {"test_not_false": {}}}}, {"break": 1},
119
+ {"text": "neg(5) = "}, {"lingo": {"state": {"test_neg": {}}}}, {"break": 2},
120
+
121
+ {"text": "Logical Functions:"},
122
+ {"break": 1},
123
+ {"text": "and(true, true) = "}, {"lingo": {"state": {"test_and_true": {}}}}, {"break": 1},
124
+ {"text": "and(true, false) = "}, {"lingo": {"state": {"test_and_false": {}}}}, {"break": 1},
125
+ {"text": "or(false, true) = "}, {"lingo": {"state": {"test_or_true": {}}}}, {"break": 1},
126
+ {"text": "or(false, false) = "}, {"lingo": {"state": {"test_or_false": {}}}}, {"break": 2},
127
+
128
+ {"text": "Math Functions:"},
129
+ {"break": 1},
130
+ {"text": "add(10, 5) = "}, {"lingo": {"state": {"test_add": {}}}}, {"break": 1},
131
+ {"text": "sub(10, 3) = "}, {"lingo": {"state": {"test_sub": {}}}}, {"break": 1},
132
+ {"text": "mul(4, 7) = "}, {"lingo": {"state": {"test_mul": {}}}}, {"break": 1},
133
+ {"text": "div(15, 3) = "}, {"lingo": {"state": {"test_div": {}}}}, {"break": 1},
134
+ {"text": "pow(2, 3) = "}, {"lingo": {"state": {"test_pow": {}}}}, {"break": 2},
135
+
136
+ {"text": "Comparison Functions:"},
137
+ {"break": 1},
138
+ {"text": "eq(5, 5) = "}, {"lingo": {"state": {"test_eq_true": {}}}}, {"break": 1},
139
+ {"text": "eq(5, 3) = "}, {"lingo": {"state": {"test_eq_false": {}}}}, {"break": 1},
140
+ {"text": "ne(5, 3) = "}, {"lingo": {"state": {"test_ne_true": {}}}}, {"break": 1},
141
+ {"text": "ne(5, 5) = "}, {"lingo": {"state": {"test_ne_false": {}}}}, {"break": 1},
142
+ {"text": "lt(3, 5) = "}, {"lingo": {"state": {"test_lt_true": {}}}}, {"break": 1},
143
+ {"text": "lt(5, 3) = "}, {"lingo": {"state": {"test_lt_false": {}}}}, {"break": 1},
144
+ {"text": "le(5, 5) = "}, {"lingo": {"state": {"test_le_true": {}}}}, {"break": 1},
145
+ {"text": "le(7, 5) = "}, {"lingo": {"state": {"test_le_false": {}}}}, {"break": 1},
146
+ {"text": "gt(7, 5) = "}, {"lingo": {"state": {"test_gt_true": {}}}}, {"break": 1},
147
+ {"text": "gt(3, 5) = "}, {"lingo": {"state": {"test_gt_false": {}}}}, {"break": 1},
148
+ {"text": "ge(5, 5) = "}, {"lingo": {"state": {"test_ge_true": {}}}}, {"break": 1},
149
+ {"text": "ge(3, 5) = "}, {"lingo": {"state": {"test_ge_false": {}}}}, {"break": 2},
150
+
151
+ {"text": "Time Functions:"},
152
+ {"break": 1},
153
+ {"text": "current.weekday() = "}, {"lingo": {"call": "current.weekday"}}, {"break": 1},
154
+ {"text": "datetime.now() = "}, {"lingo": {"call": "datetime.now"}}, {"break": 1},
155
+ {"text": "random.randint(1, 10) = "}, {"lingo": {"call": "random.randint", "args": {"a": 1, "b": 10}}}, {"break": 1}
156
+ ]}
157
+ ]
158
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+
3
+ "params": {},
4
+
5
+ "state": {},
6
+
7
+ "ops": {},
8
+
9
+ "output": [
10
+ {"heading": {"text": "Hello World"}, "level": 1},
11
+ {"block": [
12
+ {"text": "I am a sample page."}
13
+ ]}
14
+ ]
15
+
16
+ }
@@ -0,0 +1,133 @@
1
+ project:
2
+ name:
3
+ lower_case: 'my sample store'
4
+
5
+ description: 'A sample project for mspec-alpha python app generator'
6
+
7
+ author:
8
+ name: 'B rad C'
9
+ email: 'sample@email.com'
10
+
11
+ server:
12
+ port: 7007
13
+
14
+ client:
15
+ default_host: 'http://localhost:7007'
16
+
17
+ modules:
18
+ store:
19
+ name:
20
+ lower_case: 'store'
21
+
22
+ models:
23
+ products:
24
+ name:
25
+ lower_case: 'products'
26
+
27
+ fields:
28
+
29
+ product_name:
30
+ type: str
31
+ examples:
32
+ - 'Laptop'
33
+ - 'Smartphone'
34
+ - 'Tablet'
35
+
36
+ random: random_thing_name
37
+
38
+ price:
39
+ type: float
40
+ examples:
41
+ - 999.99
42
+ - 499.99
43
+ - 299.99
44
+
45
+ in_stock:
46
+ type: bool
47
+ examples:
48
+ - true
49
+ - false
50
+
51
+ customers:
52
+ name:
53
+ lower_case: 'customers'
54
+
55
+ fields:
56
+
57
+ customer_name:
58
+ type: str
59
+ examples:
60
+ - 'Alice'
61
+ - 'Bob'
62
+ - 'Charlie'
63
+ random: random_person_name
64
+
65
+ email:
66
+ type: str
67
+ examples:
68
+ - 'alice@email.com'
69
+ - 'bob@email.com'
70
+ random: random_email
71
+
72
+ phone_number:
73
+ type: str
74
+ examples:
75
+ - '+1 (123) 456-7890'
76
+ - '+1 (987) 654-3210'
77
+ random: random_phone_number
78
+
79
+ admin:
80
+ name:
81
+ lower_case: 'admin'
82
+
83
+ models:
84
+ employees:
85
+ name:
86
+ lower_case: 'employees'
87
+
88
+ fields:
89
+
90
+ employee_name:
91
+ type: str
92
+ examples:
93
+ - 'David'
94
+ - 'Eve'
95
+ - 'Frank'
96
+ random: random_person_name
97
+
98
+ position:
99
+ type: str
100
+ enum:
101
+ - 'Manager'
102
+ - 'Sales'
103
+ - 'Support'
104
+ examples:
105
+ - 'Manager'
106
+ - 'Sales'
107
+ - 'Support'
108
+
109
+ hire_date:
110
+ type: str
111
+ examples:
112
+ - '2000-01-11T12:34:56'
113
+ - '2020-10-02T15:30:00'
114
+
115
+ email:
116
+ type: str
117
+ examples:
118
+ - 'my-name@email.com'
119
+ random: random_email
120
+
121
+ phone_number:
122
+ type: str
123
+ examples:
124
+ - '+1 (123) 456-7890'
125
+ - '+1 (987) 654-3210'
126
+ random: random_phone_number
127
+
128
+ salary:
129
+ type: float
130
+ examples:
131
+ - 60000.00
132
+ - 45000.00
133
+ - 35000.00