FastAPI Project Generator 사용

소개



전회 소개한 FastAPI입니다만, 아무래도 보일러 플레이트가 존재하는 것 같기 때문에 검증합니다.

환경


- ubuntu 20.04.2 LTS(wsl)
- python 3.8

설치



편지지 작성 전에 openssl에서 키를 작성할 필요가 있다는 기재가 있었으므로 작성해 둡니다.
출력값은 나중에 사용하므로 삼가합시다.
$ openssl rand -hex 32
2cfc~

다음 명령으로 프로젝트의 편지지를 만듭니다.
cookiecutter라는 도구를 사용하여 git 저장소에서 편지지를 만드는 것 같습니다.
$ pip install cookiecutter
$ cookiecutter https://github.com/tiangolo/full-stack-fastapi-postgresql

마법사 형식으로 프로젝트에 필요한 정보를 입력합니다.
project_name [Base Project]: abcApp
project_slug [abcapp]:
domain_main [abcapp.com]:
domain_staging [stag.abcapp.com]:
docker_swarm_stack_name_main [abcapp-com]:
docker_swarm_stack_name_staging [stag-abcapp-com]:
secret_key [changethis]: 2cfc~
first_superuser [[email protected]]:
first_superuser_password [changethis]: ●●●●●
backend_cors_origins [["http://localhost", "http://localhost:4200", "http://localhost:3000", "http://localhost:8080", "https://localhost", "https://localhost:4200", "https://localhost:3000", "https://localhost:8080", "http://dev.abcapp.com", "https://stag.abcapp.com", "https://abcapp.com", "http://local.dockertoolbox.tiangolo.com", "http://localhost.tiangolo.com"]]:
smtp_port [587]:
smtp_host []:
smtp_user []:
smtp_password []:
smtp_emails_from_email [[email protected]]:
postgres_password [changethis]: ●●●●●
pgadmin_default_user [[email protected]]:
pgadmin_default_user_password [admin]:
traefik_constraint_tag [abcapp.com]:
traefik_constraint_tag_staging [stag.abcapp.com]:
traefik_public_constraint_tag [traefik-public]:
flower_auth [admin:admin]:
sentry_dsn []:
docker_image_prefix []:
docker_image_backend [backend]:
docker_image_celeryworker [celeryworker]:
docker_image_frontend [frontend]:

우선 abcApp이라는 프로젝트를 만들었습니다.
다양한 항목이 있네요.
방금 앞에 두었던 키를 secret_key로 설정합시다.
풀 스택 프로젝트 템플릿 vue + fastAPI + postgres
어쨌든 각각이 docker 컨테이너로 시작하는 구성으로되어있는 것 같습니다.

