amsdal_cli 0.0.1__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.
Files changed (65) hide show
  1. amsdal_cli/Third-Party Materials - AMSDAL Dependencies - License Notices.md +1099 -0
  2. amsdal_cli/__about__.py +4 -0
  3. amsdal_cli/__init__.py +0 -0
  4. amsdal_cli/app.py +8 -0
  5. amsdal_cli/commands/__init__.py +0 -0
  6. amsdal_cli/commands/build/__init__.py +0 -0
  7. amsdal_cli/commands/build/command.py +27 -0
  8. amsdal_cli/commands/build/constants.py +1 -0
  9. amsdal_cli/commands/build/utils/__init__.py +0 -0
  10. amsdal_cli/commands/build/utils/build_app.py +46 -0
  11. amsdal_cli/commands/build/utils/build_config_file.py +36 -0
  12. amsdal_cli/commands/callbacks.py +47 -0
  13. amsdal_cli/commands/generate/__init__.py +0 -0
  14. amsdal_cli/commands/generate/app.py +5 -0
  15. amsdal_cli/commands/generate/command.py +5 -0
  16. amsdal_cli/commands/generate/enums.py +52 -0
  17. amsdal_cli/commands/generate/sub_commands/__init__.py +13 -0
  18. amsdal_cli/commands/generate/sub_commands/generate_hook.py +35 -0
  19. amsdal_cli/commands/generate/sub_commands/generate_model.py +94 -0
  20. amsdal_cli/commands/generate/sub_commands/generate_modifier.py +32 -0
  21. amsdal_cli/commands/generate/sub_commands/generate_property.py +38 -0
  22. amsdal_cli/commands/generate/sub_commands/generate_transaction.py +38 -0
  23. amsdal_cli/commands/generate/templates/hook.pyt +3 -0
  24. amsdal_cli/commands/generate/templates/modifier/constructor.pyt +10 -0
  25. amsdal_cli/commands/generate/templates/modifier/display_name.pyt +4 -0
  26. amsdal_cli/commands/generate/templates/modifier/version_name.pyt +4 -0
  27. amsdal_cli/commands/generate/templates/property.pyt +4 -0
  28. amsdal_cli/commands/generate/templates/transaction.pyt +7 -0
  29. amsdal_cli/commands/generate/utils/__init__.py +0 -0
  30. amsdal_cli/commands/generate/utils/build_base_path.py +22 -0
  31. amsdal_cli/commands/generate/utils/cast_to_attribute_type.py +19 -0
  32. amsdal_cli/commands/generate/utils/model_attributes.py +131 -0
  33. amsdal_cli/commands/new/__init__.py +0 -0
  34. amsdal_cli/commands/new/command.py +54 -0
  35. amsdal_cli/commands/new/templates/.amsdal-cli +6 -0
  36. amsdal_cli/commands/new/templates/.gitignore +4 -0
  37. amsdal_cli/commands/new/templates/README.md +646 -0
  38. amsdal_cli/commands/new/templates/config.yml +19 -0
  39. amsdal_cli/commands/serve/__init__.py +0 -0
  40. amsdal_cli/commands/serve/command.py +38 -0
  41. amsdal_cli/commands/serve/filters/__init__.py +0 -0
  42. amsdal_cli/commands/serve/filters/models_watch_filter.py +6 -0
  43. amsdal_cli/commands/serve/filters/static_files_watch_filter.py +21 -0
  44. amsdal_cli/commands/serve/services/__init__.py +0 -0
  45. amsdal_cli/commands/serve/services/supervisor.py +373 -0
  46. amsdal_cli/commands/serve/utils.py +16 -0
  47. amsdal_cli/commands/verify/__init__.py +0 -0
  48. amsdal_cli/commands/verify/command.py +74 -0
  49. amsdal_cli/commands/verify/models.py +10 -0
  50. amsdal_cli/commands/verify/utils/__init__.py +0 -0
  51. amsdal_cli/commands/verify/utils/verify_json_model.py +31 -0
  52. amsdal_cli/commands/verify/utils/verify_python_file.py +21 -0
  53. amsdal_cli/config/__init__.py +0 -0
  54. amsdal_cli/config/main.py +38 -0
  55. amsdal_cli/main.py +7 -0
  56. amsdal_cli/py.typed +0 -0
  57. amsdal_cli/utils/__init__.py +0 -0
  58. amsdal_cli/utils/cli_config.py +27 -0
  59. amsdal_cli/utils/copier.py +103 -0
  60. amsdal_cli/utils/render_template.py +12 -0
  61. amsdal_cli-0.0.1.dist-info/METADATA +353 -0
  62. amsdal_cli-0.0.1.dist-info/RECORD +65 -0
  63. amsdal_cli-0.0.1.dist-info/WHEEL +4 -0
  64. amsdal_cli-0.0.1.dist-info/entry_points.txt +2 -0
  65. amsdal_cli-0.0.1.dist-info/licenses/LICENSE.txt +107 -0
