diff --git a/src/ohmyapi/__init__.py b/src/ohmyapi/__init__.py index b1e9019..9b9005b 100644 --- a/src/ohmyapi/__init__.py +++ b/src/ohmyapi/__init__.py @@ -1 +1 @@ -__VERSION__ = "0.2.6" +__VERSION__ = "0.2.7" diff --git a/src/ohmyapi/cli.py b/src/ohmyapi/cli.py index 8537950..6728753 100644 --- a/src/ohmyapi/cli.py +++ b/src/ohmyapi/cli.py @@ -27,6 +27,12 @@ def startapp(app_name: str, root: str = "."): scaffolding.startapp(app_name, root) +@app.command() +def dockerize(root: str = "."): + """Create template Dockerfile and docker-compose.yml.""" + scaffolding.copy_static("docker", root) + + @app.command() def serve(root: str = ".", host="127.0.0.1", port=8000): """ @@ -41,6 +47,7 @@ def serve(root: str = ".", host="127.0.0.1", port=8000): @app.command() def shell(root: str = "."): + """An interactive shell with your loaded project runtime.""" project_path = Path(root).resolve() project = runtime.Project(project_path) diff --git a/src/ohmyapi/core/scaffolding.py b/src/ohmyapi/core/scaffolding.py index 1d3f38f..c637b5a 100644 --- a/src/ohmyapi/core/scaffolding.py +++ b/src/ohmyapi/core/scaffolding.py @@ -2,6 +2,8 @@ from pathlib import Path from jinja2 import Environment, FileSystemLoader +import shutil + # Base templates directory TEMPLATE_DIR = Path(__file__).parent / "templates" env = Environment(loader=FileSystemLoader(str(TEMPLATE_DIR))) @@ -53,6 +55,26 @@ def render_template_dir( render_template_file(template_dir / template_rel_path, context, output_path) +def copy_static(dir_name: str, target_dir: Path): + """Statically copy all files from {TEMPLATE_DIR}/{dir_name} to target_dir.""" + template_dir = TEMPLATE_DIR / dir_name + target_dir = Path(target_dir) + if not template_dir.exists(): + print(f"no templates found under: {dir_name}") + return + + for root, _, files in template_dir.walk(): + root_path = Path(root) + for file in files: + src = root_path / file + dst = target_dir / file + if dst.exists(): + print(f"⛔ File exists, skipping: {dst}") + continue + shutil.copy(src, ".") + print(f"✅ Templates created successfully.") + print(f"🔧 Next, run `docker compose up -d --build`") + def startproject(name: str): """Create a new project: flat structure, all project templates go into /""" target_dir = Path(name).resolve() diff --git a/src/ohmyapi/core/templates/docker/Dockerfile b/src/ohmyapi/core/templates/docker/Dockerfile new file mode 100644 index 0000000..28a8f32 --- /dev/null +++ b/src/ohmyapi/core/templates/docker/Dockerfile @@ -0,0 +1,30 @@ +FROM python:3.13-alpine + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + POETRY_HOME="/opt/poetry" \ + POETRY_VIRTUALENVS_IN_PROJECT=true \ + POETRY_NO_INTERACTION=1 + +RUN apk add --no-cache \ + build-base \ + curl \ + git \ + bash \ + libffi-dev \ + openssl-dev \ + python3-dev \ + musl-dev + +RUN curl -sSL https://install.python-poetry.org | python3 - +ENV PATH="$POETRY_HOME/bin:$PATH" + +WORKDIR /app +COPY pyproject.toml poetry.lock* /app/ +RUN poetry lock +RUN poetry install +COPY . /app + +EXPOSE 8000 + +CMD ["poetry", "run", "ohmyapi", "serve", "--host", "0.0.0.0"] diff --git a/src/ohmyapi/core/templates/docker/docker-compose.yml b/src/ohmyapi/core/templates/docker/docker-compose.yml new file mode 100644 index 0000000..6691e61 --- /dev/null +++ b/src/ohmyapi/core/templates/docker/docker-compose.yml @@ -0,0 +1,7 @@ +services: + app: + build: + context: . + restart: unless-stopped + ports: + - 8000:8000 diff --git a/src/ohmyapi/core/templates/project/pyproject.toml.j2 b/src/ohmyapi/core/templates/project/pyproject.toml.j2 index 7b2a532..0fe3dcd 100644 --- a/src/ohmyapi/core/templates/project/pyproject.toml.j2 +++ b/src/ohmyapi/core/templates/project/pyproject.toml.j2 @@ -10,7 +10,7 @@ readme = "README.md" license = { text = "MIT" } dependencies = [ - "ohmyapi (>=0.1.0,<0.2.0)" + "ohmyapi" ] [tool.poetry.group.dev.dependencies]