• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

barseghyanartur / faker-file / 5305826025

pending completion
5305826025

push

github

barseghyanartur
Prepare 0.15.5

1793 of 1795 relevant lines covered (99.89%)

5.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/faker_file/cli.py
1
import argparse
4✔
2
import inspect
4✔
3
import os
4✔
4
import sys
4✔
5
import typing
4✔
6
from copy import deepcopy
4✔
7
from typing import Any, Dict, Tuple, Type
4✔
8

9
from faker import Faker
4✔
10

11
from .base import FileMixin, StringValue
4✔
12
from .providers.bin_file import BinFileProvider
4✔
13
from .providers.csv_file import CsvFileProvider
4✔
14
from .providers.docx_file import DocxFileProvider
4✔
15
from .providers.eml_file import EmlFileProvider
4✔
16
from .providers.epub_file import EpubFileProvider
4✔
17
from .providers.generic_file import GenericFileProvider
4✔
18
from .providers.ico_file import IcoFileProvider
4✔
19
from .providers.jpeg_file import JpegFileProvider
4✔
20
from .providers.mp3_file import Mp3FileProvider
4✔
21
from .providers.odp_file import OdpFileProvider
4✔
22
from .providers.ods_file import OdsFileProvider
4✔
23
from .providers.odt_file import OdtFileProvider
4✔
24
from .providers.pdf_file import PdfFileProvider
4✔
25
from .providers.png_file import PngFileProvider
4✔
26
from .providers.pptx_file import PptxFileProvider
4✔
27
from .providers.rtf_file import RtfFileProvider
4✔
28
from .providers.svg_file import SvgFileProvider
4✔
29
from .providers.tar_file import TarFileProvider
4✔
30
from .providers.txt_file import TxtFileProvider
4✔
31
from .providers.webp_file import WebpFileProvider
4✔
32
from .providers.xlsx_file import XlsxFileProvider
4✔
33
from .providers.xml_file import XmlFileProvider
4✔
34
from .providers.zip_file import ZipFileProvider
4✔
35

36
__author__ = "Artur Barseghyan <artur.barseghyan@gmail.com>"
4✔
37
__copyright__ = "2023 Artur Barseghyan"
4✔
38
__license__ = "MIT"
4✔
39
__all__ = [
4✔
40
    "main",
41
    "get_method_kwargs",
42
    "generate_file",
43
]
44

45
KWARGS_DROP = {
4✔
46
    "self",  # Drop as irrelevant
47
    "storage",  # Drop as non-supported arg
48
    "return",  # Drop as irrelevant
49
    # "mp3_generator_cls",  # Drop as non-supported arg
50
    # "mp3_generator_kwargs",  # Drop as non-supported arg
51
    # "pdf_generator_cls",  # Drop as non-supported arg
52
    # "pdf_generator_kwargs",  # Drop as non-supported arg
53
    "format_func",  # Drop as non-supported arg
54
    "raw",  # Drop `raw`, because we will be forcing raw=True for streaming
55
}
56
OVERRIDES = {
4✔
57
    "DocxFileProvider.docx_file": {
58
        "annotations": {
59
            "content": str,
60
        },
61
        "model_props": {
62
            "content": None,
63
        },
64
    },
65
    "GenericFileProvider.generic_file": {
66
        "annotations": {
67
            "content": str,
68
        },
69
        "model_props": {},
70
    },
71
    "Mp3FileProvider.mp3_file": {
72
        "annotations": {
73
            "mp3_generator_cls": str,
74
        },
75
        "model_props": {
76
            "mp3_generator_cls": (
77
                "faker_file.providers.mp3_file.generators"
78
                ".gtts_generator.GttsMp3Generator"
79
            ),
80
        },
81
    },
82
    "OdtFileProvider.odt_file": {
83
        "annotations": {
84
            "content": str,
85
        },
86
        "model_props": {
87
            "content": None,
88
        },
89
    },
90
    "PdfFileProvider.pdf_file": {
91
        "annotations": {
92
            "pdf_generator_cls": str,
93
        },
94
        "model_props": {
95
            "pdf_generator_cls": (
96
                "faker_file.providers.pdf_file.generators"
97
                ".pdfkit_generator.PdfkitPdfGenerator"
98
            ),
99
        },
100
    },
101
}
102
PROVIDERS = {
4✔
103
    BinFileProvider.bin_file.__name__: BinFileProvider,
104
    CsvFileProvider.csv_file.__name__: CsvFileProvider,
105
    DocxFileProvider.docx_file.__name__: DocxFileProvider,
106
    EmlFileProvider.eml_file.__name__: EmlFileProvider,
107
    EpubFileProvider.epub_file.__name__: EpubFileProvider,
108
    GenericFileProvider.generic_file.__name__: GenericFileProvider,
109
    IcoFileProvider.ico_file.__name__: IcoFileProvider,
110
    JpegFileProvider.jpeg_file.__name__: JpegFileProvider,
111
    Mp3FileProvider.mp3_file.__name__: Mp3FileProvider,
112
    OdpFileProvider.odp_file.__name__: OdpFileProvider,
113
    OdsFileProvider.ods_file.__name__: OdsFileProvider,
114
    OdtFileProvider.odt_file.__name__: OdtFileProvider,
115
    PdfFileProvider.pdf_file.__name__: PdfFileProvider,
116
    PngFileProvider.png_file.__name__: PngFileProvider,
117
    PptxFileProvider.pptx_file.__name__: PptxFileProvider,
118
    RtfFileProvider.rtf_file.__name__: RtfFileProvider,
119
    SvgFileProvider.svg_file.__name__: SvgFileProvider,
120
    TarFileProvider.tar_file.__name__: TarFileProvider,
121
    TxtFileProvider.txt_file.__name__: TxtFileProvider,
122
    WebpFileProvider.webp_file.__name__: WebpFileProvider,
123
    XlsxFileProvider.xlsx_file.__name__: XlsxFileProvider,
124
    XmlFileProvider.xml_file.__name__: XmlFileProvider,
125
    ZipFileProvider.zip_file.__name__: ZipFileProvider,
126
}
127

