Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 6 additions & 184 deletions reactant/main.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
from reactant.orm.django import DjangoModel, DjangoCombustor
from reactant.orm.peewee import PeeweeModel, PeeweeCombustor
from reactant.utils import convert_to_snake
from reactant.exceptions import RenderFailed

from pydantic import BaseModel
from click import secho
from typing import (
Any,
Iterable,
List,
Tuple,
Type,
)
from pydantic import BaseModel

from jinja2 import Environment, PackageLoader
from jinja2.exceptions import TemplateNotFound
from black import format_str, FileMode
from click import secho
from pathlib import Path


env = Environment(
loader=PackageLoader("reactant"),
trim_blocks=True,
)


Expand All @@ -45,170 +27,6 @@ def __str__(self):
return "sqlalchemy"


class DjangoCombustionChamber:
"""For rendering Reactant models that are DjangoORM subclasses."""

def __init__(self, reactants: List[Type[DjangoORM]]) -> None:
self.reactants = reactants

def get_models(self) -> List[DjangoModel]:
models = []
for reactant in self.reactants:
try:
model = DjangoCombustor.generate_django_orm_model(reactant)
models.append(model)
except Exception:
raise
return models

def render_manager(self) -> None:
try:
models = self.get_models()
model_names = [model.name for model in models]

models_code, models_name_str = self.render_models(models)
views_code, views_name_str = self.render_views(model_names)
serializers_code, serializers_name_str = self.render_serializers(
models, model_names
)
urls_code, urls_name_str = self.render_urls(model_names)

self.write_to_file(models_code, models_name_str)
self.write_to_file(views_code, views_name_str)
self.write_to_file(serializers_code, serializers_name_str)
self.write_to_file(urls_code, urls_name_str)
except Exception:
raise

def render_models(self, models: List[DjangoModel]) -> Tuple[str, str]:
item_name = "models"
try:
template_models = env.get_template("django_models.txt.jinja")
output_models = template_models.render(models=models)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_models, item_name)

def render_views(self, model_names: List[str]) -> Tuple[str, str]:
item_name = "views_class"
try:
template_views = env.get_template("django_views.txt.jinja")
output_views = template_views.render(names=model_names)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_views, item_name)

def render_serializers(
self, models: List[DjangoModel], model_names: List[str]
) -> Tuple[str, str]:
item_name = "serializers"
try:
template_serializers = env.get_template("django_serializers.txt.jinja")
output_serializers = template_serializers.render(
models=models, names=model_names
)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_serializers, item_name)

def render_urls(self, model_names: List[str]) -> Tuple[str, str]:
item_name = "urls_class"
try:
snaked_model_names = [convert_to_snake(name) for name in model_names]
paired_names = dict(zip(model_names, snaked_model_names))
template_urls = env.get_template("django_urls.txt.jinja")
output_urls = template_urls.render(names=paired_names)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_urls, item_name)

def write_to_file(self, item: Any, item_name: str) -> None:
try:
p = Path("reactant_products/django")
p.mkdir(parents=True, exist_ok=True)
formatted_code = format_str(item, mode=FileMode())
with open(f"{p}/{item_name}.py", "w") as file:
file.write(formatted_code)
except Exception:
raise
else:
self._success_secho(item_name)

def _success_secho(self, item_name: str):
return secho(f"Django {item_name}.py finished rendering.", fg="green")


class PeeweeCombustionChamber:
"""For rendering Reactant models that are PeeweeORM subclasses."""

def __init__(self, reactants: List[Type[PeeweeORM]]) -> None:
self.reactants = reactants

def get_models(self) -> List[PeeweeModel]:
models = []
for reactant in self.reactants:
try:
model = PeeweeCombustor.generate_peewee_orm_model(reactant)
models.append(model)
except Exception:
raise
return models

def render_manager(self) -> None:
try:
models = self.get_models()
fields_list = []
for model in models:
for field in model.fields:
fields_list.append(field.type)
fields_set = set(fields_list)
models_code, models_name_str = self.render_models(models, fields_set)
self.write_to_file(models_code, models_name_str)
except Exception:
raise

def render_models(
self, models: List[PeeweeModel], fields_set: Iterable
) -> Tuple[str, str]:
item_name = "models"
try:
template_models = env.get_template("peewee_models.txt.jinja")
output_models = template_models.render(models=models, fields_set=fields_set)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_models, item_name)

def write_to_file(self, item: Any, item_name: str) -> None:
try:
p = Path("reactant_products/peewee")
p.mkdir(parents=True, exist_ok=True)
formatted_code = format_str(item, mode=FileMode())
with open(f"{p}/{item_name}.py", "w") as file:
file.write(formatted_code)
except Exception:
raise
else:
self._success_secho(item_name)

