diff --git a/copier.yaml b/copier.yaml index 1fda0cc..3a36605 100644 --- a/copier.yaml +++ b/copier.yaml @@ -21,6 +21,23 @@ project_description: type: str help: Your project description +project_type: + type: str + choices: + - cli + - service + default: cli + help: Type of the project + +service_framework: + type: str + choices: + - fastapi + - flask + default: fastapi + when: "{{ project_type == 'service' }}" + help: Web framework to use + repository_namespace: type: str help: Your repository namespace diff --git a/template/Makefile b/template/Makefile.jinja similarity index 88% rename from template/Makefile rename to template/Makefile.jinja index 382c8b8..631ec99 100644 --- a/template/Makefile +++ b/template/Makefile.jinja @@ -35,3 +35,10 @@ help: [[print(f'\033[36m{m[0]:<20}\033[0m {m[1]}') for m in re.findall(r'^([a-zA-Z_-]+):.*?## (.*)$$', open(makefile).read(), re.M)] for makefile in ('$(MAKEFILE_LIST)').strip().split()]" .DEFAULT_GOAL := help + +{% if project_type == 'service' %} +.PHONY: serve +serve: ## Run the service + @echo "🚀 Running service" + @uv run python -m {{package_name}}.main +{% endif %} diff --git a/template/pyproject.toml.jinja b/template/pyproject.toml.jinja index 8ffb2cf..4591b70 100644 --- a/template/pyproject.toml.jinja +++ b/template/pyproject.toml.jinja @@ -9,14 +9,26 @@ license = "AGPL-3.0" license-files = ["LICENSE"] dependencies = [ -"typer>=0.20" + {%- if project_type == 'cli' %} + "typer>=0.20", + {%- elif project_type == 'service' %} + {%- if service_framework == 'fastapi' %} + "fastapi>=0.110.0", + {%- elif service_framework == 'flask' %} + "flask>=3.0.0", + {%- endif %} + "uvicorn>=0.27.0", + "pydantic-settings>=2.2.0", + {%- endif %} ] [project.urls] Repository = "https://github.com/trobz/{{project_name}}" +{%- if project_type == 'cli' %} [project.scripts] {{ project_name }} = "{{ package_name }}.main:app" +{%- endif %} [dependency-groups] dev = [ diff --git a/template/{% if project_type == 'service' %}.env.sample{% endif %} b/template/{% if project_type == 'service' %}.env.sample{% endif %} new file mode 100644 index 0000000..c2fc6b8 --- /dev/null +++ b/template/{% if project_type == 'service' %}.env.sample{% endif %} @@ -0,0 +1,5 @@ +ENVIRONMENT=local +DEBUG=false + +SERVER_HOST=0.0.0.0 +SERVER_PORT=8000 diff --git a/template/{{package_name}}/main.py b/template/{{package_name}}/main.py deleted file mode 100644 index e5ac6c0..0000000 --- a/template/{{package_name}}/main.py +++ /dev/null @@ -1,3 +0,0 @@ -import typer - -app = typer.Typer() diff --git a/template/{{package_name}}/main.py.jinja b/template/{{package_name}}/main.py.jinja new file mode 100644 index 0000000..79e9e8d --- /dev/null +++ b/template/{{package_name}}/main.py.jinja @@ -0,0 +1,61 @@ +{% if project_type == 'cli' -%} +import typer + +app = typer.Typer() + + +@app.command() +def hello(name: str): + print(f"Hello {name}") + + +if __name__ == "__main__": + app() + +{%- elif project_type == 'service' -%} +{%- if service_framework == 'fastapi' -%} +from fastapi import FastAPI +from .settings import settings +import uvicorn + +app = FastAPI(title="{{ project_name }}") + + +@app.get("/") +def read_root(): + return {"Hello": "World", "env": settings.environment} + +@app.get("/health") +def health_check(): + return {"status": "ok"} + + +if __name__ == "__main__": + uvicorn.run( + "{{ package_name }}.main:app", + host=settings.server_host, + port=settings.server_port, + reload=settings.debug, + ) + +{%- elif service_framework == 'flask' -%} +from flask import Flask +from .settings import settings + +app = Flask(__name__) + + +@app.route("/") +def hello_world(): + return {"Hello": "World", "env": settings.environment} + +@app.route("/health") +def health_check(): + return {"status": "ok"} + + +if __name__ == "__main__": + # For development only. Use a production WSGI server for deployment. + app.run(host=settings.server_host, port=settings.server_port, debug=settings.debug) +{%- endif -%} +{%- endif -%} diff --git a/template/{{package_name}}/{% if project_type == 'service' %}settings.py{% endif %}.jinja b/template/{{package_name}}/{% if project_type == 'service' %}settings.py{% endif %}.jinja new file mode 100644 index 0000000..c58af88 --- /dev/null +++ b/template/{{package_name}}/{% if project_type == 'service' %}settings.py{% endif %}.jinja @@ -0,0 +1,15 @@ +from pydantic_settings import BaseSettings, SettingsConfigDict + + +class Settings(BaseSettings): + model_config = SettingsConfigDict( + env_file=".env", env_ignore_empty=True, extra="ignore" + ) + + environment: str = "local" + debug: bool = False + server_host: str = "0.0.0.0" + server_port: int = 8000 + + +settings = Settings()