Skip to content

Commit

Permalink
Merge pull request #31 from barseghyanartur/dev
Browse files Browse the repository at this point in the history
Add JSON file provider
  • Loading branch information
barseghyanartur authored Jul 25, 2023
2 parents 2018f74 + 6c8956b commit 250752c
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 9 deletions.
4 changes: 2 additions & 2 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
"filename": "README.rst",
"hashed_secret": "077d5a0e0f8bb517307a6e92a73b0a9aa959233c",
"is_verified": true,
"line_number": 535
"line_number": 536
}
],
"examples/django_example/project/settings/base.py": [
Expand Down Expand Up @@ -176,5 +176,5 @@
}
]
},
"generated_at": "2023-07-25T19:48:32Z"
"generated_at": "2023-07-25T21:45:29Z"
}
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ are used for versioning (schema follows below):
0.3.4 to 0.4).
- All backwards incompatible changes are mentioned in this document.

0.17.2
------
2023-07-25

- Added ``JSON`` file provider.

0.17.1
------
2023-07-21
Expand Down
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ Supported file types
- ``ICO``
- ``GIF``
- ``JPEG``
- ``JSON``
- ``MP3``
- ``ODS``
- ``ODT``
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from setuptools import find_packages, setup

version = "0.17.1"
version = "0.17.2"