def _success_secho(self, item_name: str):
return secho(f"Peewee {item_name}.py finished rendering.", fg="green")


def classify_reactants() -> Tuple[List[Any], ...]:
dj_classes = [cls for cls in DjangoORM.__subclasses__()]
alchemy_classes = [cls for cls in SQLAlchemyORM.__subclasses__()]
Expand All @@ -227,13 +45,17 @@ def generate() -> None:
dj_classes, alchemy_classes, peewee_classes = classify_reactants()

if dj_classes:
from reactant.renderer.django import DjangoCombustionChamber

secho(f"Found {len(dj_classes)} Django reactants.", fg="blue")
dj_rxn = DjangoCombustionChamber(dj_classes)
dj_rxn.render_manager()
else:
secho("No Django reactants found.", fg="blue")

if peewee_classes:
from reactant.renderer.peewee import PeeweeCombustionChamber

secho(f"Found {len(peewee_classes)} Peewee reactants.", fg="blue")
pw_rxn = PeeweeCombustionChamber(peewee_classes)
pw_rxn.render_manager()
Expand Down
Empty file added reactant/renderer/__init__.py
Empty file.
128 changes: 128 additions & 0 deletions reactant/renderer/django.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
from reactant.orm.django import DjangoModel, DjangoCombustor
from reactant.main import DjangoORM
from reactant.utils import convert_to_snake
from reactant.exceptions import RenderFailed

from typing import (
Any,
Iterable,
List,
Tuple,
Type,
)

from jinja2 import Environment, PackageLoader
from jinja2.exceptions import TemplateNotFound
from black import format_str, FileMode
from click import secho
from pathlib import Path

env = Environment(
loader=PackageLoader("reactant"),
trim_blocks=True,
)


class DjangoCombustionChamber:
"""For rendering Reactant models that are DjangoORM subclasses."""

def __init__(self, reactants: List[Type[DjangoORM]]) -> None:
self.reactants = reactants

def get_models(self) -> List[DjangoModel]:
models = []
for reactant in self.reactants:
try:
model = DjangoCombustor.generate_django_orm_model(reactant)
models.append(model)
except Exception:
raise
return models

def render_manager(self) -> None:
try:
models = self.get_models()
model_names = [model.name for model in models]

models_code, models_name_str = self.render_models(models)
views_code, views_name_str = self.render_views(model_names)
serializers_code, serializers_name_str = self.render_serializers(
models, model_names
)
urls_code, urls_name_str = self.render_urls(model_names)

self.write_to_file(models_code, models_name_str)
self.write_to_file(views_code, views_name_str)
self.write_to_file(serializers_code, serializers_name_str)
self.write_to_file(urls_code, urls_name_str)
except Exception:
raise

def render_models(self, models: List[DjangoModel]) -> Tuple[str, str]:
item_name = "models"
try:
template_models = env.get_template("django_models.txt.jinja")
output_models = template_models.render(models=models)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_models, item_name)

def render_views(self, model_names: List[str]) -> Tuple[str, str]:
item_name = "views_class"
try:
template_views = env.get_template("django_views.txt.jinja")
output_views = template_views.render(names=model_names)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_views, item_name)

def render_serializers(
self, models: List[DjangoModel], model_names: List[str]
) -> Tuple[str, str]:
item_name = "serializers"
try:
template_serializers = env.get_template("django_serializers.txt.jinja")
output_serializers = template_serializers.render(
models=models, names=model_names
)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_serializers, item_name)

def render_urls(self, model_names: List[str]) -> Tuple[str, str]:
item_name = "urls_class"
try:
snaked_model_names = [convert_to_snake(name) for name in model_names]
paired_names = dict(zip(model_names, snaked_model_names))
template_urls = env.get_template("django_urls.txt.jinja")
output_urls = template_urls.render(names=paired_names)
except TemplateNotFound:
raise
except Exception:
raise RenderFailed(item_name)
else:
return (output_urls, item_name)

def write_to_file(self, item: Any, item_name: str) -> None:
try:
p = Path("reactant_products/django")
p.mkdir(parents=True, exist_ok=True)
formatted_code = format_str(item, mode=FileMode())
with open(f"{p}/{item_name}.py", "w") as file:
file.write(formatted_code)
except Exception:
raise
else:
self._success_secho(item_name)

def _success_secho(self, item_name: str):
return secho(f"Django {item_name}.py finished rendering.", fg="green")
Loading