128

129
def get_method_kwargs(
4✔
130
    cls: Type[FileMixin], method_name: str
131
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
132
    method = getattr(cls, method_name)
4✔
133
    method_specs = inspect.getfullargspec(method)
4✔
134

135
    kwargs = deepcopy(method_specs.args[1:])  # Omit `self`
4✔
136
    defaults = deepcopy(method_specs.defaults if method_specs.defaults else [])
4✔
137
    model_props = dict(zip(kwargs, defaults))
4✔
138
    annotations = deepcopy(method_specs.annotations)
4✔
139

140
    # Override the type definition for mp3_generator_cls
141
    override = OVERRIDES.get(f"{cls.__name__}.{method_name}", None)
4✔
142
    if override:
4✔
143
        annotations.update(override["annotations"])
4✔
144
        model_props.update(override["model_props"])
4✔
145

146
    for kwarg_name in KWARGS_DROP:
4✔
147
        annotations.pop(kwarg_name, None)
4✔
148
        model_props.pop(kwarg_name, None)
4✔
149

150
    return model_props, annotations
4✔
151

152

153
def generate_file(method_name: str, **kwargs) -> StringValue:
4✔
154
    faker = Faker()
4✔
155
    cls = PROVIDERS[method_name]
4✔
156
    method = getattr(cls(faker), method_name)
4✔
157
    value = method(**kwargs)
4✔
158
    return value
4✔
159

160

161
def is_optional_type(t: Any) -> bool:
4✔
162
    if getattr(t, "__origin__", None) is typing.Union:
4✔
163
        return any(arg is type(None) for arg in t.__args__)  # noqa
4✔
164
    return False
4✔
165

166

167
def generate_completion_file():
4✔
168
    completion_script = f"""#!/bin/bash
4✔
169

170
_faker_file_completion() {{
171
    local cur prev providers
172
    cur="${{COMP_WORDS[COMP_CWORD]}}"
173
    prev="${{COMP_WORDS[COMP_CWORD - 1]}}"
174
    providers="{(' '.join(PROVIDERS.keys()))}"
175

176
    case $prev in"""
177

178
    for method_name, provider in PROVIDERS.items():
4✔
179
        method_kwargs, _ = get_method_kwargs(provider, method_name)
4✔
180
        completion_script += f"""
4✔
181
        {method_name})
182
            COMPREPLY=($(compgen -W "{(' '.join('--' + k for k in method_kwargs.keys()))} --nb_files" -- "$cur"))
183
            ;;
184
        """  # noqa
185

186
    completion_script += """
4✔
187
        *)
188
            COMPREPLY=($(compgen -W "$providers" -- "$cur"))
189
            ;;
190
    esac
191

192
    return 0
193
}
194

195
complete -F _faker_file_completion faker-file
196
"""
197

198
    user_home_dir = os.path.expanduser("~")
4✔
199
    file_path = os.path.join(user_home_dir, "faker_file_completion.sh")
4✔
200
    with open(file_path, "w") as f:
4✔
201
        f.write(completion_script)
4✔
202

203
    print(f"Generated bash completion file: {file_path}")
4✔
204

205

206
def main():
4✔
207
    parser = argparse.ArgumentParser(
4✔
208
        description="CLI for the faker-file package."
209
    )
210
    subparsers = parser.add_subparsers(
4✔
211
        dest="command", help="Available file providers."
212
    )
213

214
    # Add generate-completion subparser
215
    __generate_completion_subparser = subparsers.add_parser(
4✔
216
        "generate-completion",
217
        help="Generate bash completion file.",
218
    )
219

220
    for method_name, provider in PROVIDERS.items():
4✔
221
        subparser = subparsers.add_parser(
4✔
222
            method_name,
223
            help=f"Generate a {method_name.split('_file')[0]} file.",
224
        )
225
        method_kwargs, annotations = get_method_kwargs(provider, method_name)
4✔
226
        for arg, default in method_kwargs.items():
4✔
227
            arg_type = annotations[arg]
4✔
228
            arg_kwargs = {
4✔
229
                "default": default,
230
                "help": f"{arg} (default: {default})",
231
                "type": (
232
                    arg_type.__args__[0]
233
                    if isinstance(arg_type, typing._GenericAlias)
234
                    and is_optional_type(arg_type)
235
                    else arg_type
236
                ),
237
            }
238

239
            subparser.add_argument(f"--{arg}", **arg_kwargs)
4✔
240

241
        # Add the optional num_files argument
242
        subparser.add_argument(
4✔
243
            "--nb_files",
244
            default=1,
245
            type=int,
246
            help="number of files to generate (default: 1)",
247
        )
248

249
    args = parser.parse_args()
4✔
250

251
    if args.command == "generate-completion":
4✔
252
        generate_completion_file()
4✔
253
    elif args.command:
4✔
254
        kwargs = {k: v for k, v in vars(args).items() if k not in ("command",)}
4✔
255
        for counter in range(args.nb_files):
4✔
256
            output_file = generate_file(args.command, **kwargs)
4✔
257
            print(
4✔
258
                f"Generated {args.command} file "
259
                f"({counter+1} of {args.nb_files}): "
260
                f"{output_file.data['filename']}"
261
            )
262
    else:
263
        parser.print_help()
4✔
264
        sys.exit(1)
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc