rra-tools 1.0.0__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.
- rra_tools-1.0.0/LICENSE +28 -0
- rra_tools-1.0.0/PKG-INFO +428 -0
- rra_tools-1.0.0/README.md +397 -0
- rra_tools-1.0.0/pyproject.toml +140 -0
- rra_tools-1.0.0/src/rra_tools/__init__.py +0 -0
- rra_tools-1.0.0/src/rra_tools/cli_tools/__init__.py +27 -0
- rra_tools-1.0.0/src/rra_tools/cli_tools/exceptions.py +38 -0
- rra_tools-1.0.0/src/rra_tools/cli_tools/importers.py +10 -0
- rra_tools-1.0.0/src/rra_tools/cli_tools/options.py +87 -0
- rra_tools-1.0.0/src/rra_tools/jobmon.py +150 -0
- rra_tools-1.0.0/src/rra_tools/logging/__init__.py +15 -0
- rra_tools-1.0.0/src/rra_tools/logging/config.py +77 -0
- rra_tools-1.0.0/src/rra_tools/logging/performance.py +141 -0
- rra_tools-1.0.0/src/rra_tools/logging/protocol.py +17 -0
- rra_tools-1.0.0/src/rra_tools/parallel.py +98 -0
- rra_tools-1.0.0/src/rra_tools/py.typed +0 -0
- rra_tools-1.0.0/src/rra_tools/shell_tools.py +110 -0
- rra_tools-1.0.0/src/rra_tools/translate.py +79 -0
rra_tools-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023, James Collins <collijk@uw.edu>
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
rra_tools-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: rra-tools
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Common utilities for IHME Rapid Response team pipelines.
|
|
5
|
+
Home-page: https://collijk.github.io/rra-tools
|
|
6
|
+
License: BSD-3-Clause
|
|
7
|
+
Author: James Collins
|
|
8
|
+
Author-email: collijk@uw.edu
|
|
9
|
+
Requires-Python: >=3.10,<4.0
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Dist: click
|
|
22
|
+
Requires-Dist: deep-translator (>=1.11.4,<2.0.0)
|
|
23
|
+
Requires-Dist: loguru (>=0.7.2,<0.8.0)
|
|
24
|
+
Requires-Dist: pandas (>=2.2.2,<3.0.0)
|
|
25
|
+
Requires-Dist: pathos (>=0.3.2,<0.4.0)
|
|
26
|
+
Requires-Dist: tqdm (>=4.66.4,<5.0.0)
|
|
27
|
+
Project-URL: Documentation, https://collijk.github.io/rra-tools
|
|
28
|
+
Project-URL: Repository, https://github.com/collijk/rra-tools
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# RRA Tools
|
|
32
|
+
|
|
33
|
+
[](https://pypi.python.org/pypi/rra-tools/)
|
|
34
|
+
[](https://pypi.python.org/pypi/rra-tools/)
|
|
35
|
+
[](https://pypi.python.org/pypi/rra-tools/)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
**Documentation**: [https://collijk.github.io/rra-tools](https://collijk.github.io/rra-tools)
|
|
40
|
+
|
|
41
|
+
**Source Code**: [https://github.com/collijk/rra-tools](https://github.com/collijk/rra-tools)
|
|
42
|
+
|
|
43
|
+
**PyPI**: [https://pypi.org/project/rra-tools/](https://pypi.org/project/rra-tools/)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
Common utilities for IHME Rapid Response team pipelines.
|
|
48
|
+
|
|
49
|
+
### CLI Tools
|
|
50
|
+
|
|
51
|
+
The provided cli tools break down into three categories.
|
|
52
|
+
|
|
53
|
+
#### Exception handling
|
|
54
|
+
|
|
55
|
+
The `cli_tools` subpackage provides a `handle_exceptions` wrapper that can be used to
|
|
56
|
+
wrap functions that may raise exceptions and drop into a pdb shell when an exception is
|
|
57
|
+
raised. This is useful for debugging functions that are failing in a pipeline.
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from rra_tools.cli_tools import handle_exceptions
|
|
61
|
+
from loguru import logger
|
|
62
|
+
|
|
63
|
+
def my_task():
|
|
64
|
+
...
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
runner = handle_exceptions(my_task, logger, with_debugger=True)
|
|
69
|
+
runner()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Dynamic module import
|
|
73
|
+
|
|
74
|
+
The `cli_tools` subpackage provides a `load_module_from_info` function that can be used
|
|
75
|
+
to dynamically import a module. This is a useful pattern for creating a CLI that can
|
|
76
|
+
dynamically add new commands and subcommands based on subpackage structure.
|
|
77
|
+
|
|
78
|
+
TODO: Usage example
|
|
79
|
+
|
|
80
|
+
#### Click options
|
|
81
|
+
|
|
82
|
+
The `cli_tools` subpackage provides several click options that can be used to create
|
|
83
|
+
CLI commands with common options.
|
|
84
|
+
|
|
85
|
+
- `with_verbose` - Add a `--verbose`, `-v` option to the command to increase the log
|
|
86
|
+
verbosity
|
|
87
|
+
- `with_debugger` - Add a `--pdb` option to the command to drop into a pdb shell on
|
|
88
|
+
exception
|
|
89
|
+
- `with_input_directory` - Add a parameterizeable `--{dir-name}-dir` option to the
|
|
90
|
+
command to specify an input directory.
|
|
91
|
+
- `with_output_directory` - Add a `--output-dir`, `-o` option to the command to
|
|
92
|
+
specify an output directory.
|
|
93
|
+
- `with_num_cores` - Add a `--num-cores`, `-c` option to the command to specify the
|
|
94
|
+
number of cores to use for parallel processing.
|
|
95
|
+
- `with_queue` - Add a `--queue`, `-q` option to the command to specify a slurm queue
|
|
96
|
+
to run jobs on.
|
|
97
|
+
- `with_progress_bar` - Add a `--progress-bar`, `--pb` option to the command to
|
|
98
|
+
display a progress bar for long-running tasks.
|
|
99
|
+
- `with_dry_run` - Add a `--dry-run`, `-n` option to the command to run the command
|
|
100
|
+
without actually executing the task.
|
|
101
|
+
|
|
102
|
+
These options do not provide implementations for the options, but rather provide a
|
|
103
|
+
standard interface for adding these options to a command to ensure consistency across
|
|
104
|
+
commands. Several of these options are meant to be used with other tools provided
|
|
105
|
+
in this package like exception handling, logging, and parallel processing.
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
import click
|
|
109
|
+
from loguru import logger
|
|
110
|
+
|
|
111
|
+
from rra_tools.cli_tools import (
|
|
112
|
+
with_verbose,
|
|
113
|
+
with_debugger,
|
|
114
|
+
with_output_directory,
|
|
115
|
+
handle_exceptions,
|
|
116
|
+
)
|
|
117
|
+
from rra_tools.logging import configure_logging_to_terminal
|
|
118
|
+
|
|
119
|
+
def my_task_main(output_dir: str):
|
|
120
|
+
...
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@click.command()
|
|
124
|
+
@with_output_directory("/path/to/default/output")
|
|
125
|
+
@with_verbose()
|
|
126
|
+
@with_debugger()
|
|
127
|
+
def my_task(output_dir: str, verbose: int, debugger: bool):
|
|
128
|
+
configure_logging_to_terminal(verbose)
|
|
129
|
+
runner = handle_exceptions(my_task_main, logger, with_debugger=debugger)
|
|
130
|
+
runner(output_dir)
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Logging
|
|
135
|
+
|
|
136
|
+
The `logging` subpackage provides a number of utilities for configuring loggers
|
|
137
|
+
and for performance logging. This package is built on top of the `loguru` package,
|
|
138
|
+
which provides a more flexible and powerful logging interface than the standard
|
|
139
|
+
library `logging` package.
|
|
140
|
+
|
|
141
|
+
#### Configuration
|
|
142
|
+
|
|
143
|
+
There are three main functions for configuring loggers:
|
|
144
|
+
|
|
145
|
+
- `configure_logging_to_terminal` - Configure a logger to log to the terminal
|
|
146
|
+
- `configure_logging_to_file` - Configure a logger to log to a file
|
|
147
|
+
- `add_logging_sink` - A generic function to add a sink to a logger
|
|
148
|
+
|
|
149
|
+
The first two options are convenience functions that set up a logger with a standard
|
|
150
|
+
configuration. The third option is more flexible and can be used to add additional
|
|
151
|
+
sinks to a logger.
|
|
152
|
+
|
|
153
|
+
#### Performance Logging
|
|
154
|
+
|
|
155
|
+
The `logging` subpackage provides a `task_performance_logger` that is a drop-in
|
|
156
|
+
replacement for the `loguru` logger that logs the time taken to run a task.
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from rra_tools.logging import task_performance_logger as logger
|
|
160
|
+
|
|
161
|
+
def my_task():
|
|
162
|
+
logger.debug("Loading training data", context="load_data")
|
|
163
|
+
# Load the data
|
|
164
|
+
|
|
165
|
+
logger.debug("Training model", context="train_model")
|
|
166
|
+
# Train the model
|
|
167
|
+
|
|
168
|
+
# Using the same context for logging will accumulate time
|
|
169
|
+
# spent in that context across both usages.
|
|
170
|
+
logger.debub("Loading inference_data", context="load_data")
|
|
171
|
+
# Load the inference data
|
|
172
|
+
|
|
173
|
+
logger.debug("Evaluating model", context="evaluate_model")
|
|
174
|
+
# Evaluate the model
|
|
175
|
+
|
|
176
|
+
logger.debug("Saving results", context="save_results")
|
|
177
|
+
# Save the results
|
|
178
|
+
|
|
179
|
+
logger.report() # Prints out the time spent in each logging context
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Additionally, `rra_tools` provides a command line tool `parse_logs` that can be used to
|
|
184
|
+
summarize the performance logs generated by the `task_performance_logger`. This is
|
|
185
|
+
useful when trying to understand the runtime characteristics of a pipeline that may
|
|
186
|
+
run hundreds or thousands of tasks.
|
|
187
|
+
|
|
188
|
+
```sh
|
|
189
|
+
parse_logs path/to/output/log/directory/
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Shell Tools
|
|
193
|
+
|
|
194
|
+
The `shell_tools` module provides a few functions to run common shell commands.
|
|
195
|
+
|
|
196
|
+
1. `wget` - Download a file from a URL
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
from rra_tools.shell_tools import wget
|
|
200
|
+
|
|
201
|
+
wget("https://example.com/file.txt", "path/to/output.txt")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
2. `unzip_and_delete_archive` - Unzip a file and delete the archive
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
from rra_tools.shell_tools import unzip_and_delete_archive
|
|
208
|
+
|
|
209
|
+
unzip_and_delete_archive("path/to/archive.zip", "path/to/output")
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Note: you may need to install `unzip` on your system to use this function. You
|
|
213
|
+
can do so with `conda install -c conda-forge unzip`.
|
|
214
|
+
|
|
215
|
+
3. `mkdir` - Create a directory with correct permissions.
|
|
216
|
+
The default operation of mkdir via the `os` module or `pathlib` translates uses
|
|
217
|
+
the umask of the user running the script along with the permissions set. This
|
|
218
|
+
often results in unexpected permissions on the created directory. This function
|
|
219
|
+
allows you to specify the permissions of the directory without relying on the
|
|
220
|
+
umask.
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
from rra_tools.shell_tools import mkdir
|
|
224
|
+
|
|
225
|
+
mkdir("path/to/directory", mode=0o755)
|
|
226
|
+
# Can also make parents
|
|
227
|
+
mkdir("path/to/other/directory", parents=True, mode=0o775)
|
|
228
|
+
# Can also do a no-op if the directory already exists
|
|
229
|
+
mkdir("path/to/other/directory", mode=0o775)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
4. `touch` - Create a file with the correct permissions.
|
|
233
|
+
Like `mkdir`, `touch` allows you to specify the permissions of the file without
|
|
234
|
+
relying on the umask.
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from rra_tools.shell_tools import touch
|
|
238
|
+
|
|
239
|
+
touch("path/to/file.txt", mode=0o664)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Parallel Processing with Multiprocessing
|
|
243
|
+
|
|
244
|
+
The `parallel` module provides a utility to run a function of a single argument in
|
|
245
|
+
parallel across a list of inputs using multiprocessing.
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
from rra_tools.parallel import run_parallel
|
|
249
|
+
|
|
250
|
+
# Trivial example
|
|
251
|
+
def my_runner(x):
|
|
252
|
+
return x ** 2
|
|
253
|
+
|
|
254
|
+
inputs = list(range(1000))
|
|
255
|
+
|
|
256
|
+
results = run_parallel(
|
|
257
|
+
my_runner,
|
|
258
|
+
inputs,
|
|
259
|
+
num_cores=3, # By default, num_cores is set to 1 and will run sequentially
|
|
260
|
+
)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
In practice, the function we want to parallelize will be significantly more complex
|
|
264
|
+
than the trivial example above. Generally, you want to set things up so that:
|
|
265
|
+
|
|
266
|
+
1. The function you want to parallelize is self-contained and does not rely on any
|
|
267
|
+
global state.
|
|
268
|
+
2. The function you want to parallelize is relatively expensive to run. If the
|
|
269
|
+
function is cheap to run, the overhead of parallelization can outweigh the benefits
|
|
270
|
+
of parallelization.
|
|
271
|
+
3. The input argument to the function is relatively small in memory. Multiprocessing
|
|
272
|
+
needs to copy the input data to each worker process, so if the input data is large,
|
|
273
|
+
the overhead of copying the data can outweigh the benefits of parallelization.
|
|
274
|
+
A common way to overcome this limitation is to pass the path to the input data
|
|
275
|
+
instead of the data itself and then have the function read the data from the path.
|
|
276
|
+
4. The function is not *too* complex. If your `runner` function is complicated, you may
|
|
277
|
+
end up with resource contention between the worker processes that is hard to
|
|
278
|
+
understand (e.g. you may run out of memory because each worker process is trying
|
|
279
|
+
is loading a big dataset at the same time). There's no hard and fast rule here,
|
|
280
|
+
but once functions get to be more than a few dozen lines long, you should start
|
|
281
|
+
thinking about whether process-based parallelization is the right choice, and maybe
|
|
282
|
+
opt for a different parallelization strategy (like `jobmon` described below).
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
### Jobmon Integration
|
|
286
|
+
|
|
287
|
+
The `jobmon` module provides a set of utilities to run more complicated parallel
|
|
288
|
+
jobs by interfacing with a job scheduler like `slurm`. See
|
|
289
|
+
[Jobmon documentation](https://jobmon.readthedocs.io/en/latest/index.html) for more
|
|
290
|
+
information.
|
|
291
|
+
|
|
292
|
+
#### Installation
|
|
293
|
+
|
|
294
|
+
Jobmon is not installed by default with `rra-tools` and is only available to download
|
|
295
|
+
and install on the IHME cluster. To install jobmon, you must have
|
|
296
|
+
a conf file in your home directory at `~/.pip/pip.conf` with the following contents:
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
[global]
|
|
300
|
+
extra-index-url = https://artifactory.ihme.washington.edu/artifactory/api/pypi/pypi-shared/simple
|
|
301
|
+
trusted-host = artifactory.ihme.washington.edu/artifactory/api/pypi/pypi-shared
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Then you can install jobmon with:
|
|
305
|
+
|
|
306
|
+
```sh
|
|
307
|
+
pip install jobmon[ihme]
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
#### Usage
|
|
311
|
+
|
|
312
|
+
TBD
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
### Translation
|
|
316
|
+
|
|
317
|
+
The `translate` module provides functions to translate text files from one
|
|
318
|
+
language to another.
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
from rra_tools.translate import translate_text_file
|
|
323
|
+
|
|
324
|
+
translate_text_file("path/to/input.txt", "path/to/output.txt")
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
By default, it will attempt to autodetect the language in the input file and produce
|
|
328
|
+
outputs in English, but you can specify the source and target languages:
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
from rra_tools.translate import translate_text_file
|
|
332
|
+
# Translate from German to Spanish
|
|
333
|
+
translate_text_file(
|
|
334
|
+
"path/to/input.txt",
|
|
335
|
+
"path/to/output.txt",
|
|
336
|
+
source_language="de",
|
|
337
|
+
target_language="es",
|
|
338
|
+
)
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The `translate` subpackage can also translate dataframe columns
|
|
342
|
+
|
|
343
|
+
```python
|
|
344
|
+
import pandas as pd
|
|
345
|
+
from rra_tools.translate import translate_dataframe
|
|
346
|
+
|
|
347
|
+
df = pd.DataFrame({"text": ["hola", "mundo"]})
|
|
348
|
+
translated_df = translate_dataframe(df, columns=["text"])
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Installation
|
|
355
|
+
|
|
356
|
+
```sh
|
|
357
|
+
pip install rra-tools
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Development
|
|
361
|
+
|
|
362
|
+
Instructions using conda:
|
|
363
|
+
|
|
364
|
+
1. Clone this repository.
|
|
365
|
+
|
|
366
|
+
Over ssh:
|
|
367
|
+
```sh
|
|
368
|
+
git clone git@github.com:ihmeuw/climate-downscale.git
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Over https:
|
|
372
|
+
```sh
|
|
373
|
+
git clone https://github.com/ihmeuw/climate-downscale.git
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
2. Create a new conda environment.
|
|
377
|
+
|
|
378
|
+
```sh
|
|
379
|
+
conda create -n climate-downscale python=3.10
|
|
380
|
+
conda activate climate-downscale
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
3. Install `poetry` and the project dependencies.
|
|
384
|
+
|
|
385
|
+
```sh
|
|
386
|
+
conda install poetry
|
|
387
|
+
poetry install
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Documentation
|
|
391
|
+
|
|
392
|
+
The documentation is automatically generated from the content of the `docs` directory and from the docstrings
|
|
393
|
+
of the public signatures of the source code. The documentation is updated and published as a [Github project page
|
|
394
|
+
](https://pages.github.com/) automatically as part each release.
|
|
395
|
+
|
|
396
|
+
### Releasing
|
|
397
|
+
|
|
398
|
+
Trigger the [Draft release workflow](https://github.com/collijk/rra-tools/actions/workflows/draft_release.yml)
|
|
399
|
+
(press _Run workflow_). This will update the changelog & version and create a GitHub release which is in _Draft_ state.
|
|
400
|
+
|
|
401
|
+
Find the draft release from the
|
|
402
|
+
[GitHub releases](https://github.com/collijk/rra-tools/releases) and publish it. When
|
|
403
|
+
a release is published, it'll trigger [release](https://github.com/collijk/rra-tools/blob/master/.github/workflows/release.yml) workflow which creates PyPI
|
|
404
|
+
release and deploys updated documentation.
|
|
405
|
+
|
|
406
|
+
### Pre-commit
|
|
407
|
+
|
|
408
|
+
Pre-commit hooks run all the auto-formatting (`ruff format`), linters (e.g. `ruff` and `mypy`), and other quality
|
|
409
|
+
checks to make sure the changeset is in good shape before a commit/push happens.
|
|
410
|
+
|
|
411
|
+
You can install the hooks with (runs for each commit):
|
|
412
|
+
|
|
413
|
+
```sh
|
|
414
|
+
pre-commit install
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Or if you want them to run only for each push:
|
|
418
|
+
|
|
419
|
+
```sh
|
|
420
|
+
pre-commit install -t pre-push
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Or if you want e.g. want to run all checks manually for all files:
|
|
424
|
+
|
|
425
|
+
```sh
|
|
426
|
+
poetry run pre-commit run --all-files
|
|
427
|
+
```
|
|
428
|
+
|