try:
readme = open(os.path.join(os.path.dirname(__file__), "README.rst")).read()
Expand Down
2 changes: 1 addition & 1 deletion src/faker_file/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = "faker_file"
__version__ = "0.17.1"
__version__ = "0.17.2"
__author__ = "Artur Barseghyan <[email protected]>"
__copyright__ = "2022-2023 Artur Barseghyan"
__license__ = "MIT"
11 changes: 6 additions & 5 deletions src/faker_file/providers/csv_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ class CsvFileProvider(BaseProvider, FileMixin):
from faker import Faker
from faker_file.providers.csv_file import CsvFileProvider
file = CsvFileProvider(Faker()).csv_file()
FAKER = Faker()
FAKER.add_provider(CsvFileProvider)
Usage example with options:
file = FAKER.csv_file()
from faker_file.providers.csv_file import CsvFileProvider
Usage example with options:
file = CsvFileProvider(Faker()).csv_file(
file = FAKER.csv_file(
prefix="zzz",
num_rows=100,
data_columns=('{{name}}', '{{sentence}}', '{{address}}'),
Expand All @@ -44,7 +45,7 @@ class CsvFileProvider(BaseProvider, FileMixin):
from django.conf import settings
from faker_file.storages.filesystem import FileSystemStorage
file = CsvFileProvider(Faker()).csv_file(
file = FAKER.csv_file(
storage=FileSystemStorage(
root_path=settings.MEDIA_ROOT,
rel_path="tmp",
Expand Down
78 changes: 78 additions & 0 deletions src/faker_file/providers/helpers/inner.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"create_inner_graphic_webp_file",
"create_inner_ico_file",
"create_inner_jpeg_file",
"create_inner_json_file",
"create_inner_mp3_file",
"create_inner_odp_file",
"create_inner_ods_file",
Expand Down Expand Up @@ -829,6 +830,83 @@ def create_inner_graphic_jpeg_file(
)


# ************************************************
# ******************** JSON **********************
# ************************************************


@overload
def create_inner_json_file(
storage: Optional[BaseStorage] = None,
basename: Optional[str] = None,
prefix: Optional[str] = None,
generator: Optional[Union[Faker, Generator, Provider]] = None,
data_columns: Optional[List] = None,
num_rows: int = 10,
indent: Optional[int] = None,
content: Optional[str] = None,
format_func: Callable[
[Union[Faker, Generator, Provider], str], str
] = DEFAULT_FORMAT_FUNC,
raw: bool = True,
**kwargs,
) -> BytesValue:
...


@overload
def create_inner_json_file(
storage: Optional[BaseStorage] = None,
basename: Optional[str] = None,
prefix: Optional[str] = None,
generator: Optional[Union[Faker, Generator, Provider]] = None,
data_columns: Optional[List] = None,
num_rows: int = 10,
indent: Optional[int] = None,
content: Optional[str] = None,
format_func: Callable[
[Union[Faker, Generator, Provider], str], str
] = DEFAULT_FORMAT_FUNC,
**kwargs,
) -> StringValue:
...


def create_inner_json_file(
storage: Optional[BaseStorage] = None,
basename: Optional[str] = None,
prefix: Optional[str] = None,
generator: Optional[Union[Faker, Generator, Provider]] = None,
data_columns: Optional[List] = None,
num_rows: int = 10,
indent: Optional[int] = None,
content: Optional[str] = None,
format_func: Callable[
[Union[Faker, Generator, Provider], str], str
] = DEFAULT_FORMAT_FUNC,
raw: bool = False,
**kwargs,
) -> Union[BytesValue, StringValue]:
"""Create inner JSON file."""
try:
from ..json_file import JsonFileProvider
except ImportError as err:
raise err

return JsonFileProvider(generator).json_file(
storage=storage,
basename=basename,
prefix=prefix,
data_columns=data_columns,
num_rows=num_rows,
indent=indent,
content=content,
format_func=format_func,
raw=raw,
**kwargs,
)


# ************************************************
# ********************* MP3 **********************
# ************************************************
Expand Down
173 changes: 173 additions & 0 deletions src/faker_file/providers/json_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
from typing import Callable, List, Optional, Union, overload

from faker import Faker
from faker.generator import Generator
from faker.providers import BaseProvider
from faker.providers.python import Provider

from ..base import DEFAULT_FORMAT_FUNC, BytesValue, FileMixin, StringValue
from ..storages.base import BaseStorage
from ..storages.filesystem import FileSystemStorage

__author__ = "Artur Barseghyan <[email protected]>"
__copyright__ = "2022-2023 Artur Barseghyan"
__license__ = "MIT"
__all__ = ("JsonFileProvider",)


FAKER = Faker()


class JsonFileProvider(BaseProvider, FileMixin):
"""JSON file provider.
Usage example:
from faker import Faker
from faker_file.providers.json_file import JsonFileProvider
FAKER = Faker()
FAKER.add_provider(JsonFileProvider)
file = FAKER.json_file()
Usage example with options:
file = FAKER.json_file(
prefix="zzz",
num_rows=100,
data_columns={"name": "{{name}}", "residency": "{{address}}"},
indent=4,
)
Usage example with `FileSystemStorage` storage (for `Django`):
from django.conf import settings
from faker_file.storages.filesystem import FileSystemStorage
file = FAKER.json_file(
storage=FileSystemStorage(
root_path=settings.MEDIA_ROOT,
rel_path="tmp",
),
prefix="zzz",
num_rows=100,
)
"""

extension: str = "json"

@overload
def json_file(
self: "JsonFileProvider",
storage: Optional[BaseStorage] = None,
basename: Optional[str] = None,
prefix: Optional[str] = None,
data_columns: Optional[List] = None,
num_rows: int = 10,
indent: Optional[int] = None,
content: Optional[str] = None,
encoding: Optional[str] = None,
format_func: Callable[
[Union[Faker, Generator, Provider], str], str
] = DEFAULT_FORMAT_FUNC,
raw: bool = True,
**kwargs,
) -> BytesValue:
...

@overload
def json_file(
self: "JsonFileProvider",
storage: Optional[BaseStorage] = None,
basename: Optional[str] = None,
prefix: Optional[str] = None,
data_columns: Optional[List] = None,
num_rows: int = 10,
indent: Optional[int] = None,
content: Optional[str] = None,
encoding: Optional[str] = None,
format_func: Callable[
[Union[Faker, Generator, Provider], str], str
] = DEFAULT_FORMAT_FUNC,
**kwargs,
) -> StringValue:
...

def json_file(
self: "JsonFileProvider",
storage: Optional[BaseStorage] = None,
basename: Optional[str] = None,
prefix: Optional[str] = None,
data_columns: Optional[List] = None,
num_rows: int = 10,
indent: Optional[int] = None,
content: Optional[str] = None,
encoding: Optional[str] = None,
format_func: Callable[
[Union[Faker, Generator, Provider], str], str
] = DEFAULT_FORMAT_FUNC,
raw: bool = False,
**kwargs,
) -> Union[BytesValue, StringValue]:
"""Generate a JSON file with random text.
:param storage: Storage. Defaults to `FileSystemStorage`.
:param basename: File basename (without extension).
:param prefix: File name prefix.
:param data_columns: The ``data_columns`` argument expects a dict of
string tokens, and these string tokens will be passed to
:meth:`parse()
<faker.providers.python.Provider.parse>`
for data generation. Argument Groups are used to pass arguments
to the provider methods.
:param num_rows: The ``num_rows`` argument controls how many rows of
data to generate, and the ``include_row_ids`` argument may be set
to ``True`` to include a sequential row ID column.
:param indent: Number of spaces to indent the fields.
:param content: File content. If given, used as is.
:param encoding: Encoding.
:param format_func: Callable responsible for formatting template
strings.
:param raw: If set to True, return `BytesValue` (binary content of
the file). Otherwise, return `StringValue` (path to the saved
file).
:return: Relative path (from root directory) of the generated file
or raw content of the file.
"""
# Generic
if storage is None:
storage = FileSystemStorage()

filename = storage.generate_filename(
extension=self.extension,
prefix=prefix,
basename=basename,
)

if self.generator is None:
self.generator = Faker()

# Specific
if content is None:
content = self.generator.json(
data_columns=data_columns,
num_rows=num_rows,
indent=indent,
)
else:
content = format_func(self.generator, content)

data = {"content": content, "filename": filename}

if raw:
raw_content = BytesValue(content.encode("utf8"))
raw_content.data = data
return raw_content

storage.write_text(filename, content, encoding=encoding)

# Generic
file_name = StringValue(storage.relpath(filename))
file_name.data = data
return file_name
Loading

0 comments on commit 250752c

Please sign in to comment.