@@ -0,0 +1,4 @@
1
+ # SPDX-FileCopyrightText: 2023-present
2
+ #
3
+ # SPDX-License-Identifier: AMSDAL End User License Agreement
4
+ __version__ = '0.0.1'
amsdal_cli/__init__.py ADDED
File without changes
amsdal_cli/app.py ADDED
@@ -0,0 +1,8 @@
1
+ import typer
2
+
3
+ from amsdal_cli.commands.callbacks import init_app_context
4
+
5
+ app = typer.Typer(
6
+ callback=init_app_context,
7
+ invoke_without_command=True,
8
+ )
File without changes
File without changes
@@ -0,0 +1,27 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+
5
+ from amsdal_cli.app import app
6
+ from amsdal_cli.commands.build.utils.build_app import build_app
7
+ from amsdal_cli.commands.generate.enums import SOURCES_DIR
8
+ from amsdal_cli.utils.cli_config import CliConfig
9
+
10
+
11
+ @app.command(name='build')
12
+ def build_command(
13
+ ctx: typer.Context,
14
+ output: Path = typer.Argument('.', help='Path to output directory'), # noqa: B008
15
+ config: Path = typer.Option(None, help='Path to custom config.yml file'), # noqa: B008
16
+ ) -> None:
17
+ """
18
+ Build the app and generate the models and other files.
19
+ """
20
+ cli_config: CliConfig = ctx.meta['config']
21
+ app_source_path = cli_config.app_directory / SOURCES_DIR
22
+
23
+ build_app(
24
+ app_source_path=app_source_path,
25
+ config_path=config or cli_config.config_path,
26
+ output=output,
27
+ )
@@ -0,0 +1 @@
1
+ TRANSACTION_FILE_NAME = 'transactions.py'
File without changes
@@ -0,0 +1,46 @@
1
+ from pathlib import Path
2
+
3
+ from amsdal_framework.configs.main import settings
4
+ from amsdal_framework.manager import AmsdalManager
5
+ from amsdal_utils.config.manager import AmsdalConfigManager
6
+ from rich import print
7
+
8
+ from amsdal_cli.commands.build.utils.build_config_file import build_config_file
9
+
10
+
11
+ def build_app(
12
+ app_source_path: Path,
13
+ config_path: Path,
14
+ output: Path = Path('.'),
15
+ ) -> None:
16
+ settings.override(APP_PATH=output)
17
+ config_manager = AmsdalConfigManager()
18
+ config_manager.load_config(config_path)
19
+ amsdal_manager = AmsdalManager()
20
+ amsdal_manager.pre_setup()
21
+
22
+ print('[blue]Building models...[/blue]', end=' ')
23
+ amsdal_manager.build_models(app_source_path / 'models')
24
+ print('[green]OK![/green]')
25
+
26
+ if output == Path('.'):
27
+ print('[yellow]No output directory specified, skipping config.yml generation[/yellow]')
28
+ else:
29
+ # build config file
30
+ build_config_file(
31
+ output_path=output,
32
+ config_path=config_path,
33
+ no_input=True,
34
+ )
35
+
36
+ print('[blue]Building transactions...[/blue]', end=' ')
37
+ amsdal_manager.build_transactions(app_source_path)
38
+ print('[green]OK![/green]')
39
+
40
+ print('[blue]Building static files...[/blue]', end=' ')
41
+ amsdal_manager.build_static_files(app_source_path)
42
+ print('[green]OK![/green]')
43
+
44
+ print('[blue]Building fixtures...[/blue]', end=' ')
45
+ amsdal_manager.build_fixtures(app_source_path / 'models')
46
+ print('[green]OK![/green]')
@@ -0,0 +1,36 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+ from rich import print
5
+
6
+
7
+ def build_config_file(
8
+ output_path: Path,
9
+ config_path: Path,
10
+ *,
11
+ no_input: bool,
12
+ ) -> None:
13
+ print('[blue]Building config.yml file...[/blue]', end=' ')
14
+
15
+ if not config_path.exists() or not config_path.name.endswith('.yml'):
16
+ print(f'\n[red]Config file "{config_path.resolve()}" does not exist or has wrong extension.[/red]')
17
+ raise typer.Exit(1)
18
+
19
+ config_destination = output_path / 'config.yml'
20
+
21
+ if (
22
+ no_input
23
+ or not config_destination.exists()
24
+ or (
25
+ typer.confirm(
26
+ f'\nThe config file "{config_destination.resolve()}" already exists. Would you like to overwrite it?',
27
+ )
28
+ )
29
+ ):
30
+ config_destination.parent.mkdir(parents=True, exist_ok=True)
31
+ config_destination.touch(exist_ok=True)
32
+
33
+ with config_path.open('rt') as _file:
34
+ config_destination.write_text(_file.read())
35
+
36
+ print('[green]OK![/green]')
@@ -0,0 +1,47 @@
1
+ import json
2
+ import os
3
+ from json import JSONDecodeError
4
+ from pathlib import Path
5
+
6
+ import typer
7
+ from rich import print
8
+
9
+ from amsdal_cli.utils.cli_config import CliConfig
10
+
11
+ COMMANDS_DO_NOT_REQUIRE_APP_PATH = ('new', 'migrate', 'write_logs')
12
+
13
+
14
+ def init_app_context(ctx: typer.Context) -> None:
15
+ """
16
+ AMSDAL CLI - a tool that provides the ability to create a new app,
17
+ generate models, transactions, build, serve, and other useful features
18
+ for the efficient building of new apps using AMSDAL Framework.
19
+ """
20
+ if not ctx.invoked_subcommand:
21
+ return
22
+
23
+ templates_path = Path(__file__).parent / ctx.invoked_subcommand / 'templates'
24
+
25
+ if ctx.invoked_subcommand in COMMANDS_DO_NOT_REQUIRE_APP_PATH:
26
+ ctx.meta['config'] = CliConfig(templates_path=templates_path)
27
+
28
+ return
29
+
30
+ app_path = Path(os.getcwd())
31
+ cli_config = app_path / '.amsdal-cli'
32
+
33
+ if not cli_config.exists():
34
+ print(f'[red]The directory "{app_path.resolve()}" does not contain AMSDAL application.[/red]')
35
+ print('Use the "amsdal new --help" command to see details about how to create an application.')
36
+ raise typer.Exit(1)
37
+
38
+ with cli_config.open('rt') as config_file:
39
+ try:
40
+ ctx.meta['config'] = CliConfig(
41
+ app_directory=app_path,
42
+ templates_path=templates_path,
43
+ **json.loads(config_file.read()),
44
+ )
45
+ except JSONDecodeError as err:
46
+ print(f'[red]The config file "{cli_config.resolve()}" is corrupted.[/red]')
47
+ raise typer.Exit(1) from err
File without changes
@@ -0,0 +1,5 @@
1
+ import typer
2
+
3
+ sub_app = typer.Typer(
4
+ help="Generates application's files such as models, properties, transactions, etc.",
5
+ )
@@ -0,0 +1,5 @@
1
+ from amsdal_cli.app import app
2
+ from amsdal_cli.commands.generate.app import sub_app
3
+ from amsdal_cli.commands.generate.sub_commands import * # noqa
4
+
5
+ app.add_typer(sub_app, name='generate')
@@ -0,0 +1,52 @@
1
+ from enum import Enum
2
+
3
+ SOURCES_DIR = 'src'
4
+ MODEL_JSON_FILE = 'model.json'
5
+ MODEL_PY_FILE = 'model.py'
6
+ FIXTURES_JSON_FILE = 'fixtures.json'
7
+
8
+
9
+ class HookName(str, Enum):
10
+ PRE_INIT = 'pre_init'
11
+ POST_INIT = 'post_init'
12
+ PRE_CREATE = 'pre_create'
13
+ POST_CREATE = 'post_create'
14
+ PRE_UPDATE = 'pre_update'
15
+ POST_UPDATE = 'post_update'
16
+ PRE_DELETE = 'pre_delete'
17
+ POST_DELETE = 'post_delete'
18
+
19
+
20
+ class ModifierName(str, Enum):
21
+ CONSTRUCTOR = 'constructor'
22
+ DISPLAY_NAME = 'display_name'
23
+ VERSION_NAME = 'version_name'
24
+
25
+
26
+ class ModelFormat(str, Enum):
27
+ JSON = 'json'
28
+ PY = 'py'
29
+
30
+
31
+ class AttributeType(str, Enum):
32
+ STRING = 'string'
33
+ NUMBER = 'number'
34
+ BOOLEAN = 'boolean'
35
+ BELONGS_TO = 'belongs-to'
36
+ HAS_MANY = 'has-many'
37
+ DICT = 'dict'
38
+
39
+
40
+ class JsonType(str, Enum):
41
+ STRING = 'string'
42
+ NUMBER = 'number'
43
+ BOOLEAN = 'boolean'
44
+ ARRAY = 'array'
45
+ DICT = 'dictionary'
46
+
47
+
48
+ class OptionName(str, Enum):
49
+ INDEX = 'index'
50
+ DEFAULT = 'default'
51
+ REQUIRED = 'required'
52
+ UNIQUE = 'unique'
@@ -0,0 +1,13 @@
1
+ from amsdal_cli.commands.generate.sub_commands.generate_hook import generate_hook
2
+ from amsdal_cli.commands.generate.sub_commands.generate_model import generate_model
3
+ from amsdal_cli.commands.generate.sub_commands.generate_modifier import generate_modifier
4
+ from amsdal_cli.commands.generate.sub_commands.generate_property import generate_property
5
+ from amsdal_cli.commands.generate.sub_commands.generate_transaction import generate_transaction
6
+
7
+ __all__ = [
8
+ 'generate_model',
9
+ 'generate_property',
10
+ 'generate_hook',
11
+ 'generate_modifier',
12
+ 'generate_transaction',
13
+ ]
@@ -0,0 +1,35 @@
1
+ import typer
2
+
3
+ from amsdal_cli.commands.generate.app import sub_app
4
+ from amsdal_cli.commands.generate.enums import HookName
5
+ from amsdal_cli.commands.generate.utils.build_base_path import build_model_base_path
6
+ from amsdal_cli.utils.cli_config import CliConfig
7
+ from amsdal_cli.utils.copier import copy_blueprint
8
+
9
+
10
+ @sub_app.command(name='hook')
11
+ def generate_hook(
12
+ ctx: typer.Context,
13
+ hook_name: HookName = typer.Argument( # noqa: B008
14
+ ...,
15
+ help='The hook name.',
16
+ ),
17
+ model: str = typer.Option(..., help='The model name. It should be provided in PascalCase.'),
18
+ ) -> None:
19
+ """
20
+ Generates hook file for specified model.
21
+ """
22
+ cli_config: CliConfig = ctx.meta['config']
23
+ base_path = build_model_base_path(ctx, model)
24
+ output_path = base_path / 'hooks'
25
+
26
+ copy_blueprint(
27
+ source_file_path=cli_config.templates_path / 'hook.pyt',
28
+ destination_path=output_path,
29
+ destination_name=f'{hook_name.value}.py',
30
+ context={
31
+ 'hook_name': hook_name.value,
32
+ 'is_init': hook_name in (HookName.PRE_INIT, HookName.POST_INIT),
33
+ },
34
+ confirm_overwriting=True,
35
+ )
@@ -0,0 +1,94 @@
1
+ import json
2
+ from typing import Any
3
+
4
+ import typer
5
+ from amsdal_utils.utils.text import classify
6
+ from amsdal_utils.utils.text import to_snake_case
7
+ from rich import print
8
+
9
+ from amsdal_cli.commands.generate.app import sub_app
10
+ from amsdal_cli.commands.generate.enums import MODEL_JSON_FILE
11
+ from amsdal_cli.commands.generate.enums import SOURCES_DIR
12
+ from amsdal_cli.commands.generate.enums import ModelFormat
13
+ from amsdal_cli.commands.generate.utils.model_attributes import parse_attributes
14
+ from amsdal_cli.utils.cli_config import CliConfig
15
+ from amsdal_cli.utils.copier import write_file
16
+
17
+
18
+ @sub_app.command(name='model')
19
+ def generate_model(
20
+ ctx: typer.Context,
21
+ model_name: str = typer.Argument(
22
+ ...,
23
+ help='The model name. It should be provided in PascalCase.',
24
+ ),
25
+ model_format: ModelFormat = typer.Option(ModelFormat.JSON.value, '--format'), # noqa: B008
26
+ attrs: list[str] = typer.Option( # noqa: B008
27
+ (None,),
28
+ '--attributes',
29
+ '-attrs',
30
+ ),
31
+ unique: list[str] = typer.Option( # noqa: B008
32
+ (None,),
33
+ '--unique',
34
+ '-u',
35
+ ),
36
+ ) -> None:
37
+ """
38
+ Generates model file.
39
+
40
+ Example of usage:
41
+
42
+ >>> bin/cli --app-path ./apps/my_app/ generate model UserProfile --format json -attrs "name:string \
43
+ email:string:index age:number:default=18"
44
+ """
45
+
46
+ if model_format == ModelFormat.PY:
47
+ print('[red]The PY format is not supported for now.[/red]')
48
+ raise typer.Exit
49
+
50
+ cli_config: CliConfig = ctx.meta['config']
51
+ model_name = classify(model_name)
52
+ name = to_snake_case(model_name)
53
+
54
+ output_path = cli_config.app_directory / SOURCES_DIR / 'models' / name
55
+ parsed_attrs = parse_attributes(attrs)
56
+
57
+ schema: dict[str, Any] = {
58
+ 'title': model_name,
59
+ 'type': 'object',
60
+ 'properties': {},
61
+ 'required': [attr.name for attr in parsed_attrs if attr.required],
62
+ 'indexed': [attr.name for attr in parsed_attrs if attr.index],
63
+ }
64
+
65
+ unique_attrs: list[str | tuple[str, ...]] = [attr.name for attr in parsed_attrs if attr.unique]
66
+
67
+ for _unique in filter(None, unique):
68
+ _unique_attrs = tuple(map(str.strip, _unique.split(',')))
69
+
70
+ if _unique_attrs not in unique_attrs:
71
+ unique_attrs.append(_unique_attrs)
72
+
73
+ if unique_attrs:
74
+ schema['unique_properties'] = unique_attrs
75
+
76
+ for attr in parsed_attrs:
77
+ property_info: dict[str, Any] = {
78
+ 'title': attr.name,
79
+ 'type': attr.json_type,
80
+ }
81
+
82
+ if attr.has_items:
83
+ property_info['items'] = attr.json_items
84
+
85
+ if attr.default != attr.NotSet:
86
+ property_info['default'] = attr.default
87
+
88
+ schema['properties'][attr.name] = property_info
89
+
90
+ write_file(
91
+ json.dumps(schema, indent=cli_config.json_indent),
92
+ destination_file_path=output_path / MODEL_JSON_FILE,
93
+ confirm_overwriting=True,
94
+ )
@@ -0,0 +1,32 @@
1
+ import typer
2
+
3
+ from amsdal_cli.commands.generate.app import sub_app
4
+ from amsdal_cli.commands.generate.enums import ModifierName
5
+ from amsdal_cli.commands.generate.utils.build_base_path import build_model_base_path
6
+ from amsdal_cli.utils.cli_config import CliConfig
7
+ from amsdal_cli.utils.copier import copy_blueprint
8
+
9
+
10
+ @sub_app.command(name='modifier')
11
+ def generate_modifier(
12
+ ctx: typer.Context,
13
+ modifier_name: ModifierName = typer.Argument( # noqa: B008
14
+ ...,
15
+ help='The modifier name.',
16
+ ),
17
+ model: str = typer.Option(..., help='The model name. It should be provided in PascalCase.'),
18
+ ) -> None:
19
+ """
20
+ Generates modifier file for specified model.
21
+ """
22
+ cli_config: CliConfig = ctx.meta['config']
23
+ base_path = build_model_base_path(ctx, model)
24
+ modifier_path = base_path / 'modifiers'
25
+
26
+ copy_blueprint(
27
+ source_file_path=cli_config.templates_path / 'modifier' / f'{modifier_name.value}.pyt',
28
+ destination_path=modifier_path,
29
+ destination_name=f'{modifier_name.value}.py',
30
+ context={},
31
+ confirm_overwriting=True,
32
+ )
@@ -0,0 +1,38 @@
1
+ import typer
2
+ from amsdal_utils.utils.text import to_snake_case
3
+
4
+ from amsdal_cli.commands.generate.app import sub_app
5
+ from amsdal_cli.commands.generate.utils.build_base_path import build_model_base_path
6
+ from amsdal_cli.utils.cli_config import CliConfig
7
+ from amsdal_cli.utils.copier import copy_blueprint
8
+
9
+
10
+ @sub_app.command(name='property')
11
+ def generate_property(
12
+ ctx: typer.Context,
13
+ property_name: str = typer.Argument(
14
+ ...,
15
+ help=(
16
+ 'The property name. Note, it will always transform the provided name to camel_case. Enter the name in '
17
+ 'camel_case in order to avoid any issues.'
18
+ ),
19
+ ),
20
+ model: str = typer.Option(..., help='The model name. It should be provided in PascalCase.'),
21
+ ) -> None:
22
+ """
23
+ Generates property file for specified model.
24
+ """
25
+ cli_config: CliConfig = ctx.meta['config']
26
+ base_path = build_model_base_path(ctx, model)
27
+ name = to_snake_case(property_name)
28
+ output_path = base_path / 'properties'
29
+
30
+ copy_blueprint(
31
+ source_file_path=cli_config.templates_path / 'property.pyt',
32
+ destination_path=output_path,
33
+ destination_name=f'{name}.py',
34
+ context={
35
+ 'property_name': name,
36
+ },
37
+ confirm_overwriting=True,
38
+ )
@@ -0,0 +1,38 @@
1
+ import typer
2
+ from amsdal_utils.utils.text import classify
3
+ from amsdal_utils.utils.text import to_snake_case
4
+
5
+ from amsdal_cli.commands.generate.app import sub_app
6
+ from amsdal_cli.commands.generate.enums import SOURCES_DIR
7
+ from amsdal_cli.utils.cli_config import CliConfig
8
+ from amsdal_cli.utils.copier import copy_blueprint
9
+
10
+
11
+ @sub_app.command(name='transaction')
12
+ def generate_transaction(
13
+ ctx: typer.Context,
14
+ transaction_name: str = typer.Argument(
15
+ ...,
16
+ help=(
17
+ 'The transaction name. Note, it will always transform the provided name to camel_case. Enter the name in '
18
+ 'camel_case in order to avoid any issues.'
19
+ ),
20
+ ),
21
+ ) -> None:
22
+ """
23
+ Generates transaction file for specified model.
24
+ """
25
+ cli_config: CliConfig = ctx.meta['config']
26
+ name = to_snake_case(transaction_name)
27
+ output_path = cli_config.app_directory / SOURCES_DIR / 'transactions'
28
+
29
+ copy_blueprint(
30
+ source_file_path=cli_config.templates_path / 'transaction.pyt',
31
+ destination_path=output_path,
32
+ destination_name=f'{name}.py',
33
+ context={
34
+ 'transaction_method_name': name,
35
+ 'transaction_class_name': classify(transaction_name),
36
+ },
37
+ confirm_overwriting=True,
38
+ )
@@ -0,0 +1,3 @@
1
+ def {{ ctx.hook_name }}(self{% if ctx.is_init %}, is_new_object, **kwargs{% endif %}):
2
+ # TODO: implementation here
3
+ ...
@@ -0,0 +1,10 @@
1
+ def __init__(self, **kwargs):
2
+ # Add implementation here
3
+ # Note, **kwargs contain raw data, which is not validated yet.
4
+
5
+ super().__init__(**kwargs)
6
+
7
+ # Or add implementation here
8
+ # Note, **kwargs were validated, converted to the correct types and
9
+ # assigned to the corresponding fields.
10
+ # So you safely can use them here via self.
@@ -0,0 +1,4 @@
1
+ @property
2
+ def display_name(self) -> str:
3
+ # TODO: implementation here
4
+ ...
@@ -0,0 +1,4 @@
1
+ @property
2
+ def version_name(self) -> str:
3
+ # TODO: implementation here
4
+ ...
@@ -0,0 +1,4 @@
1
+ @property
2
+ def {{ ctx.property_name }}(self):
3
+ # TODO: implementation here
4
+ ...
@@ -0,0 +1,7 @@
1
+ from amsdal_data.transactions import transaction
2
+
3
+
4
+ @transaction(name="{{ ctx.transaction_class_name }}")
5
+ def {{ ctx.transaction_method_name }}():
6
+ # TODO: implementation here
7
+ ...
File without changes
@@ -0,0 +1,22 @@
1
+ from pathlib import Path
2
+
3
+ import typer
4
+ from amsdal_utils.utils.text import to_snake_case
5
+ from rich import print
6
+
7
+ from amsdal_cli.commands.generate.enums import SOURCES_DIR
8
+ from amsdal_cli.utils.cli_config import CliConfig
9
+
10
+
11
+ def build_model_base_path(ctx: typer.Context, model_name: str) -> Path:
12
+ cli_config: CliConfig = ctx.meta['config']
13
+ model = to_snake_case(model_name)
14
+ model_path = cli_config.app_directory / SOURCES_DIR / 'models' / model
15
+
16
+ if cli_config.check_model_exists and not (
17
+ (model_path / 'model.json').exists() or (model_path / 'model.py').exists()
18
+ ):
19
+ print(f'[red]The model "{model_name}" does not exist.[/red]')
20
+ raise typer.Exit
21
+
22
+ return model_path
@@ -0,0 +1,19 @@
1
+ from typing import Any
2
+
3
+ from amsdal_cli.commands.generate.enums import AttributeType
4
+
5
+
6
+ def cast_to_attribute_type(
7
+ attr_type: AttributeType,
8
+ value: str,
9
+ ) -> Any:
10
+ if value.lower() == 'null':
11
+ return None
12
+
13
+ match attr_type:
14
+ case AttributeType.NUMBER:
15
+ return float(value)
16
+ case AttributeType.BOOLEAN:
17
+ return value.lower() == 'true'
18
+ case _:
19
+ return value