mirror of
https://github.com/ycd/manage-fastapi.git
synced 2021-11-08 01:34:39 +03:00
✨ Add docker support to startproject
This commit is contained in:
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
python-version: [3.6, 3.7, 3.8]
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ The package plans are here. If you want to contribute with new ideas, or develop
|
|||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
- [X] License support on `startproject`.
|
- [X] License support on `startproject`.
|
||||||
- [ ] Docker/Docker-compose support on `startproject`.
|
- [X] Docker/Docker-compose support on `startproject`.
|
||||||
- [ ] VSCode debugger support on `startproject` (available via docker).
|
- [ ] VSCode debugger support on `startproject` (available via docker).
|
||||||
- [X] Add basic linter tools on `startproject` (flake8, mypy and isort).
|
- [X] Add basic linter tools on `startproject` (flake8, mypy and isort).
|
||||||
- [X] Add `.pre-commit-config.yaml` on `startproject`.
|
- [X] Add `.pre-commit-config.yaml` on `startproject`.
|
||||||
@@ -18,3 +18,7 @@ The package plans are here. If you want to contribute with new ideas, or develop
|
|||||||
- [ ] Integrate databases on `startproject`.
|
- [ ] Integrate databases on `startproject`.
|
||||||
- [ ] Create `migrations`/`migrate` command.
|
- [ ] Create `migrations`/`migrate` command.
|
||||||
- [ ] Different Authentication support on `startproject`.
|
- [ ] Different Authentication support on `startproject`.
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
|
||||||
|
- Should we support .git by default?
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ class PythonVersion(BaseEnum):
|
|||||||
THREE_DOT_SIX = "3.6"
|
THREE_DOT_SIX = "3.6"
|
||||||
THREE_DOT_SEV = "3.7"
|
THREE_DOT_SEV = "3.7"
|
||||||
THREE_DOT_EIG = "3.8"
|
THREE_DOT_EIG = "3.8"
|
||||||
THREE_DOT_NIN = "3.9"
|
|
||||||
|
|
||||||
|
|
||||||
class License(BaseEnum):
|
class License(BaseEnum):
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
FROM tiangolo/uvicorn-gunicorn-fastapi:python{{ cookiecutter.python }}
|
||||||
|
|
||||||
|
ENV PYTHONPATH "${PYTHONPATH}:/"
|
||||||
|
ENV PORT=8000
|
||||||
|
|
||||||
|
# Install Poetry
|
||||||
|
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && \
|
||||||
|
cd /usr/local/bin && \
|
||||||
|
ln -s /opt/poetry/bin/poetry && \
|
||||||
|
poetry config virtualenvs.create false
|
||||||
|
|
||||||
|
# Copy using poetry.lock* in case it doesn't exist yet
|
||||||
|
COPY ./pyproject.toml ./poetry.lock* /app/
|
||||||
|
|
||||||
|
RUN poetry install --no-root --no-dev
|
||||||
|
|
||||||
|
COPY ./app /app
|
||||||
@@ -1,8 +1,19 @@
|
|||||||
from pydantic import BaseSettings
|
from typing import List, Union
|
||||||
|
|
||||||
|
from pydantic import AnyHttpUrl, BaseSettings, validator
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
PROJECT_NAME: str
|
PROJECT_NAME: str
|
||||||
|
BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = []
|
||||||
|
|
||||||
|
@validator("BACKEND_CORS_ORIGINS", pre=True)
|
||||||
|
def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
|
||||||
|
if isinstance(v, str) and not v.startswith("["):
|
||||||
|
return [i.strip() for i in v.split(",")]
|
||||||
|
elif isinstance(v, (list, str)):
|
||||||
|
return v
|
||||||
|
raise ValueError(v)
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
env_file = ".env"
|
env_file = ".env"
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
|
|
||||||
app = FastAPI(title=settings.PROJECT_NAME)
|
|
||||||
|
def get_application():
|
||||||
|
_app = FastAPI(title=settings.PROJECT_NAME)
|
||||||
|
|
||||||
|
_app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
return _app
|
||||||
|
|
||||||
|
|
||||||
|
app = get_application()
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: .
|
||||||
|
env_file: ".env"
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
@@ -23,7 +23,6 @@ classifiers = [
|
|||||||
"Programming Language :: Python :: 3.6",
|
"Programming Language :: Python :: 3.6",
|
||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
"Programming Language :: Python :: 3.9",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[isort]
|
[isort]
|
||||||
profile = black
|
profile = black
|
||||||
known_first_party = manage_fastapi
|
known_first_party = manage_fastapi
|
||||||
skip = '{{ cookiecutter.folder_name }}/*'
|
skip = */templates/*
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
max-complexity = 7
|
max-complexity = 7
|
||||||
@@ -16,3 +16,6 @@ plugins = pydantic.mypy
|
|||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
follow_imports = skip
|
follow_imports = skip
|
||||||
strict_optional = True
|
strict_optional = True
|
||||||
|
|
||||||
|
[coverage:run]
|
||||||
|
omit = */templates/*
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from typer.testing import CliRunner
|
|
||||||
|
|
||||||
from manage_fastapi.main import app
|
from manage_fastapi.main import app
|
||||||
|
from typer.testing import CliRunner
|
||||||
|
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
@@ -11,11 +10,19 @@ CREATED_SUCCESSFULLY = "FastAPI project created successfully! 🎉\n"
|
|||||||
ALREADY_EXISTS = "Folder 'potato' already exists. 😞\n"
|
ALREADY_EXISTS = "Folder 'potato' already exists. 😞\n"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pkg", ["pip", "poetry"])
|
@pytest.mark.parametrize("package_", ["pip", "poetry"])
|
||||||
@pytest.mark.parametrize("py", ["3.6", "3.7", "3.8", "3.9"])
|
@pytest.mark.parametrize("python", ["3.6", "3.7", "3.8"])
|
||||||
def test_startproject(project_name: str, pkg: str, py: str):
|
@pytest.mark.parametrize(
|
||||||
|
"license_", ["MIT", "BSD-3", "GNU GPL v3.0", "Apache Software License 2.0"]
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize("pre_commit", [True, False])
|
||||||
|
def test_startproject(
|
||||||
|
project_name: str, package_: str, python: str, license_: str, pre_commit: bool
|
||||||
|
):
|
||||||
package = "manage_fastapi.main.launch_cli"
|
package = "manage_fastapi.main.launch_cli"
|
||||||
with patch(package, return_value=[pkg, py]) as mock_obj:
|
with patch(
|
||||||
|
package, return_value=[package_, python, license_, pre_commit]
|
||||||
|
) as mock_obj:
|
||||||
result = runner.invoke(app, ["startproject", project_name])
|
result = runner.invoke(app, ["startproject", project_name])
|
||||||
assert mock_obj.assert_called_once
|
assert mock_obj.assert_called_once
|
||||||
assert result.output == CREATED_SUCCESSFULLY
|
assert result.output == CREATED_SUCCESSFULLY
|
||||||
|
|||||||
Reference in New Issue
Block a user