fakerforge 0.1.0__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.
- fakerforge/__init__.py +7 -0
- fakerforge/constraints/__init__.py +5 -0
- fakerforge/constraints/base.py +35 -0
- fakerforge/distributions/__init__.py +6 -0
- fakerforge/distributions/base.py +26 -0
- fakerforge/distributions/engine.py +335 -0
- fakerforge/faker.py +200 -0
- fakerforge/generator/__init__.py +5 -0
- fakerforge/generator/generator.py +68 -0
- fakerforge/providers/__init__.py +6 -0
- fakerforge/providers/base.py +16 -0
- fakerforge/providers/finance.py +112 -0
- fakerforge/py.typed +0 -0
- fakerforge/schema/__init__.py +25 -0
- fakerforge/schema/dataset.py +813 -0
- fakerforge/schema/generate.py +506 -0
- fakerforge/schema/result.py +137 -0
- fakerforge/schema/schema.py +59 -0
- fakerforge/validation/__init__.py +14 -0
- fakerforge/validation/dataset.py +438 -0
- fakerforge/validation/report.py +65 -0
- fakerforge/validation/validator.py +82 -0
- fakerforge-0.1.0.dist-info/METADATA +246 -0
- fakerforge-0.1.0.dist-info/RECORD +27 -0
- fakerforge-0.1.0.dist-info/WHEEL +5 -0
- fakerforge-0.1.0.dist-info/licenses/LICENSE +21 -0
- fakerforge-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Base class for FakerForge domain providers."""
|
|
2
|
+
|
|
3
|
+
from faker.providers import BaseProvider
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ForgeProvider(BaseProvider):
|
|
7
|
+
"""Base class for custom domain providers.
|
|
8
|
+
|
|
9
|
+
Subclass this and add public methods. Register the subclass with
|
|
10
|
+
:meth:`fakerforge.FakerForge.add_provider`. Registered methods are then
|
|
11
|
+
available on the ``FakerForge`` instance through Faker's provider lookup.
|
|
12
|
+
|
|
13
|
+
This class does not copy or replace Faker providers. It is a subclass of
|
|
14
|
+
:class:`faker.providers.BaseProvider`, so provider helpers such as
|
|
15
|
+
``random_element`` and ``numerify`` remain available.
|
|
16
|
+
"""
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Finance provider built on Faker's BaseProvider."""
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
from decimal import ROUND_HALF_UP, Decimal, InvalidOperation
|
|
5
|
+
|
|
6
|
+
from faker.providers import BaseProvider
|
|
7
|
+
|
|
8
|
+
_CENTS = Decimal("0.01")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FinanceProvider(BaseProvider):
|
|
12
|
+
"""Synthetic finance fields.
|
|
13
|
+
|
|
14
|
+
Methods draw from ``self.generator.random`` through Faker's provider
|
|
15
|
+
helpers, so they follow the ``FakerForge`` instance seed.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def credit_score(self, min_score: int = 300, max_score: int = 850) -> int:
|
|
19
|
+
"""Return an integer credit score in the inclusive range.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
min_score: Lowest accepted score.
|
|
23
|
+
max_score: Highest accepted score.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
A score between ``min_score`` and ``max_score``.
|
|
27
|
+
|
|
28
|
+
Raises:
|
|
29
|
+
TypeError: A bound is not an integer.
|
|
30
|
+
ValueError: ``min_score`` is greater than ``max_score``.
|
|
31
|
+
"""
|
|
32
|
+
low = _require_int(min_score, "min_score")
|
|
33
|
+
high = _require_int(max_score, "max_score")
|
|
34
|
+
_require_ordered(low, high, "min_score", "max_score")
|
|
35
|
+
return self.random_int(min=low, max=high)
|
|
36
|
+
|
|
37
|
+
def transaction_amount(
|
|
38
|
+
self,
|
|
39
|
+
min_amount: int | float | Decimal = 1,
|
|
40
|
+
max_amount: int | float | Decimal = 10000,
|
|
41
|
+
) -> Decimal:
|
|
42
|
+
"""Return a transaction amount in dollars and cents.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
min_amount: Lowest accepted amount.
|
|
46
|
+
max_amount: Highest accepted amount.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
A ``Decimal`` quantized to cents, inclusive of both bounds.
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
TypeError: An amount is not an int, float, or Decimal.
|
|
53
|
+
ValueError: An amount is not finite, or ``min_amount`` is greater
|
|
54
|
+
than ``max_amount``.
|
|
55
|
+
"""
|
|
56
|
+
low = _require_money(min_amount, "min_amount")
|
|
57
|
+
high = _require_money(max_amount, "max_amount")
|
|
58
|
+
_require_ordered(low, high, "min_amount", "max_amount")
|
|
59
|
+
cents = self.random_int(min=_to_cents(low), max=_to_cents(high))
|
|
60
|
+
return (Decimal(cents) / Decimal(100)).quantize(_CENTS)
|
|
61
|
+
|
|
62
|
+
def account_number(self, length: int = 12) -> str:
|
|
63
|
+
"""Return a numeric account number of the requested length.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
length: Number of digits. Leading zeros are allowed.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
A string of ``length`` digits.
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
TypeError: ``length`` is not an integer.
|
|
73
|
+
ValueError: ``length`` is less than 1.
|
|
74
|
+
"""
|
|
75
|
+
size = _require_int(length, "length")
|
|
76
|
+
if size < 1:
|
|
77
|
+
raise ValueError("length must be a positive integer")
|
|
78
|
+
return self.numerify("#" * size)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _require_int(value: object, label: str) -> int:
|
|
82
|
+
if isinstance(value, bool) or not isinstance(value, int):
|
|
83
|
+
raise TypeError(f"{label} must be an int")
|
|
84
|
+
return value
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _require_money(value: object, label: str) -> Decimal:
|
|
88
|
+
if isinstance(value, bool) or not isinstance(value, (int, float, Decimal)):
|
|
89
|
+
raise TypeError(f"{label} must be an int, float, or Decimal")
|
|
90
|
+
if isinstance(value, float) and not math.isfinite(value):
|
|
91
|
+
raise ValueError(f"{label} must be finite")
|
|
92
|
+
try:
|
|
93
|
+
amount = value if isinstance(value, Decimal) else Decimal(str(value))
|
|
94
|
+
except InvalidOperation as exc:
|
|
95
|
+
raise ValueError(f"{label} must be a finite number") from exc
|
|
96
|
+
if not amount.is_finite():
|
|
97
|
+
raise ValueError(f"{label} must be finite")
|
|
98
|
+
return amount.quantize(_CENTS, rounding=ROUND_HALF_UP)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _require_ordered(
|
|
102
|
+
low: int | Decimal,
|
|
103
|
+
high: int | Decimal,
|
|
104
|
+
low_label: str,
|
|
105
|
+
high_label: str,
|
|
106
|
+
) -> None:
|
|
107
|
+
if low > high:
|
|
108
|
+
raise ValueError(f"{low_label} must be less than or equal to {high_label}")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _to_cents(amount: Decimal) -> int:
|
|
112
|
+
return int((amount * 100).to_integral_value(rounding=ROUND_HALF_UP))
|
fakerforge/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Schema types for synthetic records."""
|
|
2
|
+
|
|
3
|
+
from fakerforge.schema.dataset import (
|
|
4
|
+
Column,
|
|
5
|
+
DatabaseSchema,
|
|
6
|
+
DatasetSchema,
|
|
7
|
+
GenerationError,
|
|
8
|
+
SchemaError,
|
|
9
|
+
TableSchema,
|
|
10
|
+
)
|
|
11
|
+
from fakerforge.schema.result import DatabaseResult, DatasetResult
|
|
12
|
+
from fakerforge.schema.schema import Field, Schema
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"Column",
|
|
16
|
+
"DatabaseResult",
|
|
17
|
+
"DatabaseSchema",
|
|
18
|
+
"DatasetResult",
|
|
19
|
+
"DatasetSchema",
|
|
20
|
+
"Field",
|
|
21
|
+
"GenerationError",
|
|
22
|
+
"Schema",
|
|
23
|
+
"SchemaError",
|
|
24
|
+
"TableSchema",
|
|
25
|
+
]
|