mirror of
https://github.com/ycd/manage-fastapi.git
synced 2021-11-08 01:34:39 +03:00
✨ Add startapp command
This commit is contained in:
@@ -22,6 +22,7 @@ repos:
|
|||||||
rev: v5.4.2
|
rev: v5.4.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
exclude: .*/templates/.*
|
||||||
args: ["--profile", "black"]
|
args: ["--profile", "black"]
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ The package plans are here. If you want to contribute with new ideas, or develop
|
|||||||
* [X] Integrate databases on `startproject`.
|
* [X] Integrate databases on `startproject`.
|
||||||
- [X] Postgres
|
- [X] Postgres
|
||||||
* [ ] Different Authentication support on `startproject`.
|
* [ ] Different Authentication support on `startproject`.
|
||||||
|
* [X] Support `startapp` command.
|
||||||
|
- [X] Simple app creation.
|
||||||
|
- [ ] Append the APIRouter to the FastAPI app.
|
||||||
* [ ] Add tests.
|
* [ ] Add tests.
|
||||||
* [ ] Fix documentation accordingly.
|
* [ ] Fix documentation accordingly.
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,19 @@ from manage_fastapi.config import FASTAPI_VERSION
|
|||||||
from manage_fastapi.constants import Database, License, PackageManager, PythonVersion
|
from manage_fastapi.constants import Database, License, PackageManager, PythonVersion
|
||||||
|
|
||||||
|
|
||||||
class Context(BaseModel):
|
class AppContext(BaseModel):
|
||||||
|
name: str
|
||||||
|
folder_name: str
|
||||||
|
snake_name: str
|
||||||
|
|
||||||
|
@root_validator(pre=True)
|
||||||
|
def validate_app(cls, values: dict):
|
||||||
|
values["folder_name"] = values["name"].lower().replace(" ", "-").strip()
|
||||||
|
values["snake_name"] = values["folder_name"].replace("-", "_")
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectContext(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
folder_name: str
|
folder_name: str
|
||||||
packaging: PackageManager
|
packaging: PackageManager
|
||||||
@@ -28,7 +40,7 @@ class Context(BaseModel):
|
|||||||
database: Optional[Database]
|
database: Optional[Database]
|
||||||
|
|
||||||
@root_validator(pre=True)
|
@root_validator(pre=True)
|
||||||
def git_info(cls, values: dict):
|
def validate_project(cls, values: dict):
|
||||||
try:
|
try:
|
||||||
values["username"] = subprocess.check_output(
|
values["username"] = subprocess.check_output(
|
||||||
["git", "config", "--get", "user.name"]
|
["git", "config", "--get", "user.name"]
|
||||||
@@ -1,21 +1,33 @@
|
|||||||
import os
|
import os
|
||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
import typer
|
import typer
|
||||||
from cookiecutter.exceptions import OutputDirExistsException
|
from cookiecutter.exceptions import OutputDirExistsException
|
||||||
from cookiecutter.main import cookiecutter
|
from cookiecutter.main import cookiecutter
|
||||||
|
from pydantic.main import BaseModel
|
||||||
|
|
||||||
from manage_fastapi.config import TEMPLATES_DIR
|
from manage_fastapi.config import TEMPLATES_DIR
|
||||||
from manage_fastapi.schemas import Context
|
from manage_fastapi.context import AppContext, ProjectContext
|
||||||
|
|
||||||
|
ContextType = TypeVar("ContextType", bound=BaseModel)
|
||||||
|
|
||||||
|
|
||||||
def generate_project(context: Context):
|
def fill_template(template_name: str, context: ContextType):
|
||||||
try:
|
try:
|
||||||
cookiecutter(
|
cookiecutter(
|
||||||
os.path.join(TEMPLATES_DIR, "project"),
|
os.path.join(TEMPLATES_DIR, template_name),
|
||||||
extra_context=context.dict(),
|
extra_context=context.dict(),
|
||||||
no_input=True,
|
no_input=True,
|
||||||
)
|
)
|
||||||
except OutputDirExistsException:
|
except OutputDirExistsException:
|
||||||
typer.echo(f"Folder '{context.folder_name}' already exists. 😞")
|
typer.echo(f"Folder '{context.folder_name}' already exists. 😞")
|
||||||
else:
|
else:
|
||||||
typer.echo("FastAPI project created successfully! 🎉")
|
typer.echo(f"FastAPI {template_name} created successfully! 🎉")
|
||||||
|
|
||||||
|
|
||||||
|
def generate_app(context: AppContext):
|
||||||
|
fill_template("app", context)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_project(context: ProjectContext):
|
||||||
|
fill_template("project", context)
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import pkg_resources
|
|||||||
import typer
|
import typer
|
||||||
|
|
||||||
from manage_fastapi.constants import Database, License, PackageManager, PythonVersion
|
from manage_fastapi.constants import Database, License, PackageManager, PythonVersion
|
||||||
from manage_fastapi.generator import generate_project
|
from manage_fastapi.context import AppContext, ProjectContext
|
||||||
|
from manage_fastapi.generator import generate_app, generate_project
|
||||||
from manage_fastapi.helpers import bullet, launch_cli, yes_no
|
from manage_fastapi.helpers import bullet, launch_cli, yes_no
|
||||||
from manage_fastapi.schemas import Context
|
|
||||||
|
|
||||||
app = typer.Typer(help="Managing FastAPI projects made easy!", name="Manage FastAPI")
|
app = typer.Typer(help="Managing FastAPI projects made easy!", name="Manage FastAPI")
|
||||||
|
|
||||||
@@ -33,9 +33,9 @@ def startproject(
|
|||||||
("docker", yes_no("docker")),
|
("docker", yes_no("docker")),
|
||||||
("database", bullet(Database)),
|
("database", bullet(Database)),
|
||||||
)
|
)
|
||||||
context = Context(name=name, **result)
|
context = ProjectContext(name=name, **result)
|
||||||
else:
|
else:
|
||||||
context = Context(
|
context = ProjectContext(
|
||||||
name=name,
|
name=name,
|
||||||
packaging=packaging,
|
packaging=packaging,
|
||||||
python=python,
|
python=python,
|
||||||
@@ -48,8 +48,9 @@ def startproject(
|
|||||||
|
|
||||||
|
|
||||||
@app.command(help="Creates a FastAPI component.")
|
@app.command(help="Creates a FastAPI component.")
|
||||||
def startapp():
|
def startapp(name: str):
|
||||||
...
|
context = AppContext(name=name)
|
||||||
|
generate_app(context)
|
||||||
|
|
||||||
|
|
||||||
@app.command(help="Run a FastAPI application.")
|
@app.command(help="Run a FastAPI application.")
|
||||||
|
|||||||
0
manage_fastapi/templates/app/__init__.py
Normal file
0
manage_fastapi/templates/app/__init__.py
Normal file
5
manage_fastapi/templates/app/cookiecutter.json
Normal file
5
manage_fastapi/templates/app/cookiecutter.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"folder_name": "{{ cookiecutter.folder_name }}",
|
||||||
|
"name": "{{ cookiecutter.name }}",
|
||||||
|
"snake_name": "{{ cookiecutter.snake_name }}"
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/")
|
||||||
|
def get_{{ cookiecutter.snake_name }}():
|
||||||
|
return "{{ cookiecutter.name }} app created!"
|
||||||
@@ -17,14 +17,10 @@ def remove_paths(paths: list):
|
|||||||
|
|
||||||
def set_packaging():
|
def set_packaging():
|
||||||
packaging = "{{ cookiecutter.packaging }}"
|
packaging = "{{ cookiecutter.packaging }}"
|
||||||
paths = []
|
|
||||||
|
|
||||||
if packaging == PackageManager.PIP:
|
if packaging == PackageManager.PIP:
|
||||||
paths = ["poetry.lock", "pyproject.toml"]
|
remove_paths(["poetry.lock", "pyproject.toml"])
|
||||||
elif packaging == PackageManager.POETRY:
|
elif packaging == PackageManager.POETRY:
|
||||||
paths = ["requirements.txt"]
|
remove_paths(["requirements.txt"])
|
||||||
|
|
||||||
remove_paths(paths)
|
|
||||||
|
|
||||||
|
|
||||||
def set_pre_commit():
|
def set_pre_commit():
|
||||||
@@ -51,6 +47,14 @@ def set_license():
|
|||||||
remove_paths(["LICENSE"])
|
remove_paths(["LICENSE"])
|
||||||
|
|
||||||
|
|
||||||
|
# def set_config_location():
|
||||||
|
# database = "{{ cookiecutter.database }}"
|
||||||
|
# if database == "None":
|
||||||
|
# remove_paths(["app/core/config.py"])
|
||||||
|
# else:
|
||||||
|
# remove_paths(["app/config.py"])
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
set_database()
|
set_database()
|
||||||
set_docker()
|
set_docker()
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from manage_fastapi.main import app
|
|
||||||
from typer.testing import CliRunner
|
from typer.testing import CliRunner
|
||||||
|
|
||||||
|
from manage_fastapi.main import app
|
||||||
|
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
CREATED_SUCCESSFULLY = "FastAPI project created successfully! 🎉\n"
|
CREATED_SUCCESSFULLY = "FastAPI project created successfully! 🎉\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user