작성된 파일입니다.
├── README.md
├── backend
│   ├── app
│   │   ├── alembic
│   │   │   ├── README
│   │   │   ├── env.py
│   │   │   ├── script.py.mako
│   │   │   └── versions
│   │   │       └── d4867f3a4c0a_first_revision.py
│   │   ├── alembic.ini
│   │   ├── app
│   │   │   ├── __init__.py
│   │   │   ├── api
│   │   │   │   ├── __init__.py
│   │   │   │   ├── api_v1
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── api.py
│   │   │   │   │   └── endpoints
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       ├── items.py
│   │   │   │   │       ├── login.py
│   │   │   │   │       ├── users.py
│   │   │   │   │       └── utils.py
│   │   │   │   └── deps.py
│   │   │   ├── backend_pre_start.py
│   │   │   ├── celeryworker_pre_start.py
│   │   │   ├── core
│   │   │   │   ├── __init__.py
│   │   │   │   ├── celery_app.py
│   │   │   │   ├── config.py
│   │   │   │   └── security.py
│   │   │   ├── crud
│   │   │   │   ├── __init__.py
│   │   │   │   ├── base.py
│   │   │   │   ├── crud_item.py
│   │   │   │   └── crud_user.py
│   │   │   ├── db
│   │   │   │   ├── __init__.py
│   │   │   │   ├── base.py
│   │   │   │   ├── base_class.py
│   │   │   │   ├── init_db.py
│   │   │   │   └── session.py
│   │   │   ├── email-templates
│   │   │   │   ├── build
│   │   │   │   │   ├── new_account.html
│   │   │   │   │   ├── reset_password.html
│   │   │   │   │   └── test_email.html
│   │   │   │   └── src
│   │   │   │       ├── new_account.mjml
│   │   │   │       ├── reset_password.mjml
│   │   │   │       └── test_email.mjml
│   │   │   ├── initial_data.py
│   │   │   ├── main.py
│   │   │   ├── models
│   │   │   │   ├── __init__.py
│   │   │   │   ├── item.py
│   │   │   │   └── user.py
│   │   │   ├── schemas
│   │   │   │   ├── __init__.py
│   │   │   │   ├── item.py
│   │   │   │   ├── msg.py
│   │   │   │   ├── token.py
│   │   │   │   └── user.py
│   │   │   ├── tests
│   │   │   │   ├── __init__.py
│   │   │   │   ├── api
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   └── api_v1
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       ├── test_celery.py
│   │   │   │   │       ├── test_items.py
│   │   │   │   │       ├── test_login.py
│   │   │   │   │       └── test_users.py
│   │   │   │   ├── conftest.py
│   │   │   │   ├── crud
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── test_item.py
│   │   │   │   │   └── test_user.py
│   │   │   │   └── utils
│   │   │   │       ├── __init__.py
│   │   │   │       ├── item.py
│   │   │   │       ├── user.py
│   │   │   │       └── utils.py
│   │   │   ├── tests_pre_start.py
│   │   │   ├── utils.py
│   │   │   └── worker.py
│   │   ├── mypy.ini
│   │   ├── prestart.sh
│   │   ├── pyproject.toml
│   │   ├── scripts
│   │   │   ├── format-imports.sh
│   │   │   ├── format.sh
│   │   │   ├── lint.sh
│   │   │   ├── test-cov-html.sh
│   │   │   └── test.sh
│   │   ├── tests-start.sh
│   │   └── worker-start.sh
│   ├── backend.dockerfile
│   └── celeryworker.dockerfile
├── cookiecutter-config-file.yml
├── docker-compose.override.yml
├── docker-compose.yml
├── frontend
│   ├── Dockerfile
│   ├── README.md
│   ├── babel.config.js
│   ├── nginx-backend-not-found.conf
│   ├── package.json
│   ├── public
│   │   ├── favicon.ico
│   │   ├── img
│   │   │   └── icons
│   │   │       ├── android-chrome-192x192.png
│   │   │       ├── android-chrome-512x512.png
│   │   │       ├── apple-touch-icon-120x120.png
│   │   │       ├── apple-touch-icon-152x152.png
│   │   │       ├── apple-touch-icon-180x180.png
│   │   │       ├── apple-touch-icon-60x60.png
│   │   │       ├── apple-touch-icon-76x76.png
│   │   │       ├── apple-touch-icon.png
│   │   │       ├── favicon-16x16.png
│   │   │       ├── favicon-32x32.png
│   │   │       ├── msapplication-icon-144x144.png
│   │   │       ├── mstile-150x150.png
│   │   │       └── safari-pinned-tab.svg
│   │   ├── index.html
│   │   ├── manifest.json
│   │   └── robots.txt
│   ├── src
│   │   ├── App.vue
│   │   ├── api.ts
│   │   ├── assets
│   │   │   └── logo.png
│   │   ├── component-hooks.ts
│   │   ├── components
│   │   │   ├── NotificationsManager.vue
│   │   │   ├── RouterComponent.vue
│   │   │   └── UploadButton.vue
│   │   ├── env.ts
│   │   ├── interfaces
│   │   │   └── index.ts
│   │   ├── main.ts
│   │   ├── plugins
│   │   │   ├── vee-validate.ts
│   │   │   └── vuetify.ts
│   │   ├── registerServiceWorker.ts
│   │   ├── router.ts
│   │   ├── shims-tsx.d.ts
│   │   ├── shims-vue.d.ts
│   │   ├── store
│   │   │   ├── admin
│   │   │   │   ├── actions.ts
│   │   │   │   ├── getters.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── mutations.ts
│   │   │   │   └── state.ts
│   │   │   ├── index.ts
│   │   │   ├── main
│   │   │   │   ├── actions.ts
│   │   │   │   ├── getters.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── mutations.ts
│   │   │   │   └── state.ts
│   │   │   └── state.ts
│   │   ├── utils.ts
│   │   └── views
│   │       ├── Login.vue
│   │       ├── PasswordRecovery.vue
│   │       ├── ResetPassword.vue
│   │       └── main
│   │           ├── Dashboard.vue
│   │           ├── Main.vue
│   │           ├── Start.vue
│   │           ├── admin
│   │           │   ├── Admin.vue
│   │           │   ├── AdminUsers.vue
│   │           │   ├── CreateUser.vue
│   │           │   └── EditUser.vue
│   │           └── profile
│   │               ├── UserProfile.vue
│   │               ├── UserProfileEdit.vue
│   │               └── UserProfileEditPassword.vue
│   ├── tests
│   │   └── unit
│   │       └── upload-button.spec.ts
│   ├── tsconfig.json
│   ├── tslint.json
│   └── vue.config.js
└── scripts
    ├── build-push.sh
    ├── build.sh
    ├── deploy.sh
    ├── test-local.sh
    └── test.sh

아무래도 유저의 CRUD 기능과 인증 기능이 디폴트로 구현되고 있어, 거기로부터 각 기능을 확장하는 것 같은 느낌이군요.

컨테이너 시작



컨테이너를 시작해 봅니다.
$ cd abcapp
$ docker-compose up -d

상당한 시간이 걸렸지만 컨테이너가 일어났습니다.

localhost:80/에 액세스해 봅니다.



방금 입력한 admin의 ID/Pass로 로그인해 봅니다.



사용자 등록 화면이 열렸습니다.
UI 세트는 vuetify를 사용하는 것 같습니다.

약간 중후장대한 템플릿인 느낌은 합니다만(보면 pgAdmin의 컨테이너까지 있었습니다.), 컨테이너나 DB 주위의 설정 등 어느 정도의 기초가 완성되고 있는 데에 참고가 되는 코드도 볼 수 있다고 하는 것은 매우 좋다고 생각합니다. 불필요한 컨테이너 등은 깎아 가면 좋네요.
나와 같은 초보자는 이 코드를 먼저 보면서 실제 것을 만들어 가는 편이 습득의 지름길일지도 모릅니다.

좋은 웹페이지 즐겨찾기