instant-python 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.
- instant_python/__init__.py +0 -0
- instant_python/cli.py +11 -0
- instant_python/folder_cli.py +50 -0
- instant_python/installer/__init__.py +0 -0
- instant_python/installer/dependency_manager.py +15 -0
- instant_python/installer/dependency_manager_factory.py +14 -0
- instant_python/installer/git_configurer.py +47 -0
- instant_python/installer/installer.py +18 -0
- instant_python/installer/managers.py +7 -0
- instant_python/installer/operating_systems.py +7 -0
- instant_python/installer/pdm_manager.py +72 -0
- instant_python/installer/uv_manager.py +73 -0
- instant_python/project_cli.py +100 -0
- instant_python/project_generator/__init__.py +0 -0
- instant_python/project_generator/custom_template_manager.py +20 -0
- instant_python/project_generator/default_template_manager.py +45 -0
- instant_python/project_generator/directory.py +28 -0
- instant_python/project_generator/file.py +20 -0
- instant_python/project_generator/folder_tree.py +40 -0
- instant_python/project_generator/jinja_custom_filters.py +18 -0
- instant_python/project_generator/node.py +14 -0
- instant_python/project_generator/project_generator.py +31 -0
- instant_python/project_generator/template_manager.py +7 -0
- instant_python/question_prompter/__init__.py +0 -0
- instant_python/question_prompter/question/__init__.py +0 -0
- instant_python/question_prompter/question/boolean_question.py +13 -0
- instant_python/question_prompter/question/choice_question.py +18 -0
- instant_python/question_prompter/question/conditional_question.py +25 -0
- instant_python/question_prompter/question/dependencies_question.py +43 -0
- instant_python/question_prompter/question/free_text_question.py +13 -0
- instant_python/question_prompter/question/multiple_choice_question.py +13 -0
- instant_python/question_prompter/question/question.py +15 -0
- instant_python/question_prompter/question_wizard.py +15 -0
- instant_python/question_prompter/step/__init__.py +0 -0
- instant_python/question_prompter/step/dependencies_step.py +20 -0
- instant_python/question_prompter/step/general_custom_template_project_step.py +45 -0
- instant_python/question_prompter/step/general_project_step.py +50 -0
- instant_python/question_prompter/step/git_step.py +23 -0
- instant_python/question_prompter/step/steps.py +16 -0
- instant_python/question_prompter/step/template_step.py +63 -0
- instant_python/question_prompter/template_types.py +7 -0
- instant_python/question_prompter/user_requirements.py +39 -0
- instant_python/templates/__init__.py +0 -0
- instant_python/templates/boilerplate/.gitignore +164 -0
- instant_python/templates/boilerplate/.pre-commit-config.yml +33 -0
- instant_python/templates/boilerplate/.python-version +1 -0
- instant_python/templates/boilerplate/LICENSE +896 -0
- instant_python/templates/boilerplate/event_bus/__init__.py +0 -0
- instant_python/templates/boilerplate/event_bus/aggregate_root.py +19 -0
- instant_python/templates/boilerplate/event_bus/domain_event.py +15 -0
- instant_python/templates/boilerplate/event_bus/domain_event_json_deserializer.py +28 -0
- instant_python/templates/boilerplate/event_bus/domain_event_json_serializer.py +17 -0
- instant_python/templates/boilerplate/event_bus/domain_event_subscriber.py +15 -0
- instant_python/templates/boilerplate/event_bus/event_bus.py +10 -0
- instant_python/templates/boilerplate/event_bus/exchange_type.py +7 -0
- instant_python/templates/boilerplate/event_bus/mock_event_bus.py +18 -0
- instant_python/templates/boilerplate/event_bus/rabbit_mq_configurer.py +54 -0
- instant_python/templates/boilerplate/event_bus/rabbit_mq_connection.py +77 -0
- instant_python/templates/boilerplate/event_bus/rabbit_mq_consumer.py +58 -0
- instant_python/templates/boilerplate/event_bus/rabbit_mq_event_bus.py +28 -0
- instant_python/templates/boilerplate/event_bus/rabbit_mq_queue_formatter.py +22 -0
- instant_python/templates/boilerplate/event_bus/rabbit_mq_settings.py +8 -0
- instant_python/templates/boilerplate/exceptions/__init__.py +0 -0
- instant_python/templates/boilerplate/exceptions/domain_error.py +17 -0
- instant_python/templates/boilerplate/exceptions/domain_event_type_not_found_error.py +17 -0
- instant_python/templates/boilerplate/exceptions/incorrect_value_type_error.py +21 -0
- instant_python/templates/boilerplate/exceptions/invalid_id_format_error.py +17 -0
- instant_python/templates/boilerplate/exceptions/invalid_negative_value_error.py +17 -0
- instant_python/templates/boilerplate/exceptions/required_value_error.py +17 -0
- instant_python/templates/boilerplate/fastapi/__init__.py +0 -0
- instant_python/templates/boilerplate/fastapi/application.py +25 -0
- instant_python/templates/boilerplate/fastapi/http_response.py +45 -0
- instant_python/templates/boilerplate/fastapi/lifespan.py +14 -0
- instant_python/templates/boilerplate/fastapi/status_code.py +9 -0
- instant_python/templates/boilerplate/github/action.yml +22 -0
- instant_python/templates/boilerplate/github/test_lint.yml +36 -0
- instant_python/templates/boilerplate/logger/__init__.py +0 -0
- instant_python/templates/boilerplate/logger/json_formatter.py +16 -0
- instant_python/templates/boilerplate/logger/logger.py +39 -0
- instant_python/templates/boilerplate/mypy.ini +41 -0
- instant_python/templates/boilerplate/persistence/__init__.py +0 -0
- instant_python/templates/boilerplate/persistence/alembic_migrator.py +20 -0
- instant_python/templates/boilerplate/persistence/async/README.md +1 -0
- instant_python/templates/boilerplate/persistence/async/__init__.py +0 -0
- instant_python/templates/boilerplate/persistence/async/alembic.ini +124 -0
- instant_python/templates/boilerplate/persistence/async/async_engine_fixture.py +21 -0
- instant_python/templates/boilerplate/persistence/async/env.py +95 -0
- instant_python/templates/boilerplate/persistence/async/models_metadata.py +11 -0
- instant_python/templates/boilerplate/persistence/async/postgres_settings.py +15 -0
- instant_python/templates/boilerplate/persistence/async/script.py.mako +26 -0
- instant_python/templates/boilerplate/persistence/async/sqlalchemy_repository.py +30 -0
- instant_python/templates/boilerplate/persistence/base.py +4 -0
- instant_python/templates/boilerplate/persistence/synchronous/__init__.py +0 -0
- instant_python/templates/boilerplate/persistence/synchronous/session_maker.py +22 -0
- instant_python/templates/boilerplate/persistence/synchronous/sqlalchemy_repository.py +35 -0
- instant_python/templates/boilerplate/pyproject.toml +29 -0
- instant_python/templates/boilerplate/pytest.ini +10 -0
- instant_python/templates/boilerplate/random_generator.py +9 -0
- instant_python/templates/boilerplate/scripts/add_dependency.sh +37 -0
- instant_python/templates/boilerplate/scripts/create_aggregate.py +33 -0
- instant_python/templates/boilerplate/scripts/insert_template.py +90 -0
- instant_python/templates/boilerplate/scripts/integration.sh +39 -0
- instant_python/templates/boilerplate/scripts/local_setup.sh +15 -0
- instant_python/templates/boilerplate/scripts/makefile +137 -0
- instant_python/templates/boilerplate/scripts/post-merge +11 -0
- instant_python/templates/boilerplate/scripts/pre-commit +4 -0
- instant_python/templates/boilerplate/scripts/pre-push +6 -0
- instant_python/templates/boilerplate/scripts/remove_dependency.sh +36 -0
- instant_python/templates/boilerplate/scripts/unit.sh +40 -0
- instant_python/templates/boilerplate/value_object/__init__.py +0 -0
- instant_python/templates/boilerplate/value_object/int_value_object.py +11 -0
- instant_python/templates/boilerplate/value_object/string_value_object.py +19 -0
- instant_python/templates/boilerplate/value_object/uuid.py +17 -0
- instant_python/templates/boilerplate/value_object/value_object.py +21 -0
- instant_python/templates/project_structure/alembic_migrator.yml.j2 +3 -0
- instant_python/templates/project_structure/async_alembic.yml.j2 +20 -0
- instant_python/templates/project_structure/async_sqlalchemy.yml.j2 +17 -0
- instant_python/templates/project_structure/clean_architecture/main_structure.yml.j2 +25 -0
- instant_python/templates/project_structure/clean_architecture/source.yml.j2 +51 -0
- instant_python/templates/project_structure/clean_architecture/test.yml.j2 +23 -0
- instant_python/templates/project_structure/domain_driven_design/bounded_context.yml.j2 +20 -0
- instant_python/templates/project_structure/domain_driven_design/main_structure.yml.j2 +25 -0
- instant_python/templates/project_structure/domain_driven_design/source.yml.j2 +55 -0
- instant_python/templates/project_structure/domain_driven_design/test.yml.j2 +26 -0
- instant_python/templates/project_structure/event_bus_domain.yml.j2 +26 -0
- instant_python/templates/project_structure/event_bus_infra.yml.j2 +32 -0
- instant_python/templates/project_structure/fastapi_app.yml.j2 +10 -0
- instant_python/templates/project_structure/fastapi_infra.yml.j2 +10 -0
- instant_python/templates/project_structure/github_action.yml.j2 +18 -0
- instant_python/templates/project_structure/gitignore.yml.j2 +2 -0
- instant_python/templates/project_structure/license.yml.j2 +2 -0
- instant_python/templates/project_structure/logger.yml.j2 +10 -0
- instant_python/templates/project_structure/macros.j2 +6 -0
- instant_python/templates/project_structure/makefile.yml.j2 +38 -0
- instant_python/templates/project_structure/mypy.yml.j2 +3 -0
- instant_python/templates/project_structure/pre_commit.yml.j2 +3 -0
- instant_python/templates/project_structure/pyproject.yml.j2 +3 -0
- instant_python/templates/project_structure/pytest.yml.j2 +3 -0
- instant_python/templates/project_structure/python_version.yml.j2 +2 -0
- instant_python/templates/project_structure/standard_project/main_structure.yml.j2 +25 -0
- instant_python/templates/project_structure/standard_project/source.yml.j2 +30 -0
- instant_python/templates/project_structure/standard_project/test.yml.j2 +16 -0
- instant_python/templates/project_structure/synchronous_sqlalchemy.yml.j2 +17 -0
- instant_python/templates/project_structure/value_objects.yml.j2 +35 -0
- instant_python-0.0.1.dist-info/METADATA +276 -0
- instant_python-0.0.1.dist-info/RECORD +149 -0
- instant_python-0.0.1.dist-info/WHEEL +4 -0
- instant_python-0.0.1.dist-info/entry_points.txt +2 -0
- instant_python-0.0.1.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import questionary
|
|
2
|
+
|
|
3
|
+
from instant_python.question_prompter.question.question import Question
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BooleanQuestion(Question[bool]):
|
|
7
|
+
def __init__(self, key: str, message: str, default: bool) -> None:
|
|
8
|
+
super().__init__(key, message)
|
|
9
|
+
self._default = default
|
|
10
|
+
|
|
11
|
+
def ask(self) -> dict[str, bool]:
|
|
12
|
+
answer = questionary.confirm(self._message, default=self._default).ask()
|
|
13
|
+
return {self._key: answer}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import questionary
|
|
2
|
+
|
|
3
|
+
from instant_python.question_prompter.question.question import Question
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ChoiceQuestion(Question[str]):
|
|
7
|
+
def __init__(self, key: str, message: str, options: list[str] | None = None) -> None:
|
|
8
|
+
super().__init__(key, message)
|
|
9
|
+
self._default = options[0] if options else ""
|
|
10
|
+
self._options = options if options else []
|
|
11
|
+
|
|
12
|
+
def ask(self) -> dict[str, str]:
|
|
13
|
+
answer = questionary.select(
|
|
14
|
+
self._message,
|
|
15
|
+
choices=self._options,
|
|
16
|
+
default=self._default,
|
|
17
|
+
).ask()
|
|
18
|
+
return {self._key: answer}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from instant_python.question_prompter.question.question import Question
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ConditionalQuestion:
|
|
5
|
+
def __init__(
|
|
6
|
+
self, base_question: Question, subquestions: list[Question], condition: str | bool
|
|
7
|
+
) -> None:
|
|
8
|
+
self._base_question = base_question
|
|
9
|
+
self._subquestions = subquestions
|
|
10
|
+
self._condition = condition
|
|
11
|
+
|
|
12
|
+
def ask(self) -> dict[str, str]:
|
|
13
|
+
base_answer = self._base_question.ask()
|
|
14
|
+
|
|
15
|
+
if self._base_answer_does_not_satisfies_condition(base_answer):
|
|
16
|
+
return base_answer
|
|
17
|
+
|
|
18
|
+
answers = base_answer
|
|
19
|
+
for question in self._subquestions:
|
|
20
|
+
answers.update(question.ask())
|
|
21
|
+
return answers
|
|
22
|
+
|
|
23
|
+
def _base_answer_does_not_satisfies_condition(self, base_answer: dict[str, str]) -> bool:
|
|
24
|
+
answer_value = next(iter(base_answer.values()))
|
|
25
|
+
return answer_value != self._condition
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from instant_python.question_prompter.question.boolean_question import BooleanQuestion
|
|
2
|
+
from instant_python.question_prompter.question.free_text_question import (
|
|
3
|
+
FreeTextQuestion,
|
|
4
|
+
)
|
|
5
|
+
from instant_python.question_prompter.question.question import Question
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DependenciesQuestion(Question[list[str]]):
|
|
9
|
+
def __init__(self, key: str, message: str) -> None:
|
|
10
|
+
super().__init__(key, message)
|
|
11
|
+
|
|
12
|
+
def ask(self) -> dict[str, list[str]]:
|
|
13
|
+
dependencies = []
|
|
14
|
+
while True:
|
|
15
|
+
user_wants_to_install_dependencies = BooleanQuestion(
|
|
16
|
+
key="keep_asking", message=self._message, default=False
|
|
17
|
+
).ask()["keep_asking"]
|
|
18
|
+
|
|
19
|
+
if not user_wants_to_install_dependencies:
|
|
20
|
+
break
|
|
21
|
+
|
|
22
|
+
dependency = FreeTextQuestion(
|
|
23
|
+
key="dependency",
|
|
24
|
+
message="Enter the name of the dependency you want to install",
|
|
25
|
+
).ask()["dependency"]
|
|
26
|
+
|
|
27
|
+
if not dependency:
|
|
28
|
+
print("Dependency name cannot be empty. Let's try again.")
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
dependency_is_correct = BooleanQuestion(
|
|
32
|
+
key="dependency_is_correct",
|
|
33
|
+
message=f"Is '{dependency}' spelled correctly?",
|
|
34
|
+
default=True,
|
|
35
|
+
).ask()["dependency_is_correct"]
|
|
36
|
+
|
|
37
|
+
if dependency_is_correct:
|
|
38
|
+
print(f"Dependency {dependency} will be installed.")
|
|
39
|
+
dependencies.append(dependency)
|
|
40
|
+
else:
|
|
41
|
+
print("Let's try again.")
|
|
42
|
+
|
|
43
|
+
return {self._key: dependencies}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import questionary
|
|
2
|
+
|
|
3
|
+
from instant_python.question_prompter.question.question import Question
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FreeTextQuestion(Question[str]):
|
|
7
|
+
def __init__(self, key: str, message: str, default: str | None = None) -> None:
|
|
8
|
+
super().__init__(key, message)
|
|
9
|
+
self._default = default if default else ""
|
|
10
|
+
|
|
11
|
+
def ask(self) -> dict[str, str]:
|
|
12
|
+
answer = questionary.text(self._message, default=self._default).ask()
|
|
13
|
+
return {self._key: answer}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import questionary
|
|
2
|
+
|
|
3
|
+
from instant_python.question_prompter.question.question import Question
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MultipleChoiceQuestion(Question[list[str]]):
|
|
7
|
+
def __init__(self, key: str, message: str, options: list[str]) -> None:
|
|
8
|
+
super().__init__(key, message)
|
|
9
|
+
self._options = options
|
|
10
|
+
|
|
11
|
+
def ask(self) -> dict[str, list[str]]:
|
|
12
|
+
answer = questionary.checkbox(self._message, choices=self._options).ask()
|
|
13
|
+
return {self._key: answer}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Question[T](ABC):
|
|
5
|
+
def __init__(self, key: str, message: str) -> None:
|
|
6
|
+
self._key = key
|
|
7
|
+
self._message = message
|
|
8
|
+
|
|
9
|
+
@abstractmethod
|
|
10
|
+
def ask(self) -> dict[str, T]:
|
|
11
|
+
raise NotImplementedError
|
|
12
|
+
|
|
13
|
+
@property
|
|
14
|
+
def key(self) -> str:
|
|
15
|
+
return self._key
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from instant_python.question_prompter.step.steps import Steps
|
|
2
|
+
from instant_python.question_prompter.user_requirements import UserRequirements
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class QuestionWizard:
|
|
6
|
+
def __init__(self, steps: Steps) -> None:
|
|
7
|
+
self._steps = steps
|
|
8
|
+
self._answers = {}
|
|
9
|
+
|
|
10
|
+
def run(self) -> UserRequirements:
|
|
11
|
+
for step in self._steps:
|
|
12
|
+
answer = step.run(self._answers)
|
|
13
|
+
self._answers.update(answer)
|
|
14
|
+
|
|
15
|
+
return UserRequirements(**self._answers)
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from instant_python.question_prompter.question.dependencies_question import (
|
|
2
|
+
DependenciesQuestion,
|
|
3
|
+
)
|
|
4
|
+
from instant_python.question_prompter.step.steps import Step
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DependenciesStep(Step):
|
|
8
|
+
def __init__(self) -> None:
|
|
9
|
+
self._questions = [
|
|
10
|
+
DependenciesQuestion(
|
|
11
|
+
key="dependencies",
|
|
12
|
+
message="Do you want to install any dependencies?",
|
|
13
|
+
)
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
def run(self, answers_so_far: dict[str, str]) -> dict[str, str]:
|
|
17
|
+
for question in self._questions:
|
|
18
|
+
answers_so_far.update(question.ask())
|
|
19
|
+
|
|
20
|
+
return answers_so_far
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from instant_python.question_prompter.question.choice_question import ChoiceQuestion
|
|
2
|
+
from instant_python.question_prompter.question.free_text_question import FreeTextQuestion
|
|
3
|
+
from instant_python.question_prompter.step.steps import Step
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GeneralCustomTemplateProjectStep(Step):
|
|
7
|
+
def __init__(self) -> None:
|
|
8
|
+
self._questions = [
|
|
9
|
+
FreeTextQuestion(
|
|
10
|
+
key="project_slug",
|
|
11
|
+
message="Enter the name of the project (CANNOT CONTAIN SPACES)",
|
|
12
|
+
default="python-project",
|
|
13
|
+
),
|
|
14
|
+
FreeTextQuestion(
|
|
15
|
+
key="description",
|
|
16
|
+
message="Enter the project description",
|
|
17
|
+
default="Python Project Description",
|
|
18
|
+
),
|
|
19
|
+
FreeTextQuestion(
|
|
20
|
+
key="version",
|
|
21
|
+
message="Enter the project initial version",
|
|
22
|
+
default="0.1.0",
|
|
23
|
+
),
|
|
24
|
+
FreeTextQuestion(key="author", message="Enter your name"),
|
|
25
|
+
ChoiceQuestion(
|
|
26
|
+
key="license",
|
|
27
|
+
message="Select a license",
|
|
28
|
+
options=["MIT", "Apache", "GPL"],
|
|
29
|
+
),
|
|
30
|
+
ChoiceQuestion(
|
|
31
|
+
key="python_version",
|
|
32
|
+
message="Enter the python version",
|
|
33
|
+
options=["3.13", "3.12", "3.11", "3.10"],
|
|
34
|
+
),
|
|
35
|
+
ChoiceQuestion(
|
|
36
|
+
key="dependency_manager",
|
|
37
|
+
message="Select a dependency manager",
|
|
38
|
+
options=["uv", "pdm"],
|
|
39
|
+
),
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
def run(self, answers_so_far: dict[str, str]) -> dict[str, str]:
|
|
43
|
+
for question in self._questions:
|
|
44
|
+
answers_so_far.update(question.ask())
|
|
45
|
+
return answers_so_far
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from instant_python.question_prompter.question.choice_question import ChoiceQuestion
|
|
2
|
+
from instant_python.question_prompter.question.free_text_question import FreeTextQuestion
|
|
3
|
+
from instant_python.question_prompter.step.steps import Step
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GeneralProjectStep(Step):
|
|
7
|
+
def __init__(self) -> None:
|
|
8
|
+
self._questions = [
|
|
9
|
+
FreeTextQuestion(
|
|
10
|
+
key="project_slug",
|
|
11
|
+
message="Enter the name of the project (CANNOT CONTAIN SPACES)",
|
|
12
|
+
default="python-project",
|
|
13
|
+
),
|
|
14
|
+
FreeTextQuestion(
|
|
15
|
+
key="source_name",
|
|
16
|
+
message="Enter the name of the source folder",
|
|
17
|
+
default="src",
|
|
18
|
+
),
|
|
19
|
+
FreeTextQuestion(
|
|
20
|
+
key="description",
|
|
21
|
+
message="Enter the project description",
|
|
22
|
+
default="Python Project Description",
|
|
23
|
+
),
|
|
24
|
+
FreeTextQuestion(
|
|
25
|
+
key="version",
|
|
26
|
+
message="Enter the project initial version",
|
|
27
|
+
default="0.1.0",
|
|
28
|
+
),
|
|
29
|
+
FreeTextQuestion(key="author", message="Enter your name"),
|
|
30
|
+
ChoiceQuestion(
|
|
31
|
+
key="license",
|
|
32
|
+
message="Select a license",
|
|
33
|
+
options=["MIT", "Apache", "GPL"],
|
|
34
|
+
),
|
|
35
|
+
ChoiceQuestion(
|
|
36
|
+
key="python_version",
|
|
37
|
+
message="Enter the python version",
|
|
38
|
+
options=["3.13", "3.12", "3.11", "3.10"],
|
|
39
|
+
),
|
|
40
|
+
ChoiceQuestion(
|
|
41
|
+
key="dependency_manager",
|
|
42
|
+
message="Select a dependency manager",
|
|
43
|
+
options=["uv", "pdm"],
|
|
44
|
+
),
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
def run(self, answers_so_far: dict[str, str]) -> dict[str, str]:
|
|
48
|
+
for question in self._questions:
|
|
49
|
+
answers_so_far.update(question.ask())
|
|
50
|
+
return answers_so_far
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from instant_python.question_prompter.question.boolean_question import BooleanQuestion
|
|
2
|
+
from instant_python.question_prompter.question.conditional_question import ConditionalQuestion
|
|
3
|
+
from instant_python.question_prompter.question.free_text_question import FreeTextQuestion
|
|
4
|
+
from instant_python.question_prompter.step.steps import Step
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class GitStep(Step):
|
|
8
|
+
def __init__(self) -> None:
|
|
9
|
+
self._questions = [
|
|
10
|
+
ConditionalQuestion(
|
|
11
|
+
base_question=BooleanQuestion(key="git", message="Do you want to initialize a git repository?", default=True),
|
|
12
|
+
subquestions=[
|
|
13
|
+
FreeTextQuestion(key="git_user_name", message="Type your git user name"),
|
|
14
|
+
FreeTextQuestion(key="git_email", message="Type your git email"),
|
|
15
|
+
],
|
|
16
|
+
condition=True
|
|
17
|
+
)
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
def run(self, answers_so_far: dict[str, str]) -> dict[str, str]:
|
|
21
|
+
for question in self._questions:
|
|
22
|
+
answers_so_far.update(question.ask())
|
|
23
|
+
return answers_so_far
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from collections.abc import Iterator
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Step(ABC):
|
|
6
|
+
@abstractmethod
|
|
7
|
+
def run(self, answers_so_far: dict[str, str]) -> dict[str, str]:
|
|
8
|
+
raise NotImplementedError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Steps:
|
|
12
|
+
def __init__(self, *step: Step) -> None:
|
|
13
|
+
self._steps = list(step)
|
|
14
|
+
|
|
15
|
+
def __iter__(self) -> Iterator[Step]:
|
|
16
|
+
return iter(self._steps)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from instant_python.question_prompter.question.choice_question import ChoiceQuestion
|
|
2
|
+
from instant_python.question_prompter.question.conditional_question import (
|
|
3
|
+
ConditionalQuestion,
|
|
4
|
+
)
|
|
5
|
+
from instant_python.question_prompter.question.free_text_question import (
|
|
6
|
+
FreeTextQuestion,
|
|
7
|
+
)
|
|
8
|
+
from instant_python.question_prompter.question.multiple_choice_question import (
|
|
9
|
+
MultipleChoiceQuestion,
|
|
10
|
+
)
|
|
11
|
+
from instant_python.question_prompter.step.steps import Step
|
|
12
|
+
from instant_python.question_prompter.template_types import TemplateTypes
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TemplateStep(Step):
|
|
16
|
+
def __init__(self) -> None:
|
|
17
|
+
self._questions = [
|
|
18
|
+
MultipleChoiceQuestion(
|
|
19
|
+
key="built_in_features",
|
|
20
|
+
message="Select the built-in features you want to include (fastapi_application option requires logger)",
|
|
21
|
+
options=[
|
|
22
|
+
"value_objects",
|
|
23
|
+
"github_actions",
|
|
24
|
+
"makefile",
|
|
25
|
+
"synchronous_sqlalchemy",
|
|
26
|
+
"logger",
|
|
27
|
+
"event_bus",
|
|
28
|
+
"async_sqlalchemy",
|
|
29
|
+
"async_alembic",
|
|
30
|
+
"fastapi_application",
|
|
31
|
+
],
|
|
32
|
+
),
|
|
33
|
+
ConditionalQuestion(
|
|
34
|
+
base_question=ChoiceQuestion(
|
|
35
|
+
key="template",
|
|
36
|
+
message="Select a template",
|
|
37
|
+
options=[
|
|
38
|
+
"domain_driven_design",
|
|
39
|
+
"clean_architecture",
|
|
40
|
+
"standard_project",
|
|
41
|
+
],
|
|
42
|
+
),
|
|
43
|
+
subquestions=[
|
|
44
|
+
FreeTextQuestion(
|
|
45
|
+
key="bounded_context",
|
|
46
|
+
message="Enter the bounded context name",
|
|
47
|
+
default="backoffice",
|
|
48
|
+
),
|
|
49
|
+
FreeTextQuestion(
|
|
50
|
+
key="aggregate_name",
|
|
51
|
+
message="Enter the aggregate name",
|
|
52
|
+
default="user",
|
|
53
|
+
),
|
|
54
|
+
],
|
|
55
|
+
condition=TemplateTypes.DDD,
|
|
56
|
+
),
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
def run(self, answers_so_far: dict[str, str]) -> dict[str, str]:
|
|
60
|
+
for question in self._questions:
|
|
61
|
+
answers_so_far.update(question.ask())
|
|
62
|
+
|
|
63
|
+
return answers_so_far
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from dataclasses import dataclass, asdict, field
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class UserRequirements:
|
|
10
|
+
project_slug: str
|
|
11
|
+
license: str
|
|
12
|
+
version: str
|
|
13
|
+
description: str
|
|
14
|
+
author: str
|
|
15
|
+
python_version: str
|
|
16
|
+
dependency_manager: str
|
|
17
|
+
git: bool = field(default=False)
|
|
18
|
+
source_name: str = field(default_factory=str)
|
|
19
|
+
template: str = field(default_factory=str)
|
|
20
|
+
git_email: str = field(default_factory=str)
|
|
21
|
+
git_user_name: str = field(default_factory=str)
|
|
22
|
+
dependencies: list[str] = field(default_factory=list)
|
|
23
|
+
bounded_context: str = field(default_factory=str)
|
|
24
|
+
aggregate_name: str = field(default_factory=str)
|
|
25
|
+
built_in_features: list[str] = field(default_factory=list)
|
|
26
|
+
year: int = field(default=datetime.now().year)
|
|
27
|
+
|
|
28
|
+
def __post_init__(self) -> None:
|
|
29
|
+
self._file_path = "user_requirements.yml"
|
|
30
|
+
|
|
31
|
+
def to_dict(self) -> dict:
|
|
32
|
+
return asdict(self)
|
|
33
|
+
|
|
34
|
+
def save_in_memory(self) -> None:
|
|
35
|
+
with open(self._file_path, "w") as file:
|
|
36
|
+
yaml.dump(self.to_dict(), file)
|
|
37
|
+
|
|
38
|
+
def remove(self) -> None:
|
|
39
|
+
Path(self._file_path).unlink()
|
|
File without changes
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
|
|
110
|
+
# pdm
|
|
111
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
112
|
+
#pdm.lock
|
|
113
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
114
|
+
# in version control.
|
|
115
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
116
|
+
.pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
121
|
+
__pypackages__/
|
|
122
|
+
|
|
123
|
+
# Celery stuff
|
|
124
|
+
celerybeat-schedule
|
|
125
|
+
celerybeat.pid
|
|
126
|
+
|
|
127
|
+
# SageMath parsed files
|
|
128
|
+
*.sage.py
|
|
129
|
+
|
|
130
|
+
# Environments
|
|
131
|
+
.env
|
|
132
|
+
.venv
|
|
133
|
+
env/
|
|
134
|
+
venv/
|
|
135
|
+
ENV/
|
|
136
|
+
env.bak/
|
|
137
|
+
venv.bak/
|
|
138
|
+
|
|
139
|
+
# Spyder project settings
|
|
140
|
+
.spyderproject
|
|
141
|
+
.spyproject
|
|
142
|
+
|
|
143
|
+
# Rope project settings
|
|
144
|
+
.ropeproject
|
|
145
|
+
|
|
146
|
+
# mkdocs documentation
|
|
147
|
+
/site
|
|
148
|
+
|
|
149
|
+
# mypy
|
|
150
|
+
.mypy_cache/
|
|
151
|
+
.dmypy.json
|
|
152
|
+
dmypy.json
|
|
153
|
+
|
|
154
|
+
# Pyre type checker
|
|
155
|
+
.pyre/
|
|
156
|
+
|
|
157
|
+
# pytype static type analyzer
|
|
158
|
+
.pytype/
|
|
159
|
+
|
|
160
|
+
# Cython debug symbols
|
|
161
|
+
cython_debug/
|
|
162
|
+
|
|
163
|
+
# PyPI configuration file
|
|
164
|
+
.pypirc
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-added-large-files
|
|
6
|
+
- id: check-ast
|
|
7
|
+
- id: check-case-conflict
|
|
8
|
+
- id: check-merge-conflict
|
|
9
|
+
|
|
10
|
+
- repo: local
|
|
11
|
+
hooks:
|
|
12
|
+
- id: type-check
|
|
13
|
+
name: check typing
|
|
14
|
+
entry: make check-typing
|
|
15
|
+
language: system
|
|
16
|
+
- id: lint
|
|
17
|
+
name: check for lint
|
|
18
|
+
entry: make lint
|
|
19
|
+
language: system
|
|
20
|
+
- id: format
|
|
21
|
+
name: check for code format
|
|
22
|
+
entry: make format
|
|
23
|
+
language: system
|
|
24
|
+
- id: unit-test
|
|
25
|
+
name: run all unit test
|
|
26
|
+
entry: make all-unit
|
|
27
|
+
language: system
|
|
28
|
+
- id: pre-push
|
|
29
|
+
name: run integration and acceptance test
|
|
30
|
+
entry: make pre-push
|
|
31
|
+
language: system
|
|
32
|
+
stages:
|
|
33
|
+
- pre-push
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{ python_version }}
|