common-python-tasks 0.0.2__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {common_python_tasks-0.0.2 → common_python_tasks-0.0.3}/LICENSE +1 -1
- common_python_tasks-0.0.3/PKG-INFO +415 -0
- common_python_tasks-0.0.3/README.md +381 -0
- {common_python_tasks-0.0.2 → common_python_tasks-0.0.3}/pyproject.toml +5 -4
- {common_python_tasks-0.0.2 → common_python_tasks-0.0.3}/src/common_python_tasks/__init__.py +2 -4
- common_python_tasks-0.0.3/src/common_python_tasks/__main__.py +35 -0
- common_python_tasks-0.0.3/src/common_python_tasks/compose.py +625 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/dockerfile_extensions/.gitkeep +0 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/fastapi/alembic.ini.j2 +52 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/fastapi/compose-base.yml.j2 +40 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/fastapi/compose-db-debug.yml.j2 +45 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/fastapi/compose-db.yml.j2 +80 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/fastapi/compose-debug.yml.j2 +30 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/generic/.pytest_cache/v/cache/lastfailed +4 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/generic/.pytest_cache/v/cache/nodeids +227 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/generic/Dockerfile.deps.j2 +17 -0
- common_python_tasks-0.0.3/src/common_python_tasks/data/generic/Dockerfile.j2 +145 -0
- common_python_tasks-0.0.3/src/common_python_tasks/docker.py +454 -0
- common_python_tasks-0.0.3/src/common_python_tasks/env.py +406 -0
- common_python_tasks-0.0.3/src/common_python_tasks/git.py +268 -0
- common_python_tasks-0.0.3/src/common_python_tasks/github.py +515 -0
- common_python_tasks-0.0.3/src/common_python_tasks/project.py +298 -0
- common_python_tasks-0.0.3/src/common_python_tasks/tasks.py +1344 -0
- common_python_tasks-0.0.3/src/common_python_tasks/utils.py +315 -0
- common_python_tasks-0.0.2/PKG-INFO +0 -295
- common_python_tasks-0.0.2/README.md +0 -262
- common_python_tasks-0.0.2/src/common_python_tasks/data/.pytest_cache/v/cache/nodeids +0 -47
- common_python_tasks-0.0.2/src/common_python_tasks/data/Containerfile +0 -76
- common_python_tasks-0.0.2/src/common_python_tasks/tasks.py +0 -849
- {common_python_tasks-0.0.2/src/common_python_tasks/data → common_python_tasks-0.0.3/src/common_python_tasks/data/generic}/.coveragerc +0 -0
- {common_python_tasks-0.0.2/src/common_python_tasks/data → common_python_tasks-0.0.3/src/common_python_tasks/data/generic}/.dockerignore +0 -0
- {common_python_tasks-0.0.2/src/common_python_tasks/data → common_python_tasks-0.0.3/src/common_python_tasks/data/generic}/.flake8 +0 -0
- {common_python_tasks-0.0.2/src/common_python_tasks/data → common_python_tasks-0.0.3/src/common_python_tasks/data/generic}/.isort.cfg +0 -0
- {common_python_tasks-0.0.2/src/common_python_tasks/data → common_python_tasks-0.0.3/src/common_python_tasks/data/generic}/.pytest_cache/.gitignore +0 -0
- {common_python_tasks-0.0.2/src/common_python_tasks/data → common_python_tasks-0.0.3/src/common_python_tasks/data/generic}/.pytest_cache/CACHEDIR.TAG +0 -0
- {common_python_tasks-0.0.2/src/common_python_tasks/data → common_python_tasks-0.0.3/src/common_python_tasks/data/generic}/.pytest_cache/README.md +0 -0
- {common_python_tasks-0.0.2/src/common_python_tasks/data → common_python_tasks-0.0.3/src/common_python_tasks/data/generic}/pytest.ini +0 -0
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: common-python-tasks
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: Opinionated Poe the Poet tasks for Python package development.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Joseph Asbury
|
|
8
|
+
Author-email: ci_sourcerer@yahoo.com
|
|
9
|
+
Requires-Python: >=3.11,<4.0
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
18
|
+
Requires-Dist: autoflake (>=2.3.1,<3.0.0)
|
|
19
|
+
Requires-Dist: black (>=25.11.0,<26.0.0)
|
|
20
|
+
Requires-Dist: dunamai (>=1.25.0,<2.0.0)
|
|
21
|
+
Requires-Dist: flake8 (>=7.3.0,<8.0.0)
|
|
22
|
+
Requires-Dist: git-cliff (>=2.12.0,<3.0.0)
|
|
23
|
+
Requires-Dist: isort (>=7.0.0,<8.0.0)
|
|
24
|
+
Requires-Dist: jinja2 (>=3.1.6,<4.0.0)
|
|
25
|
+
Requires-Dist: poethepoet-tasks (>=0.3.0,<0.4.0)
|
|
26
|
+
Requires-Dist: pytest (>=9.0.1,<10.0.0)
|
|
27
|
+
Requires-Dist: pytest-cov (>=7.0.0,<8.0.0)
|
|
28
|
+
Requires-Dist: tomlkit (>=0.13.3,<0.14.0)
|
|
29
|
+
Project-URL: Homepage, http://github.com/ci-sourcerer/common-python-tasks
|
|
30
|
+
Project-URL: Issues, http://github.com/ci-sourcerer/common-python-tasks/issues
|
|
31
|
+
Project-URL: Source, http://github.com/ci-sourcerer/common-python-tasks.git
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# Common Python Tasks
|
|
35
|
+
|
|
36
|
+
This package is a collection of (very) opinionated [Poe the Poet](https://poethepoet.natn.io/guides/packaged_tasks.html) Python tasks for common Python development workflows.
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
### Automated setup
|
|
41
|
+
|
|
42
|
+
You can add `common-python-tasks` to a new project by using the handy automated installation script.
|
|
43
|
+
|
|
44
|
+
```shell
|
|
45
|
+
curl -sSL https://api.github.com/repos/ci-sourcerer/common-python-tasks/contents/scripts/add-common-python-tasks.sh | jq -r '.content' | base64 -d | TAGS_TO_INCLUDE="format lint test" sh
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This will complete the following steps.
|
|
49
|
+
|
|
50
|
+
1. Add the latest version of `common-python-tasks` to your `pyproject.toml` dependencies
|
|
51
|
+
2. Configure Poe the Poet to include only the tasks with the specified tags
|
|
52
|
+
3. Install the package using Poetry
|
|
53
|
+
|
|
54
|
+
**Always review scripts before running them!** Even though I believe I write good software, it's best practice to verify any script you download from the Internet.
|
|
55
|
+
|
|
56
|
+
### Manual setup
|
|
57
|
+
|
|
58
|
+
1. Add `common-python-tasks` to your `pyproject.toml` and configure Poe the Poet to include the desired tasks
|
|
59
|
+
|
|
60
|
+
```toml
|
|
61
|
+
[project]
|
|
62
|
+
name = "my-awesome-project"
|
|
63
|
+
version = "0.0.2"
|
|
64
|
+
dependencies = [
|
|
65
|
+
"common-python-tasks==0.0.2", # Always pin to a specific version
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
[tool.poe]
|
|
69
|
+
include_script = "common_python_tasks:tasks(include_tags=['format', 'lint', 'test'])" # Include or exclude tasks by tags
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
2. Install the package
|
|
73
|
+
|
|
74
|
+
```shell
|
|
75
|
+
poetry install
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
3. Run tasks
|
|
79
|
+
|
|
80
|
+
```shell
|
|
81
|
+
poe format # Format your code
|
|
82
|
+
poe lint # Check code quality
|
|
83
|
+
poe test # Run tests with coverage
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Available tasks
|
|
87
|
+
|
|
88
|
+
Internal tasks are used by other tasks and are not meant to be run directly.
|
|
89
|
+
|
|
90
|
+
<!-- tasks-table -->
|
|
91
|
+
| Task | Description | Tags |
|
|
92
|
+
| - | - | - |
|
|
93
|
+
| `build` | Build the project and its containers (when `containers` tag is included) | packaging, containers |
|
|
94
|
+
| `build-image` | Build the container image for this project using the Dockerfile template (and configured extensions) | containers, build |
|
|
95
|
+
| `build-package` | Build the package (wheel and sdist) | packaging, build |
|
|
96
|
+
| `bump-version` | Bump the project version, defaulting to an inferred semantic bump from git history | packaging |
|
|
97
|
+
| `changelog` | Print the changelog for the current version based on git history | packaging, release |
|
|
98
|
+
| `clean` | Clean up temporary files and directories | clean |
|
|
99
|
+
| `container-shell` | Run the debug image with an interactive shell | containers, debug |
|
|
100
|
+
| `db-shell` | Open a psql shell to the database container | web, containers, database |
|
|
101
|
+
| `format` | Format code with autoflake, black, and isort | format |
|
|
102
|
+
| `lint` | Lint Python code with autoflake, black, isort, and flake8 | lint |
|
|
103
|
+
| `publish-package` | Publish the package to the PyPI server | packaging |
|
|
104
|
+
| `publish-github-release` | Publish or update a GitHub Release and attach built distribution assets | packaging, release |
|
|
105
|
+
| `push-image` | Push the Docker image to the container registry | containers, packaging, release |
|
|
106
|
+
| `release` | Run package release flow and publish containers when `containers` tag is included. Supports optional `RELEASE_PRE_SCRIPT` and `RELEASE_POST_SCRIPT` hooks. | packaging, release |
|
|
107
|
+
| `reset-db` | Reset the database by deleting the database volume | web, containers, database |
|
|
108
|
+
| `run-container` | Run the Docker image as a container | containers |
|
|
109
|
+
| `run-db-migrations` | Run database migrations | web, containers, database |
|
|
110
|
+
| `stack-down` | Bring down the development stack for the application | web, containers |
|
|
111
|
+
| `stack-up` | Bring up the development stack for the application | web, containers |
|
|
112
|
+
| `test` | Run the test suite with coverage | test |
|
|
113
|
+
<!-- end-tasks-table -->
|
|
114
|
+
|
|
115
|
+
## Docker Compose Development Stacks
|
|
116
|
+
|
|
117
|
+
Some tasks of certain tags provide Docker Compose-based development stacks for running your application with supporting services (databases, caches, etc.). Currently supports FastAPI applications with PostgreSQL.
|
|
118
|
+
|
|
119
|
+
### Configuration
|
|
120
|
+
|
|
121
|
+
#### `COMPOSE_TYPE`
|
|
122
|
+
|
|
123
|
+
Specifies the type of application stack. Currently supported:
|
|
124
|
+
|
|
125
|
+
- `fastapi` - FastAPI application with optional database, Alembic migrations
|
|
126
|
+
|
|
127
|
+
Set via environment variable:
|
|
128
|
+
|
|
129
|
+
```toml
|
|
130
|
+
[tool.poe.env]
|
|
131
|
+
COMPOSE_TYPE = "fastapi"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### `COMPOSE_ADDONS`
|
|
135
|
+
|
|
136
|
+
Colon-separated list of additional services to include. Available addons:
|
|
137
|
+
|
|
138
|
+
- `db` - PostgreSQL database with Alembic migration support and Adminer web UI
|
|
139
|
+
|
|
140
|
+
Example:
|
|
141
|
+
|
|
142
|
+
```toml
|
|
143
|
+
[tool.poe.env]
|
|
144
|
+
COMPOSE_ADDONS = "db"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
For multiple addons (future): `COMPOSE_ADDONS = "db:redis:cache"`
|
|
148
|
+
|
|
149
|
+
### Compose File Customization
|
|
150
|
+
|
|
151
|
+
The compose setup follows this precedence.
|
|
152
|
+
|
|
153
|
+
1. **Environment override** - `COMPOSE_FILE` environment variable with colon-separated paths
|
|
154
|
+
2. **Auto-loaded files** - Based on `COMPOSE_TYPE` and `COMPOSE_ADDONS`:
|
|
155
|
+
- `compose-base.yml` - Core application service
|
|
156
|
+
- `compose-{addon}.yml` - For each addon (e.g., `compose-db.yml`)
|
|
157
|
+
- `compose-debug.yml` - When `--debug` flag is used
|
|
158
|
+
- `compose-{addon}-debug.yml` - Debug overlays for addons
|
|
159
|
+
3. **Additional overlays** - `COMPOSE_OVERLAY_FILES` with colon-separated paths
|
|
160
|
+
|
|
161
|
+
You can provide local compose files or let the tasks use bundled templates.
|
|
162
|
+
|
|
163
|
+
### `fastapi`
|
|
164
|
+
|
|
165
|
+
The `fastapi` stack includes a service for your FastAPI application. It uses the standard Dockerfile included with this package.
|
|
166
|
+
|
|
167
|
+
#### Environment variables
|
|
168
|
+
|
|
169
|
+
- `API_PORT` - Port for the API server (default: `8080`)
|
|
170
|
+
- `SECRET_KEY` - Application secret key (auto-generated and stored in `.env` if not set)
|
|
171
|
+
- `ENVIRONMENT` - Environment name like `development` or `production` (default: `production`)
|
|
172
|
+
- `DEBUG_PORT` - Port for the Python debugger when using `--debug` (default: `5678`)
|
|
173
|
+
- `DB_PORT` - PostgreSQL port (default: `5432`)
|
|
174
|
+
- `DB_USER` - Database user (default: package name)
|
|
175
|
+
- `DB_BASE` - Database name (default: package name)
|
|
176
|
+
- `DB_PASS` - Database password (auto-generated and stored in `.env` if not set)
|
|
177
|
+
- `POSTGRES_VERSION` - PostgreSQL Docker image version (default: `17`)
|
|
178
|
+
- `ADMINER_PORT` - Adminer web UI port (default: `8081`)
|
|
179
|
+
|
|
180
|
+
## How it works
|
|
181
|
+
|
|
182
|
+
### Prerequisites
|
|
183
|
+
|
|
184
|
+
Your project must meet the following requirements.
|
|
185
|
+
|
|
186
|
+
- Use Poetry for dependency management
|
|
187
|
+
- Have a `pyproject.toml` file at the root
|
|
188
|
+
- Have a package name (automatically inferred from `project.name` in `pyproject.toml` or set via `PACKAGE_NAME` environment variable)
|
|
189
|
+
|
|
190
|
+
### Configuration precedence
|
|
191
|
+
|
|
192
|
+
Tasks that need configuration files (`pytest`, `coverage`, `flake8`, `isort`) follow this order of precedence.
|
|
193
|
+
|
|
194
|
+
1. **`pyproject.toml` sections** - `[tool.pytest]`, `[tool.coverage]`, `[tool.isort]` take priority
|
|
195
|
+
2. **Environment variables** - Override config paths (see [Environment Variables](#environment-variables))
|
|
196
|
+
3. **Local config files** - `pytest.ini`, `.coveragerc`, `.flake8`, `.isort.cfg` in project root
|
|
197
|
+
4. **Bundled defaults** - Sensible defaults included with this package, found in the [`src/common_python_tasks/data`](src/common_python_tasks/data) directory
|
|
198
|
+
|
|
199
|
+
You can start with zero configuration and customize as needed.
|
|
200
|
+
|
|
201
|
+
### Environment variables
|
|
202
|
+
|
|
203
|
+
#### Configuration files
|
|
204
|
+
|
|
205
|
+
The following environment variables configure the paths to configuration files.
|
|
206
|
+
|
|
207
|
+
- `PYTEST_CONFIG` specifies the path to the pytest configuration file
|
|
208
|
+
- `COVERAGE_RCFILE` specifies the path to the coverage configuration file
|
|
209
|
+
- `FLAKE8_CONFIG` specifies the path to the flake8 configuration file
|
|
210
|
+
- `ISORT_CONFIG` specifies the path to the isort configuration file
|
|
211
|
+
|
|
212
|
+
#### Package/Container settings
|
|
213
|
+
|
|
214
|
+
The following environment variables configure package and container behavior.
|
|
215
|
+
|
|
216
|
+
- `PACKAGE_NAME` overrides the package name (default is from `pyproject.toml`)
|
|
217
|
+
- `POETRY_VERSION` overrides the Poetry version for container builds
|
|
218
|
+
- `DOCKERHUB_USERNAME` specifies the Docker Hub username for image tagging (default is current local user)
|
|
219
|
+
- `CONTAINER_REGISTRY_URL` specifies the registry URL (default is `docker.io/{username}`)
|
|
220
|
+
- `CONTAINER_BUILD_ARGS` provides additional Docker build arguments in `KEY=VALUE:OTHER=VALUE` format
|
|
221
|
+
- `CONTAINER_EXTENSION_FILES` specifies colon-delimited local extension Dockerfile paths to include in the rendered build.
|
|
222
|
+
- `CONTAINER_EXTENSIONS` specifies colon-delimited extension bundle names or parameterized bundle values to include in the rendered build.
|
|
223
|
+
- `CONTAINER_ENV` provides colon-delimited `KEY=VALUE` declarations to inject into the builder stage of the rendered Dockerfile.
|
|
224
|
+
- `.containerenv` can also supply the same declarations from a file in the project root. It is the fallback source when neither `container_envfile` nor `CONTAINER_ENV` is provided.
|
|
225
|
+
- `CONTAINER_PRUNE_KEEP` controls image pruning after builds (`-1` keep all, `0` keep latest only, `N` keep latest + `N` previous)
|
|
226
|
+
- `CUSTOM_IMAGE_ENTRYPOINT` specifies a custom entrypoint script name for containers
|
|
227
|
+
- `CONTAINER_DEPS_CONTENT` supplies inline Dockerfile instructions for a dependency image that installs artifacts into `/tmp/deps`
|
|
228
|
+
- `CONTAINER_DEPS_FILE` points to one or more explicit Dockerfiles to build the dependency image. It may be a colon-delimited list of file paths and is used only when `CONTAINER_DEPS_CONTENT` is unset.
|
|
229
|
+
- `CONTAINER_DEPS_MAPPINGS` maps copied dependency names from `/tmp/deps` into destination paths, as whitespace-separated `name:/target/path` entries. This is only used when `CONTAINER_DEPS_MOVE_SCRIPT` or `CONTAINER_DEPS_MOVE_SCRIPT_PATH` is not set.
|
|
230
|
+
- `CONTAINER_DEPS_MOVE_SCRIPT` supplies a raw executable script to run after `/tmp/deps` is copied into the image. The script is written to `/tmp/container-deps-move-script` and executed with its own shebang.
|
|
231
|
+
- `CONTAINER_DEPS_MOVE_SCRIPT_PATH` supplies a host path to a script file to run after `/tmp/deps` is copied into the image. This path takes precedence over `CONTAINER_DEPS_MOVE_SCRIPT` when both are set.
|
|
232
|
+
- `GITHUB_RELEASE_ASSETS` colon-separated list of file paths or glob patterns to attach to the GitHub Release (default: `dist/*`)
|
|
233
|
+
- `SKIP_GITHUB_RELEASE` truthy value to skip GitHub Release publication.
|
|
234
|
+
- `GITHUB_TOKEN` or `GH_TOKEN` GitHub authentication token used to publish releases and upload assets.
|
|
235
|
+
- `GITHUB_REPOSITORY` optional override for the repository slug used when publishing a GitHub Release.
|
|
236
|
+
- `GITHUB_API_URL` and `GITHUB_SERVER_URL` configure the GitHub API host for GitHub Enterprise environments.
|
|
237
|
+
- `GITHUB_RELEASE_TAG` optional tag name to publish for the GitHub Release.
|
|
238
|
+
- `GITHUB_RELEASE_NAME` optional release title to use for the GitHub Release.
|
|
239
|
+
- `GITHUB_RELEASE_BODY` optional release body text to use for the GitHub Release.
|
|
240
|
+
- `RELEASE_PRE_SCRIPT` optional shell command to run before the release steps.
|
|
241
|
+
- `RELEASE_POST_SCRIPT` optional shell command to run after the release completes.
|
|
242
|
+
- Hook commands receive the following env vars: `RELEASE_TAG`, `RELEASE_VERSION`, `RELEASE_STAGE`, `RELEASE_COMPONENT`, and `RELEASE_DRY_RUN`.
|
|
243
|
+
|
|
244
|
+
#### Docker Compose settings
|
|
245
|
+
|
|
246
|
+
The following environment variables configure Docker Compose stacks (when using the `web` tag).
|
|
247
|
+
|
|
248
|
+
- `COMPOSE_TYPE` specifies the type of application stack (e.g., `fastapi`)
|
|
249
|
+
- `COMPOSE_ADDONS` colon-separated list of services to include (e.g., `db` for database)
|
|
250
|
+
- `COMPOSE_FILE` overrides all compose files with colon-separated paths
|
|
251
|
+
- `COMPOSE_OVERLAY_FILES` additional compose files to merge (colon-separated paths)
|
|
252
|
+
- `API_PORT` port for the API server (default: `8080`)
|
|
253
|
+
- `SECRET_KEY` application secret key (auto-generated if not set)
|
|
254
|
+
- `ENVIRONMENT` environment name (default: `production`)
|
|
255
|
+
- `DEBUG_PORT` port for Python debugger in debug mode (default: `5678`)
|
|
256
|
+
- `DB_PORT` PostgreSQL port (default: `5432`)
|
|
257
|
+
- `DB_USER` database user (default: package name)
|
|
258
|
+
- `DB_BASE` database name (default: package name)
|
|
259
|
+
- `DB_PASS` database password (auto-generated if not set)
|
|
260
|
+
- `POSTGRES_VERSION` PostgreSQL version (default: `17`)
|
|
261
|
+
- `ADMINER_PORT` Adminer web UI port (default: `8081`)
|
|
262
|
+
|
|
263
|
+
#### Debugging
|
|
264
|
+
|
|
265
|
+
The following environment variable enables debugging output.
|
|
266
|
+
|
|
267
|
+
- `COMMON_PYTHON_TASKS_LOG_LEVEL` should be set to `DEBUG` to see detailed configuration resolution
|
|
268
|
+
|
|
269
|
+
### Usage examples
|
|
270
|
+
|
|
271
|
+
You can include or exclude tasks by tags in your `pyproject.toml`
|
|
272
|
+
|
|
273
|
+
#### Minimal setup
|
|
274
|
+
|
|
275
|
+
```toml
|
|
276
|
+
[project]
|
|
277
|
+
name = "simple-cli-tool"
|
|
278
|
+
version = "0.0.1"
|
|
279
|
+
dependencies = ["common-python-tasks==0.0.1"]
|
|
280
|
+
|
|
281
|
+
[tool.poe]
|
|
282
|
+
include_script = "common_python_tasks:tasks(include_tags=['format', 'lint'])"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Available tasks: `format`, `lint`.
|
|
286
|
+
|
|
287
|
+
#### Container-based project
|
|
288
|
+
|
|
289
|
+
```toml
|
|
290
|
+
[project]
|
|
291
|
+
name = "containerized-app"
|
|
292
|
+
version = "0.0.1"
|
|
293
|
+
dependencies = ["common-python-tasks==0.0.1"]
|
|
294
|
+
|
|
295
|
+
[tool.poe]
|
|
296
|
+
include_script = "common_python_tasks:tasks(include_tags=['format', 'lint', 'test', 'containers'])"
|
|
297
|
+
|
|
298
|
+
[tool.poe.env]
|
|
299
|
+
DOCKERHUB_USERNAME = "myusername"
|
|
300
|
+
PACKAGE_NAME = "containerized-app"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Available tasks: All tasks including `build-image` and `push-image`.
|
|
304
|
+
|
|
305
|
+
#### Custom pytest configuration
|
|
306
|
+
|
|
307
|
+
```toml
|
|
308
|
+
[project]
|
|
309
|
+
name = "custom-test-setup"
|
|
310
|
+
dependencies = ["common-python-tasks==0.0.1"]
|
|
311
|
+
dynamic = ["version"]
|
|
312
|
+
|
|
313
|
+
[tool.poe]
|
|
314
|
+
include_script = "common_python_tasks:tasks(include_tags=['test'])"
|
|
315
|
+
|
|
316
|
+
[tool.pytest.ini_options]
|
|
317
|
+
testpaths = ["tests", "integration"]
|
|
318
|
+
addopts = "-ra"
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
The `test` task will automatically use your `[tool.pytest.ini_options]` configuration.
|
|
322
|
+
|
|
323
|
+
## Troubleshooting
|
|
324
|
+
|
|
325
|
+
### Tasks not showing up with `poe --help`
|
|
326
|
+
|
|
327
|
+
Check your `[tool.poe]` configuration in `pyproject.toml`. Make sure you're using `include_script`, not `includes`.
|
|
328
|
+
|
|
329
|
+
```toml
|
|
330
|
+
# Correct
|
|
331
|
+
[tool.poe]
|
|
332
|
+
include_script = "common_python_tasks:tasks(exclude_tags=['internal'])"
|
|
333
|
+
|
|
334
|
+
# Incorrect
|
|
335
|
+
[tool.poe]
|
|
336
|
+
includes = "common_python_tasks:tasks"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Version bump fails with "no changes since last tag"
|
|
340
|
+
|
|
341
|
+
This is expected behavior. The `bump-version` task requires commits between the last tag and HEAD. You can resolve this in one of the following ways.
|
|
342
|
+
|
|
343
|
+
- Make changes and commit them first
|
|
344
|
+
- Delete the old tag (for example, `git tag -d v0.0.1`). This is not recommended. Versions should be immutable, and if you need to fix something, you should create a new patch version instead. Rarely do you want to pass off new code as an old version
|
|
345
|
+
|
|
346
|
+
### Config files not being used
|
|
347
|
+
|
|
348
|
+
Check the configuration precedence (see [How it works](#how-it-works)). Use debug logging to see which config is selected.
|
|
349
|
+
|
|
350
|
+
### GitHub Release assets not uploading
|
|
351
|
+
|
|
352
|
+
If your release task does not attach assets, confirm `dist/` contains the built wheels and sdists. You can override the default asset selection using `GITHUB_RELEASE_ASSETS`, for example:
|
|
353
|
+
|
|
354
|
+
```shell
|
|
355
|
+
GITHUB_RELEASE_ASSETS="dist/*.whl:dist/*.tar.gz" poe publish-github-release
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
```shell
|
|
359
|
+
COMMON_PYTHON_TASKS_LOG_LEVEL=DEBUG poe test
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Container build fails with "unable to find package"
|
|
363
|
+
|
|
364
|
+
Make sure your `pyproject.toml` contains the following.
|
|
365
|
+
|
|
366
|
+
- A correct package name in `[project]`
|
|
367
|
+
- A package location defined with this configuration: `[tool.poetry] packages = [{ include = "your_package", from = "src" }]`
|
|
368
|
+
|
|
369
|
+
### Stack fails to start or services won't connect
|
|
370
|
+
|
|
371
|
+
If `stack-up` builds successfully but services can't connect:
|
|
372
|
+
|
|
373
|
+
- Check that required environment variables are set (`COMPOSE_TYPE` at minimum)
|
|
374
|
+
- Verify ports aren't already in use (defaults: 8080 for API, 5432 for database, 8081 for Adminer)
|
|
375
|
+
- Check Docker daemon is running: `docker info`
|
|
376
|
+
- View service logs: `docker-compose logs` in your project directory
|
|
377
|
+
|
|
378
|
+
### Database migrations fail
|
|
379
|
+
|
|
380
|
+
If `run-db-migrations` fails:
|
|
381
|
+
|
|
382
|
+
- Ensure the `db` addon is included: `COMPOSE_ADDONS=db`
|
|
383
|
+
- Check that your project has Alembic configured with migrations in the expected location
|
|
384
|
+
- Verify database credentials in `.env` match your Alembic configuration
|
|
385
|
+
- Manually inspect the database: `poe db-shell`
|
|
386
|
+
|
|
387
|
+
### Secrets not being generated
|
|
388
|
+
|
|
389
|
+
If `SECRET_KEY` or `DB_PASS` aren't auto-generated:
|
|
390
|
+
|
|
391
|
+
- Ensure `.env` file is writable in your project root
|
|
392
|
+
- Check file permissions: `ls -la .env`
|
|
393
|
+
- Generate manually: `python -c "import secrets; print(secrets.token_hex(32))"`
|
|
394
|
+
|
|
395
|
+
## Design choices
|
|
396
|
+
|
|
397
|
+
### Dockerfile (see [src/common_python_tasks/data/Dockerfile](src/common_python_tasks/data/Dockerfile))
|
|
398
|
+
|
|
399
|
+
The standard Python Dockerfile incorporates several intentional design choices.
|
|
400
|
+
|
|
401
|
+
- Multi-stage build: The build stage installs Poetry and builds a wheel while the runtime stage installs only the wheel to keep the final image slim and reproducible
|
|
402
|
+
- Pip and Poetry cache mounts speed up iterative builds without bloating the final image
|
|
403
|
+
- Explicit inputs through build args (`PYTHON_VERSION`, `POETRY_VERSION`, `PACKAGE_NAME`, `AUTHORS`, `GIT_COMMIT`, `CUSTOM_ENTRYPOINT`) make image metadata and behavior predictable and auditable
|
|
404
|
+
- Optional debug stage exports and installs the `debug` dependency group only when present without failing otherwise and is not part of the default final image
|
|
405
|
+
- Stable package path creates symlinks to the installed package so entrypoints and consumers have a consistent `/pkg` and `/_$PACKAGE_NAME` path regardless of wheel layout, which ensures that the package can be reliably imported and executed from a known location, and allows for the less common use case of reading files directly from the package path
|
|
406
|
+
- Safe entrypoint selection means the default entrypoint resolves the console script matching the package name while `CUSTOM_ENTRYPOINT` allows overriding at build time while keeping runtime behavior predictable
|
|
407
|
+
- Minimal final image uses the slim Python base by default, cleans wheel artifacts and caches, and sets `runtime` as the explicit final target so the debug stage is opt-in
|
|
408
|
+
|
|
409
|
+
## Notes
|
|
410
|
+
|
|
411
|
+
- This project dogfoods itself - it uses `common-python-tasks` for its own development
|
|
412
|
+
- `RELEASE_PRE_SCRIPT` and `RELEASE_POST_SCRIPT` hooks may not be necessary for most users, as this package promotes the use of `poetry-dynamic-versioning` and `git-cliff` to automate versioning and changelog generation based on git history. However, one advanced use case for the `RELEASE_PRE_SCRIPT` hook is to edit a file before release, such as a README that references the current stable version number. This allows you to keep the README up to date with the latest version without hardcoding it.
|
|
413
|
+
- Contributions welcome! Open an issue/discussion to discuss changes before submitting a PR. I do not claim to have all the answers, and you can help determine the future of low-code solutions for Python. I am very interested in your feedback as I don't want to work in a vacuum
|
|
414
|
+
- Alpha status: Expect breaking changes between minor versions until 1.0.0
|
|
415
|
+
|