Improve template (#1)
- Created a README file - Added PyCharm/IntelliJ IDE run configuration - Squashed bugs related to: - Code style - Default Postgre database URL schema - Updated project dependencies Reviewed-on: #1 Co-authored-by: Ēriks K <git@72.lv> Co-committed-by: Ēriks K <git@72.lv>
This commit is contained in:
parent
0f01088e4f
commit
ef5da867a6
1
{{ cookiecutter.project_slug }}/.gitignore
vendored
1
{{ cookiecutter.project_slug }}/.gitignore
vendored
@ -176,3 +176,4 @@ dmypy.json
|
||||
.pytype/
|
||||
cython_debug/
|
||||
cookiecutter.zip
|
||||
envs.yml
|
||||
|
8
{{ cookiecutter.project_slug }}/.idea/.gitignore
generated
vendored
Normal file
8
{{ cookiecutter.project_slug }}/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
6
{{ cookiecutter.project_slug }}/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
{{ cookiecutter.project_slug }}/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
6
{{ cookiecutter.project_slug }}/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
{{ cookiecutter.project_slug }}/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
7
{{ cookiecutter.project_slug }}/.idea/misc.xml
generated
Normal file
7
{{ cookiecutter.project_slug }}/.idea/misc.xml
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3 ({{ cookiecutter.project_slug }})" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3 ({{ cookiecutter.project_slug }})" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
{{ cookiecutter.project_slug }}/.idea/modules.xml
generated
Normal file
8
{{ cookiecutter.project_slug }}/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/{{ cookiecutter.project_slug }}.iml" filepath="$PROJECT_DIR$/.idea/{{ cookiecutter.project_slug }}.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
26
{{ cookiecutter.project_slug }}/.idea/runConfigurations/Create_migration.xml
generated
Normal file
26
{{ cookiecutter.project_slug }}/.idea/runConfigurations/Create_migration.xml
generated
Normal file
@ -0,0 +1,26 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Create migration" type="PythonConfigurationType" factoryName="Python">
|
||||
<module name="{{ cookiecutter.project_slug }}" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="SDK_NAME" value="Python 3 ({{ cookiecutter.project_slug }})" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="false" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/venv/bin/aerich" />
|
||||
<option name="PARAMETERS" value="migrate" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
18
{{ cookiecutter.project_slug }}/.idea/runConfigurations/Run.xml
generated
Normal file
18
{{ cookiecutter.project_slug }}/.idea/runConfigurations/Run.xml
generated
Normal file
@ -0,0 +1,18 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run" type="Python.FastAPI">
|
||||
<option name="file" value="$PROJECT_DIR$/service/api/main.py" />
|
||||
<module name="{{ cookiecutter.project_slug }}" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<option name="SDK_HOME" value="$PROJECT_DIR$/venv/bin/python" />
|
||||
<option name="SDK_NAME" value="Python 3 ({{ cookiecutter.project_slug }})" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="false" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="launchJavascriptDebuger" value="false" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
26
{{ cookiecutter.project_slug }}/.idea/runConfigurations/Run_Migrations.xml
generated
Normal file
26
{{ cookiecutter.project_slug }}/.idea/runConfigurations/Run_Migrations.xml
generated
Normal file
@ -0,0 +1,26 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Migrations" type="PythonConfigurationType" factoryName="Python">
|
||||
<module name="{{ cookiecutter.project_slug }}" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="SDK_NAME" value="Python 3 ({{ cookiecutter.project_slug }})" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="false" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/venv/bin/aerich" />
|
||||
<option name="PARAMETERS" value="upgrade" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
6
{{ cookiecutter.project_slug }}/.idea/vcs.xml
generated
Normal file
6
{{ cookiecutter.project_slug }}/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
14
{{ cookiecutter.project_slug }}/.idea/{{ cookiecutter.project_slug }}.iml
generated
Normal file
14
{{ cookiecutter.project_slug }}/.idea/{{ cookiecutter.project_slug }}.iml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.12 (project_slug)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
<option name="format" value="PLAIN" />
|
||||
<option name="myDocStringFormat" value="Plain" />
|
||||
</component>
|
||||
</module>
|
@ -1,13 +1,13 @@
|
||||
FROM python:3.12-alpine as python
|
||||
FROM python:3.12-alpine AS python
|
||||
WORKDIR /app
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
ARG ENVIRONMENT=local
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV TZ="Europe/Riga"
|
||||
|
||||
COPY requirements /app/requirements
|
||||
RUN apk add libpq \
|
||||
poppler-utils zlib-dev \
|
||||
# curl \
|
||||
&& pip install --no-cache-dir --upgrade -r requirements/production.txt \
|
||||
&& pip install --no-cache-dir --upgrade -r requirements/${ENVIRONMENT}.txt \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
COPY entrypoint.sh /entrypoint
|
||||
@ -19,4 +19,4 @@ RUN chmod +x /entrypoint \
|
||||
EXPOSE 5000
|
||||
|
||||
ENTRYPOINT ["/entrypoint"]
|
||||
CMD ["uvicorn", "--workers", "2", "--proxy-headers", "--host", "0.0.0.0", "--port", "5000", "--forwarded-allow-ips=*", "service.main:app"]
|
||||
CMD ["uvicorn", "--workers", "2", "--proxy-headers", "--host", "0.0.0.0", "--port", "5000", "--forwarded-allow-ips=*", "service.api.main:app"]
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
# `SERVICE_DATABASE_URL`
|
||||
|
||||
*Optional*, default value: `psql://{{ cookiecutter.project_slug }}:{{ cookiecutter.project_slug }}@postgres:5432/{{ cookiecutter.project_slug }}`
|
||||
*Optional*, default value: `asyncpg://{{ cookiecutter.project_slug }}:{{ cookiecutter.project_slug }}@postgres:5432/{{ cookiecutter.project_slug }}`
|
||||
|
||||
# `SERVICE_TIMEZONE`
|
||||
|
||||
|
37
{{ cookiecutter.project_slug }}/README.md
Normal file
37
{{ cookiecutter.project_slug }}/README.md
Normal file
@ -0,0 +1,37 @@
|
||||
# Welcome to {{ cookiecutter.project_name }}
|
||||
|
||||
## Setup
|
||||
### 1. Install dependencies
|
||||
#### Local virtual environment
|
||||
```shell
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements/local.txt
|
||||
```
|
||||
|
||||
#### Docker image
|
||||
```shell
|
||||
docker build -f Dockerfile --tag {{ cookiecutter.project_slug }} .
|
||||
```
|
||||
|
||||
### 2. Initial setup
|
||||
#### Environment variables
|
||||
Environment variables for the project are being read from the env.yml file:
|
||||
- Copy example yml:
|
||||
`cp envs.example.yml envs.yml`
|
||||
- Adjust values as necessary
|
||||
|
||||
#### Initialize database
|
||||
```shell
|
||||
aerich init-db
|
||||
```
|
||||
|
||||
#### Migrate database
|
||||
```shell
|
||||
aerich upgrade
|
||||
```
|
||||
|
||||
#### Create new database migration
|
||||
```shell
|
||||
aerich migrate
|
||||
```
|
@ -7,13 +7,13 @@ service:
|
||||
token_expiration_days: 28
|
||||
cors_origins:
|
||||
- "http://localhost:5000"
|
||||
- "https://example.com"
|
||||
- "https://{{ cookiecutter.project_slug }}.xyz"
|
||||
|
||||
environment: "local"
|
||||
log_level: "DEBUG"
|
||||
|
||||
redis_url: "redis://redis:6379"
|
||||
database_url: "psql://{{ cookiecutter.project_slug }}:{{ cookiecutter.project_slug }}@postgres:5432/{{ cookiecutter.project_slug }}"
|
||||
database_url: "asyncpg://{{ cookiecutter.project_slug }}:{{ cookiecutter.project_slug }}@postgres:5432/{{ cookiecutter.project_slug }}"
|
||||
|
||||
timezone: "UTC"
|
||||
sentry_url: null
|
||||
|
@ -1,26 +1,26 @@
|
||||
fastapi==0.115.5 # https://github.com/tiangolo/fastapi
|
||||
uvicorn==0.32.1 # https://pypi.org/project/uvicorn/
|
||||
fastapi==0.115.12 # https://github.com/tiangolo/fastapi
|
||||
uvicorn==0.34.0 # https://pypi.org/project/uvicorn/
|
||||
|
||||
pydantic[email]==2.10.2 # https://github.com/pydantic/pydantic
|
||||
pydantic-settings[yaml]==2.6.1 # https://github.com/pydantic/pydantic-settings/
|
||||
pydantic[email]==2.11.2 # https://github.com/pydantic/pydantic
|
||||
pydantic-settings[yaml]==2.8.1 # https://github.com/pydantic/pydantic-settings/
|
||||
|
||||
tortoise-orm[accel,asyncpg]==0.22.1 # https://pypi.org/project/tortoise-orm/
|
||||
aerich==0.7.2 # https://pypi.org/project/aerich/
|
||||
tortoise-orm[accel,asyncpg]==0.24.2 # https://pypi.org/project/tortoise-orm/
|
||||
aerich==0.8.2 # https://pypi.org/project/aerich/
|
||||
|
||||
setech==1.4.2 # https://pypi.org/project/setech/
|
||||
|
||||
python-multipart==0.0.18 # https://pypi.org/project/python-multipart/
|
||||
python-multipart==0.0.20 # https://pypi.org/project/python-multipart/
|
||||
email-validator==2.2.0 # https://pypi.org/project/email-validator/
|
||||
|
||||
|
||||
tenacity==9.0.0 # https://pypi.org/project/tenacity/
|
||||
pydantic==2.10.2 # https://pypi.org/project/pydantic/
|
||||
tenacity==9.1.2 # https://pypi.org/project/tenacity/
|
||||
pydantic==2.11.2 # https://pypi.org/project/pydantic/
|
||||
#emails==0.6 # https://pypi.org/project/emails/
|
||||
|
||||
python-jose[cryptography]==3.3 # https://pypi.org/project/python-jose/
|
||||
python-jose[cryptography]==3.4.0 # https://pypi.org/project/python-jose/
|
||||
passlib[bcrypt]==1.7.4 # https://pypi.org/project/passlib/
|
||||
bcrypt==4.2.1 # https://pypi.org/project/bcrypt/
|
||||
bcrypt==4.3.0 # https://pypi.org/project/bcrypt/
|
||||
# Pin bcrypt until passlib supports the latest
|
||||
pydantic-settings==2.6.1 # https://pypi.org/project/pydantic-settings/
|
||||
pydantic-settings==2.8.1 # https://pypi.org/project/pydantic-settings/
|
||||
|
||||
asyncio==3.4.3
|
||||
|
@ -1,25 +1,25 @@
|
||||
-r base.txt
|
||||
|
||||
uvicorn[standard]==0.32.1 # https://pypi.org/project/uvicorn/
|
||||
uvicorn[standard]==0.34.0 # https://pypi.org/project/uvicorn/
|
||||
|
||||
black==24.10.0 # https://pypi.org/project/black/
|
||||
isort==5.13.2 # https://pypi.org/project/isort/
|
||||
pur==7.3.2 # https://pypi.org/project/pur/
|
||||
pre-commit==4.0.1 # https://pypi.org/project/pre-commit/
|
||||
flake8==7.1.1
|
||||
black==25.1.0 # https://pypi.org/project/black/
|
||||
isort==6.0.1 # https://pypi.org/project/isort/
|
||||
pur==7.3.3 # https://pypi.org/project/pur/
|
||||
pre-commit==4.2.0 # https://pypi.org/project/pre-commit/
|
||||
flake8==7.2.0
|
||||
|
||||
pytest==8.3.3 # https://pypi.org/project/pytest/
|
||||
coverage==7.6.8 # https://pypi.org/project/coverage/
|
||||
pytest==8.3.5 # https://pypi.org/project/pytest/
|
||||
coverage==7.8.0 # https://pypi.org/project/coverage/
|
||||
|
||||
mypy==1.13.0 # https://pypi.org/project/mypy/
|
||||
types-python-jose==3.3.4.20240106 # https://pypi.org/project/types-python-jose/
|
||||
types-passlib==1.7.7.20240819 # https://pypi.org/project/types-passlib/
|
||||
types-PyYAML==6.0.12.20240917
|
||||
types-Pygments==2.18.0.20240506
|
||||
mypy==1.15.0 # https://pypi.org/project/mypy/
|
||||
types-python-jose==3.4.0.20250224 # https://pypi.org/project/types-python-jose/
|
||||
types-passlib==1.7.7.20250401 # https://pypi.org/project/types-passlib/
|
||||
types-PyYAML==6.0.12.20250402
|
||||
types-Pygments==2.19.0.20250305
|
||||
types-colorama==0.4.15.20240311
|
||||
types-decorator==5.1.8.20240310
|
||||
types-six==1.16.21.20241105
|
||||
types-ujson==5.10.0.20240515
|
||||
types-decorator==5.2.0.20250324
|
||||
types-six==1.17.0.20250403
|
||||
types-ujson==5.10.0.20250326
|
||||
|
||||
settings-doc==4.3.1 # https://github.com/radeklat/settings-doc
|
||||
ipython==8.30.0
|
||||
settings-doc==4.3.2 # https://github.com/radeklat/settings-doc
|
||||
ipython==9.0.2
|
||||
|
@ -1,3 +1,3 @@
|
||||
-r base.txt
|
||||
|
||||
sentry-sdk[fastapi]==2.19.0 # https://pypi.org/project/sentry-sdk/
|
||||
sentry-sdk[fastapi]==2.25.1 # https://pypi.org/project/sentry-sdk/
|
||||
|
@ -24,7 +24,7 @@ class ProjectSettings(ProjectBaseSettings):
|
||||
|
||||
# Background task config
|
||||
redis_url: RedisDsn = Field(RedisDsn(url="redis://redis:6379"))
|
||||
database_url: str = Field("psql://{{ cookiecutter.project_slug }}:{{ cookiecutter.project_slug }}@postgres:5432/{{ cookiecutter.project_slug }}")
|
||||
database_url: str = Field("asyncpg://{{ cookiecutter.project_slug }}:{{ cookiecutter.project_slug }}@postgres:5432/{{ cookiecutter.project_slug }}")
|
||||
|
||||
# Various
|
||||
timezone: str = Field(
|
||||
|
@ -1,9 +1,8 @@
|
||||
from service.api.dependencies import QueryParams
|
||||
from service.core.security import verify_password
|
||||
from service.crud.user.models import UserPublic, UserRegister
|
||||
from service.crud.utils import order_queryset
|
||||
from service.database.models import User
|
||||
from ..utils import order_queryset
|
||||
|
||||
from ...api.dependencies import QueryParams
|
||||
from .models import UserPublic, UserRegister
|
||||
|
||||
|
||||
async def authenticate(*, username: str, password: str) -> User | None:
|
||||
|
@ -4,5 +4,7 @@ from service.constants.types import PaginationParams
|
||||
|
||||
|
||||
def order_queryset(qs: QuerySet, filters: PaginationParams, default: str) -> QuerySet:
|
||||
ordering = [f for f in filters.order.split(",") if f.split("-")[-1] in qs.fields]
|
||||
ordering = None
|
||||
if filters.order:
|
||||
ordering = [f for f in filters.order.split(",") if f.split("-")[-1] in qs.fields]
|
||||
return qs.order_by(*(ordering or (default, )))
|
||||
|
Loading…
x
Reference in New Issue
Block a user