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

barseghyanartur / faker-file / 4952667591

pending completion
4952667591

push

github

Artur Barseghyan
MyPy fixes

1612 of 1614 relevant lines covered (99.88%)

6.11 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
5✔
2
import inspect
5✔
3
import os
5✔
4
import sys
5✔
5
import typing
5✔
6
from copy import deepcopy
5✔
7
from typing import Any, Dict, Tuple, Type
5✔
8

9
from faker import Faker
5✔
10

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

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

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

127

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

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

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

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

149
    return model_props, annotations
5✔
150

151

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

159

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

165

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

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

175
    case $prev in"""
176

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

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

191
    return 0
192
}
193

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

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

202
    print(f"Generated bash completion file: {file_path}")
5✔
203

204

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

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

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

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

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

248
    args = parser.parse_args()
5✔
249

250
    if args.command == "generate-completion":
5✔
251
        generate_completion_file()
5✔
252
    elif args.command:
5✔
253
        kwargs = {k: v for k, v in vars(args).items() if k not in ("command",)}
5✔
254
        for counter in range(args.nb_files):
5✔
255
            output_file = generate_file(args.command, **kwargs)
5✔
256
            print(
5✔
257
                f"Generated {args.command} file "
258
                f"({counter+1} of {args.nb_files}): "
259
                f"{output_file.data['filename']}"
260
            )
261
    else:
262
        parser.print_help()
5✔
263
        sys.exit(1)
5✔
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