Skip to content

Commit fab1a56

Browse files
committed
[FEAT] add email validation feature, add current version printing method(need modifing)
1 parent 7abba98 commit fab1a56

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

src/fastapi_fastkit/cli.py

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#
55
# @author bnbong bbbong9@gmail.com
66
# --------------------------------------------------------------------------
7+
import re
78
import os
89
import click
910

@@ -29,6 +30,31 @@
2930
# --------------------------------------------------------------------------
3031
# Backend operators
3132
# --------------------------------------------------------------------------
33+
REGEX = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b"
34+
35+
36+
def validate_email(ctx, param, value):
37+
"""
38+
Check if the provided email is in a valid format.
39+
This will recursively loop until a valid email input entry is given.
40+
41+
:param ctx: context of passing configurations (NOT specify it at CLI)
42+
:type ctx: <Object click.Context>
43+
:param param: parameters from CLI
44+
:param value: values from CLI
45+
:return:
46+
"""
47+
try:
48+
if not re.match(REGEX, value):
49+
raise ValueError(value)
50+
else:
51+
return value
52+
except ValueError as e:
53+
click.echo("Incorrect email address given: {}".format(e))
54+
value = click.prompt(param.prompt)
55+
return validate_email(ctx, param, value)
56+
57+
3258
def _inject_project_metadata(
3359
target_dir: str,
3460
project_name: str,
@@ -71,11 +97,27 @@ def _inject_project_metadata(
7197
raise TemplateExceptions("ERROR : Having some errors with injecting metadata")
7298

7399

100+
def _print_version(ctx: Context, value: click.Option, *args, **kwargs) -> None:
101+
# TODO : apply this at fastapi-cli group
102+
"""
103+
print current version of fastapi-fastkit
104+
105+
:param ctx: context of passing configurations (NOT specify it at CLI)
106+
:type ctx: <Object click.Context>
107+
"""
108+
if value:
109+
version_info = f"fastapi-fastkit version {__version__}"
110+
click.echo(print(version_info))
111+
ctx.exit()
112+
113+
74114
# --------------------------------------------------------------------------
75115
# Click operator methods
76116
# --------------------------------------------------------------------------
77117
@click.group()
78118
@click.option("--debug/--no-debug", default=False)
119+
# @click.option('--version', callback=_print_version,
120+
# expose_value=False)
79121
@click.pass_context
80122
def fastkit_cli(ctx: Context, debug: bool) -> Union["BaseCommand", None]:
81123
"""
@@ -138,7 +180,7 @@ def echo(ctx: Context) -> None:
138180

139181

140182
@fastkit_cli.command(context_settings={"ignore_unknown_options": True})
141-
@click.argument("template")
183+
@click.argument("template", default="fastapi-default")
142184
@click.option(
143185
"--project-name",
144186
prompt="Enter the project name",
@@ -151,6 +193,8 @@ def echo(ctx: Context) -> None:
151193
"--author-email",
152194
prompt="Enter the author email",
153195
help="The email of the project author.",
196+
type=str,
197+
callback=validate_email,
154198
)
155199
@click.option(
156200
"--description",
@@ -166,6 +210,7 @@ def startproject(
166210
author_email: str,
167211
description: str,
168212
) -> None:
213+
# TODO : add a feature - name project folder name to project_name
169214
"""
170215
Create a new FastAPI project from templates and inject metadata.
171216
@@ -179,22 +224,36 @@ def startproject(
179224
settings = ctx.obj["settings"]
180225

181226
template_dir = settings.FASTKIT_TEMPLATE_ROOT
227+
click.echo(f"Deploying FastAPI project using '{template}' template")
182228
target_template = os.path.join(template_dir, template)
183229
print(f"Template path: {target_template}")
184230

185231
if not os.path.exists(target_template):
186232
raise CLIExceptions(
187233
f"Error: Template '{template}' does not exist in '{template_dir}'."
188234
)
235+
# TODO : add confirm step : checking template stack & name & metadata, confirm it y/n
236+
# click.echo("Project Stack: [FastAPI, Uvicorn, SQLAlchemy, Docker (optional)]")
237+
238+
confirm = click.confirm(
239+
"\nDo you want to proceed with project creation?", default=False
240+
)
241+
if not confirm:
242+
click.echo("Project creation aborted!")
243+
return
189244

190245
try:
191246
user_local = settings.USER_WORKSPACE
192247
click.echo(f"FastAPI template project will deploy at '{user_local}'")
193248

194249
click.echo(f"Project Name: {project_name}")
195250

196-
# TODO : add confirm step : checking template stack & name & metadata, confirm it y/n
197-
# click.echo("Project Stack: [FastAPI, Uvicorn, SQLAlchemy, Docker (optional)]")
251+
confirm = click.confirm(
252+
"\nDo you want to proceed with project creation?", default=False
253+
)
254+
if not confirm:
255+
click.echo("Project creation aborted!")
256+
return
198257

199258
copy_and_convert_template(target_template, user_local)
200259

tests/test_cli_operations/test_cli.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,20 @@ def test_startproject(self, temp_dir) -> None:
5252
result = self.runner.invoke(
5353
fastkit_cli, # type: ignore
5454
["startproject", "fastapi-default"],
55-
input='\n'.join(["test-project", "bnbong", "bbbong9@gmail.com", "test project"]),
55+
input="\n".join(
56+
["test-project", "bnbong", "bbbong9@gmail.com", "test project"]
57+
),
5658
)
5759

5860
# then
59-
project_path = Path(temp_dir) / "fastapi-default" # TODO : change this after adding folder naming feature.
61+
project_path = (
62+
Path(temp_dir) / "fastapi-default"
63+
) # TODO : change this after adding folder naming feature.
6064
assert project_path.exists() and project_path.is_dir()
61-
assert f"FastAPI project 'test-project' from 'fastapi-default' has been created and saved to {temp_dir}!" in result.output
65+
assert (
66+
f"FastAPI project 'test-project' from 'fastapi-default' has been created and saved to {temp_dir}!"
67+
in result.output
68+
)
6269

6370
expected_files = ["main.py", "setup.py"]
6471
for file in expected_files:

0 commit comments

Comments
 (0)