xmlgenerator 0.2.0__py3-none-any.whl → 0.2.1__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.
- xmlgenerator/bootstrap.py +1 -1
- xmlgenerator/generator.py +24 -10
- xmlgenerator/randomization.py +28 -2
- xmlgenerator/substitution.py +28 -18
- {xmlgenerator-0.2.0.dist-info → xmlgenerator-0.2.1.dist-info}/METADATA +2 -1
- xmlgenerator-0.2.1.dist-info/RECORD +14 -0
- xmlgenerator-0.2.0.dist-info/RECORD +0 -14
- {xmlgenerator-0.2.0.dist-info → xmlgenerator-0.2.1.dist-info}/WHEEL +0 -0
- {xmlgenerator-0.2.0.dist-info → xmlgenerator-0.2.1.dist-info}/entry_points.txt +0 -0
- {xmlgenerator-0.2.0.dist-info → xmlgenerator-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {xmlgenerator-0.2.0.dist-info → xmlgenerator-0.2.1.dist-info}/top_level.txt +0 -0
xmlgenerator/bootstrap.py
CHANGED
@@ -49,7 +49,7 @@ def _main():
|
|
49
49
|
|
50
50
|
logger.debug('found %s schemas', len(xsd_files))
|
51
51
|
for xsd_file in xsd_files:
|
52
|
-
logger.
|
52
|
+
logger.info('processing schema: %s', xsd_file.name)
|
53
53
|
|
54
54
|
# get configuration override for current schema
|
55
55
|
local_config = config.get_for_file(xsd_file.name)
|
xmlgenerator/generator.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
import re
|
3
3
|
|
4
|
-
import rstr
|
5
4
|
import xmlschema
|
6
5
|
from lxml import etree
|
7
6
|
from xmlschema.validators import XsdComplexType, XsdAtomicRestriction, XsdTotalDigitsFacet, XsdElement, \
|
@@ -296,10 +295,11 @@ class XmlGenerator:
|
|
296
295
|
|
297
296
|
def _generate_string(self, target_name, patterns, min_length, max_length):
|
298
297
|
rnd = self.randomizer.rnd
|
298
|
+
re_gen = self.randomizer.re_gen
|
299
299
|
if patterns is not None:
|
300
300
|
# Генерация строки по regex
|
301
301
|
random_pattern = rnd.choice(patterns)
|
302
|
-
xeger =
|
302
|
+
xeger = re_gen.xeger(random_pattern.attrib['value'])
|
303
303
|
xeger = re.sub(r'\s', ' ', xeger)
|
304
304
|
if min_length > -1 and len(xeger) < min_length:
|
305
305
|
logger.warning(
|
@@ -358,29 +358,43 @@ class XmlGenerator:
|
|
358
358
|
raise RuntimeError("not yet implemented")
|
359
359
|
|
360
360
|
def _generate_datetime(self):
|
361
|
-
|
361
|
+
random_datetime = self.randomizer.random_datetime()
|
362
|
+
formatted = random_datetime.isoformat()
|
363
|
+
return formatted
|
362
364
|
|
363
365
|
def _generate_date(self):
|
364
|
-
|
366
|
+
random_date = self.randomizer.random_date()
|
367
|
+
formatted = random_date.isoformat()
|
368
|
+
return formatted
|
365
369
|
|
366
370
|
def _generate_time(self):
|
367
|
-
|
371
|
+
random_time = self.randomizer.random_time()
|
372
|
+
formatted = random_time.isoformat()
|
373
|
+
return formatted
|
368
374
|
|
369
375
|
def _generate_gyearmonth(self):
|
370
|
-
|
376
|
+
random_date = self.randomizer.random_date()
|
377
|
+
formatted = random_date.strftime('%Y-%m')
|
378
|
+
return formatted
|
371
379
|
|
372
380
|
def _generate_gyear(self):
|
373
381
|
rnd = self.randomizer.rnd
|
374
|
-
return rnd.randint(2000, 2050)
|
382
|
+
return str(rnd.randint(2000, 2050))
|
375
383
|
|
376
384
|
def _generate_gmonthday(self):
|
377
|
-
|
385
|
+
random_date = self.randomizer.random_date()
|
386
|
+
formatted = random_date.strftime('--%m-%d')
|
387
|
+
return formatted
|
378
388
|
|
379
389
|
def _generate_gday(self):
|
380
|
-
|
390
|
+
random_date = self.randomizer.random_date()
|
391
|
+
formatted = random_date.strftime('---%d')
|
392
|
+
return formatted
|
381
393
|
|
382
394
|
def _generate_gmonth(self):
|
383
|
-
|
395
|
+
random_date = self.randomizer.random_date()
|
396
|
+
formatted = random_date.strftime('--%m--')
|
397
|
+
return formatted
|
384
398
|
|
385
399
|
def _generate_hex_binary(self):
|
386
400
|
raise RuntimeError("not yet implemented")
|
xmlgenerator/randomization.py
CHANGED
@@ -2,8 +2,9 @@ import logging
|
|
2
2
|
import random
|
3
3
|
import string
|
4
4
|
import sys
|
5
|
-
from datetime import datetime, timedelta
|
5
|
+
from datetime import datetime, date, time, timedelta
|
6
6
|
|
7
|
+
import rstr
|
7
8
|
from faker import Faker
|
8
9
|
|
9
10
|
logger = logging.getLogger(__name__)
|
@@ -20,6 +21,7 @@ class Randomizer:
|
|
20
21
|
self.rnd = random.Random(seed)
|
21
22
|
self.fake = Faker(locale='ru_RU')
|
22
23
|
self.fake.seed_instance(seed)
|
24
|
+
self.re_gen = rstr.Rstr(self.rnd)
|
23
25
|
|
24
26
|
def ascii_string(self, min_length=-1, max_length=-1):
|
25
27
|
min_length = min_length if min_length and min_length > -1 else 1
|
@@ -31,7 +33,31 @@ class Randomizer:
|
|
31
33
|
letters = string.ascii_letters # Все буквы латиницы (a-z, A-Z)
|
32
34
|
return ''.join(self.rnd.choice(letters) for _ in range(length))
|
33
35
|
|
34
|
-
def random_date(self, start_date: str, end_date: str) ->
|
36
|
+
def random_date(self, start_date: str = '1990-01-01', end_date: str = '2025-12-31') -> date:
|
37
|
+
# Преобразуем строки в объекты datetime
|
38
|
+
start = date.fromisoformat(start_date)
|
39
|
+
end = date.fromisoformat(end_date)
|
40
|
+
|
41
|
+
# Вычисляем разницу в днях между начальной и конечной датой
|
42
|
+
delta = (end - start).days
|
43
|
+
|
44
|
+
# Генерируем случайное количество дней в пределах delta
|
45
|
+
random_days = self.rnd.randint(0, delta)
|
46
|
+
|
47
|
+
# Добавляем случайное количество дней к начальной дате
|
48
|
+
return start + timedelta(days=random_days)
|
49
|
+
|
50
|
+
def random_time(self, start_time: str = '00:00:00', end_time: str = '23:59:59') -> time:
|
51
|
+
start = time.fromisoformat(start_time)
|
52
|
+
end = time.fromisoformat(end_time)
|
53
|
+
|
54
|
+
random_h = self.rnd.randint(start.hour, end.hour)
|
55
|
+
random_m = self.rnd.randint(start.minute, end.minute)
|
56
|
+
random_s = self.rnd.randint(start.second, end.second)
|
57
|
+
|
58
|
+
return time(hour=random_h, minute=random_m, second=random_s)
|
59
|
+
|
60
|
+
def random_datetime(self, start_date: str = '1990-01-01', end_date: str = '2025-12-31') -> datetime:
|
35
61
|
# Преобразуем строки в объекты datetime
|
36
62
|
start = datetime.strptime(start_date, "%Y-%m-%d")
|
37
63
|
end = datetime.strptime(end_date, "%Y-%m-%d")
|
xmlgenerator/substitution.py
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
import logging
|
2
2
|
import re
|
3
|
-
import uuid
|
4
|
-
|
5
|
-
import rstr
|
6
3
|
|
7
4
|
from xmlgenerator.randomization import Randomizer
|
8
5
|
|
9
6
|
__all__ = ['Substitutor']
|
10
7
|
|
11
|
-
_pattern = re.compile(
|
8
|
+
_pattern = re.compile(
|
9
|
+
r'\{\{\s*(?:(?P<function>\S*?)(?:\(\s*(?P<argument>[^)]*)\s*\))?\s*(?:\|\s*(?P<modifier>.*?))?)?\s*}}')
|
12
10
|
|
13
11
|
logger = logging.getLogger(__name__)
|
14
12
|
|
13
|
+
|
15
14
|
class Substitutor:
|
16
15
|
def __init__(self, randomizer: Randomizer):
|
17
16
|
fake = randomizer.fake
|
@@ -20,18 +19,19 @@ class Substitutor:
|
|
20
19
|
self._global_context = {}
|
21
20
|
self.providers_dict = {
|
22
21
|
# Функции локального контекста
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
'uuid': lambda:
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
22
|
+
'source_filename': lambda: self._local_context["source_filename"],
|
23
|
+
'source_extracted': lambda: self._local_context["source_extracted"],
|
24
|
+
'output_filename': lambda: self.get_output_filename(),
|
25
|
+
|
26
|
+
'uuid': lambda: fake.uuid4(),
|
27
|
+
'regex': self._rand_regex,
|
28
|
+
'any': self._rand_any,
|
29
|
+
'number': self._rand_int,
|
30
|
+
'date': self._rand_date,
|
31
|
+
|
32
|
+
'last_name': fake.last_name_male,
|
33
|
+
'first_name': fake.first_name_male,
|
34
|
+
'middle_name': fake.middle_name_male,
|
35
35
|
'address_text': fake.address,
|
36
36
|
'administrative_unit': fake.administrative_unit,
|
37
37
|
'house_number': fake.building_number,
|
@@ -48,6 +48,16 @@ class Substitutor:
|
|
48
48
|
'snils_formatted': randomizer.snils_formatted,
|
49
49
|
}
|
50
50
|
|
51
|
+
def _rand_regex(self, a):
|
52
|
+
pattern = a.strip("'").strip('"')
|
53
|
+
return self.randomizer.re_gen.xeger(pattern)
|
54
|
+
|
55
|
+
def _rand_any(self, a):
|
56
|
+
args = str(a).split(sep=",")
|
57
|
+
value = self.randomizer.rnd.choice(args)
|
58
|
+
value = value.strip(' ').strip("'").strip('"')
|
59
|
+
return value
|
60
|
+
|
51
61
|
def _rand_int(self, a):
|
52
62
|
args = str(a).split(sep=",")
|
53
63
|
return str(self.randomizer.rnd.randint(int(args[0]), int(args[1])))
|
@@ -56,8 +66,8 @@ class Substitutor:
|
|
56
66
|
args = str(a).split(sep=",")
|
57
67
|
date_from = args[0].strip(' ').strip("'").strip('"')
|
58
68
|
date_until = args[1].strip(' ').strip("'").strip('"')
|
59
|
-
random_date = self.randomizer.
|
60
|
-
return random_date.strftime('%Y%m%d')
|
69
|
+
random_date = self.randomizer.random_datetime(date_from, date_until)
|
70
|
+
return random_date.strftime('%Y%m%d') # TODO externalize pattern
|
61
71
|
|
62
72
|
def reset_context(self, xsd_filename, config_local):
|
63
73
|
self._local_context.clear()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: xmlgenerator
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.1
|
4
4
|
Summary: Generates XML documents from XSD schemas
|
5
5
|
Home-page: https://github.com/lexakimov/xmlgenerator
|
6
6
|
Author: Alexey Akimov
|
@@ -247,6 +247,7 @@ In the `value_override` sections, you can specify either a string value or speci
|
|
247
247
|
| `output_filename` | String described by the `output_filename_template` configuration parameter |
|
248
248
|
| `uuid` | Random UUIDv4 |
|
249
249
|
| `regex("pattern")` | Random string value matching the specified regular expression |
|
250
|
+
| `any('A', "B", C)` | Random value from enumeration |
|
250
251
|
| `number(A, B)` | Random number between A and B |
|
251
252
|
| `date("2010-01-01", "2025-01-01")` | Random date within the specified range |
|
252
253
|
| `last_name` | Last Name |
|
@@ -0,0 +1,14 @@
|
|
1
|
+
xmlgenerator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
xmlgenerator/arguments.py,sha256=E0b5ndlGAxu39OgRatqmPdWSkS5EvCTLUEMKFgezi7c,4612
|
3
|
+
xmlgenerator/bootstrap.py,sha256=bPVHugpMSkv54_8Kxe0RPqyvIxC3cci-1yehntZm_YY,3510
|
4
|
+
xmlgenerator/configuration.py,sha256=DiYUpNCjkerjr73yD209q8FJwGWgipbwWXuLkt25rQM,5903
|
5
|
+
xmlgenerator/generator.py,sha256=Ci3xuOoG2jpTcoRa2c1BEDI_4hIfEd3iU05tcgB0paM,18877
|
6
|
+
xmlgenerator/randomization.py,sha256=LK4ZwSZdyks7qV0OOxKsGyKA0q660ID7x2DeU9gvL_I,3261
|
7
|
+
xmlgenerator/substitution.py,sha256=mD827EbgYg2mTp-PNcvsERJtVUKaLvaoOoQmGnq5zBo,5595
|
8
|
+
xmlgenerator/validation.py,sha256=uCJjS5YmRDlAp9C-5Rd4E2Brh6_3WOG2-dSGxDiaH14,2023
|
9
|
+
xmlgenerator-0.2.1.dist-info/licenses/LICENSE,sha256=QlXK8O3UcoAYUYwVJNgB9MSM7O94ogNo_1hd9GzznUQ,1070
|
10
|
+
xmlgenerator-0.2.1.dist-info/METADATA,sha256=zfA1y1vFm58sX2tRolF6G8LngaBGViSPp8C2Xp7_PvY,12801
|
11
|
+
xmlgenerator-0.2.1.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
12
|
+
xmlgenerator-0.2.1.dist-info/entry_points.txt,sha256=ly9hKr3o4AzFUkelBZNRzyKYf-Ld4kfcffvBu1oHq54,61
|
13
|
+
xmlgenerator-0.2.1.dist-info/top_level.txt,sha256=jr7FbMBm8MQ6j8I_-nWzQQEseXzwSCZNXgrkWuk9P4E,13
|
14
|
+
xmlgenerator-0.2.1.dist-info/RECORD,,
|
@@ -1,14 +0,0 @@
|
|
1
|
-
xmlgenerator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
xmlgenerator/arguments.py,sha256=E0b5ndlGAxu39OgRatqmPdWSkS5EvCTLUEMKFgezi7c,4612
|
3
|
-
xmlgenerator/bootstrap.py,sha256=FW1wyWRLY9LFFWFTV0XNycFWMfkXP2jwfcfIapzFGUA,3511
|
4
|
-
xmlgenerator/configuration.py,sha256=DiYUpNCjkerjr73yD209q8FJwGWgipbwWXuLkt25rQM,5903
|
5
|
-
xmlgenerator/generator.py,sha256=aAXGyiqzkU5eWiOaixMs9sPvm9EZZjQVZBdQvqtyB_A,18306
|
6
|
-
xmlgenerator/randomization.py,sha256=cPnUWrvylIw2GH1FAW2SvyqdQQJDcoU8AgEmakPfB-I,1993
|
7
|
-
xmlgenerator/substitution.py,sha256=p0j5QXhNHBJPlDJAQ33dV8wlnWVdO05cOvh9ggP9uFY,5277
|
8
|
-
xmlgenerator/validation.py,sha256=uCJjS5YmRDlAp9C-5Rd4E2Brh6_3WOG2-dSGxDiaH14,2023
|
9
|
-
xmlgenerator-0.2.0.dist-info/licenses/LICENSE,sha256=QlXK8O3UcoAYUYwVJNgB9MSM7O94ogNo_1hd9GzznUQ,1070
|
10
|
-
xmlgenerator-0.2.0.dist-info/METADATA,sha256=rLtz6c0Oosz79qqZvR5A7l5ZBjcnHJr2m6wWLn327CY,12653
|
11
|
-
xmlgenerator-0.2.0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
12
|
-
xmlgenerator-0.2.0.dist-info/entry_points.txt,sha256=ly9hKr3o4AzFUkelBZNRzyKYf-Ld4kfcffvBu1oHq54,61
|
13
|
-
xmlgenerator-0.2.0.dist-info/top_level.txt,sha256=jr7FbMBm8MQ6j8I_-nWzQQEseXzwSCZNXgrkWuk9P4E,13
|
14
|
-
xmlgenerator-0.2.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|